陣列指標與函數

文章推薦指數: 80 %
投票人數:10人

C語言允許陣列指標和函數三者混合宣告,以表達複雜的資料結構。

對於要撰寫比較複雜的應用程式來說,了解這三者的關係是非常必要的。

例如下面的變數x到底是甚麼? C語言允許陣列指標和函數三者混合宣告,以表達複雜的資料結構。

對於要撰寫比較複雜的應用程式來說,了解這三者的關係是非常必要的。

例如下面的變數x到底是甚麼? char(*x[])(); 要看懂這些東西,首先要查型別與運算裡有關優先權與結合序的表格,得到()[]是第一優先權左結合,而*是第二優先權右結合。

在看變數宣告時,如同運算式的推演過程,必須遵守C程式語言對*()[]的優先權定義。

接下來請讀者背誦下面的口訣 看見[]就說array[]of 看見*就說pointerto 看見變數後面的()就說function()returning 上述口訣配合*()[]的優先權,依序找出其執行的順序,每看到運算符號就把這幾句口訣念出來。

因此變數的意義如下面範例 char*x;//x:apointertochar charx[3];//x:anarray[3]ofchar charx();//x:afunction()returningchar char*x[3];//x:anarray[3]ofpointertochar char(*x)[3];//x:apointertoarray[3]ofchar char**x;//x:apointertopointertochar char*x();//x:afunction()returningpointertochar char*x()[3];//x:afunction()returningarray[3]ofpointertochar char(*x[])();//x:anarray[]ofpointertofunction()returningchar char(*x())();//x:afunction()returningpointertofunction()returningchar char(*(*x)[])(int,int);//x:apointertoarray[]ofpointertofunction(int,int)returningchar 讀者在閱讀上面範例時,千萬不要把這些英文翻成中文!英文文法是後面修飾前面,比中文更能確切表達文句的意義,因此在處理這些複雜宣告時,用英文去了解即可。

在讀運算式時,則每看到一個運算符號,就把宣告前面的口訣拿掉一個,就是該運算式的意義 char*x;//x:apointertochar *x:achar char*x[3];//x:anarray[3]ofpointertochar x[0]:apointertochar char**x;//x:apointertopointertochar *x:apointertochar char*x();//x:afunction()returningpointertochar x():apointertochar char*x()[3];//x:afunction()returningarray[3]ofpointertochar x()[1]:apointertochar 下面的宣告摘錄自"TheCProgrammingLanguage"第二版的第122頁,請讀者寫出其宣告意義,並參考該書核對答案,相信可以增強讀者的自信: char**argv; int(*daytab)[13]; int*daytab[13]; void*comp(); void(*comp)(); char(*(*x())[])(); char(*(*x[3])())[5]; 以下是計算積分的程式範例,用到pointertofunction的觀念 #include #include /* *計算平方 */ doublesquare(doublex){ returnx*x; } /* *計算三次方 */ doublecube(doublex){ returnx*x*x; } /* *計算f()在(x,y)之間以n等份來逼近的積分數值,使用梯形法 */ doubleintegral(double(*f)(double),intn,doublex,doubley){ inti; doublegap=(y-x)/n; doublefy1=(*f)(x); doublefy2=(*f)(x+gap); doublearea=0; for(i=0;i intmain(intargc,char*argv[]){ inti; for(i=0;iechoabc abc > 這個程式很容易寫: #include intmain(intargc,char*argv[]){ inti; for(i=1;i裡面的函數。

va_list型態可用來存取每一個參數: #include //or#include voidminprintf(char*fmt,...){ va_listap;/*pointertoeachunnamedarginturn*/ char*p,*sval; intival; doubledval; va_start(ap,fmt);/*makeappointto1stunnamedarg*/ for(p=fmt;*p;p++){//checkeachcharacter if(*p!='%'){//不是特殊字元,直接輸出即可 putchar(*p); continue; } switch(*++p){//檢查%的下一個字元是甚麼 case'd': ival=va_arg(ap,int); printf("%d",ival); break; case'f': dval=va_arg(ap,double); printf("%f",dval); break; case's': for(sval=va_arg(ap,char*);*sval;sval++){//印出sval所指到的所有字元 putchar(*sval); } break; default: putchar(*p); break; } } va_end(ap);//cleanupwhendone*/ }



請為這篇文章評分?