در زبان C میتوان آرایهای از اشارهگرها تعریف کرد. یعنی آرایهای که عناصر آن اشارهگر باشند . دستور زیر آرایهای 10 عنصری از اشارهگرها را توصیف میکند : int *x[10] ; اینها اشارهگرهایی هستند که میتوانند آدرس متغیرهایی از نوع مقادیر صحیح را در خود داشته باشند. بعنوان مثال برای اختصاص دادن آدرس متغیری به نام z به عنصر سوم آرایه مزبور ، مینویسیم : *x[2] = &z ; همینطور برای بدست آوردن مقدار z از دستور **x[2] استفاده می کنیم . آرایهای از اشارهگرها را نیز میتوان مشابه آرایههای معمولی به یک تابع انتقال داد . یعنی به سادگی ، نام آرایه را بدون اندیس یا زیرنویس آن بعنوان آرگومان تابع قرار میدهیم . برای مثال تابع display میتواند آرایه x را بصورت زیر دریافت نماید : void display (int *a[ ] ) { int k ; for ( k=0 ; k<10 ; k+ +) printf (" %p" , *a[k] ) ; } توجه داشته باشید که در مثال بالا ، a یک اشارهگر به مقادیر صحیح نیست بلکه یک اشارهگر به آرایهای از اشارهگرهایی به مقادیر صحیح است . بنابراین نیاز است که پارامتر a بعنوان آرایهای از اشارهگرهایی به مقادیر صحیح به همان طریق که نشان داده شد ، توصیف شود . آرایههای اشارهگر اغلب برای نگهداری اشارهگرهایی به رشتهها بکار برده میشوند . - انتقال آرایه به تابع ( بعنوان آرگومان )
بطوری که در فصل آرایهها بیان شد ، در زبان C ، نام هر آرایهای که بعنوان آرگومان یک تابع بکار برده شود ، بعنوان آدرس اولین عنصر آرایه تفسیر میگردد . برای مثال برنامه زیر را درنظر بگیرید : main ( ) { float func( ) ; float x , array[15] ; ....... ....... x = func(array) ; /* same as func (&array [0]) */ ....... ....... } حال در تابع فرعی نیاز است که ما آرگومان را بعنوان اشارهگر به اولین عنصر آرایه توصیف کنیم . برای این کار ، دو راه بصورت زیر وجود دارد : راه دوم | | راه اول | func(ar) float ar[ ] ; { ....... ....... } | | func(ar) float *ar ; { ....... ....... } |
راه دوم ، ar را بهعنوان آرایهای با اندازه (یا بزرگی) نامشخص ، توصیف میکند . آرایه هماکنون در تابع اصلی ایجاد شده است ، آنچه گذر داده میشود ، یک اشارهگر به اولین عنصر از آرایه است . چون کامپایلر میداند که عبارت آرایه منتج به اشارهگر به اولین عنصر آرایه میگردد ، پس ar را مشابه توصیف ar در روش اول ، به یک اشارهگر از نوع float تبدیل میکند . بنابراین هر دو گونه ازنظر نحوة عملکرد ، معادل و همارز یکدیگر میباشند . به هرحال ازنظر واضحتر بودن ، ممکن است روش دوم ترجیح داده شود . زیرا این روش تأکید میکند که آنچه که باید گذر داده شود آدرس پایه یا آدرس اولین عنصر یک آرایه است . در روش اول ، راهی برای تشخیص اینکه آیا ar به آغاز یک آرایه از نوع float و یا تنها به یک عنصر از نوع float اشاره میکند یا نه ، وجود ندارد . • fputs , fgets برای نوشتن رشتهها در فایل ، از تابع fputs و برای خواندن رشتهها از فایل ، از تابع fgets استفاده میگردد . الگوهای این دو تابع بصورت زیر میباشند : int fputs (const char *str , FILE *fp) char *fgets (char *str , int length , FILE *fp) در الگوهای فوق ، fp اشارهگری است که مشخص میکند این توابع باید بر روی چه فایلهایی عمل کنند . در تابع fgets اشارهگر str به رشتهای اشاره میکند که باید در فایل نوشته شود . این اشارهگر در تابع fputs به رشتهای اشاره میکند که اطلاعات خوانده شده از فایل در آن قرار میگیرند . length طول رشتهای را که باید از فایل خوانده شود مشخص میکند . نحوة عمل تابع fgets به این صورت است که از ابتدای فایل شروع به خواندن میکند تا به انتهای یک خط برسد و یا رشتهای به طول length کاراکتر را از فایل بخواند . برخلاف تابع gets ، در تابع fgets کاراکتری که انتهای خط را مشخص میکند جزء رشتهای خواهد بود که این تابع از فایل میخواند . مثال ـ برنامه زیر رشتههایی را از ورودی (صفحه کلید) خوانده و در یک فایل قرار میدهد . از آنجایی که تابعgets کاراکتری که پایان خط را مشخص میکند به رشته اضافه نمیکند ، در حین نوشتن بر روی فایل این کاراکتر به رشته خوانده شده اضافه میشود . برای خاتمه برنامه کافی است به جای رشته ، فقط کلید enter وارد شود . # include "stdio . h" # include "stdlib . h" void main (void) { FILE *fp ; char str [80] ; if (( fp = fopen ("test" , "w")) = = NULL ) { printf ("cannot open file \n") ; exit(1) ; } printf ("enter a string") ; printf ("ENTER to quit . \n") ; while(1) { gets (str) ; if (str[0]) break ; strcat (str , "\n") ; fputs (str , fp) ; } fclose (fp) ; } ادامه دارد .....
|