a)||(m=aa-b?a++:++b,+ ... 如何學好C語言-指針 " />
復習運算符 (關系運算與邏輯運算) #include "stdio.h" void main() { int a=1,b=2,m=0,n=0,k;printf("%d\n",m); k=(n=b>a)||(m=a printf("%d,%d\n",k,m); } (條件運算,與逗號運算) #include "stdio.h" void main() { char a=1,b=3,c=0; printf("%d",(a+b>a-b?a++:++b,++a,b+5)); }//%d 整形輸出 %c 字符 %s 字符串 %f 浮點 復習函數(帶形參的返回函數值可以做判斷語句的條件) #include “stdio.h” char delay(char t); char delay(char t) //t=3 { t++; //t=4 return t; } void main() { char i=8,k; if(i>delay(2)) { k=delay(3); //k=4 i++; //i=9 printf("k=%d,i=%d",k,i); } } 復習全局變量做形參其值不變 #include "stdio.h" void delay(int y); int y=3; void delay(int y) //y=5 { for(;y<6;y++); printf("y1=%d\n",y); //y=6 } void main() { int mm; delay(5); printf("y2=%d\n",y); //y=3 mm=y++; //mn=3,y=4 printf("y3=%d\n",y); 指針數組(里面存放的是指針,如果是字符串則存放的是字符串的首地址) #include "stdio.h" void main() { char i=0,*p[3]={"wejlj","dsag","dsfads"} ; for(;i<3;i++) { printf("%c \n",*(p[i])); } } #include "stdio.h" main(){ int a[3][3]={1,2,3,4,5,6,7,8,9}; int *pa[3]={a[0],a[1],a[2]}; int *p=a[0]; int i; for(i=0;i<3;i++) printf("%d,%d,%d\n",a[i][2-i],*a[i],*(*(a+i)+i)); for(i=0;i<3;i++) printf("%d,%d,%d\n",*pa[i],p[i],*(p+i)); } 指針函數與函數指針的區別 1、指針函數是指帶指針的函數,即本質是一個函數。函數返回類型是某一類型的指針 類型標識符 *函數名(類型 參數表) int *f(int x,int y); 首先它是一個函數,只不過這個函數的返回值是一個地址值。函數返回值必須用同類型的指針變量來接受,也就是說,指針函數一定有函數返回值,而且,在主調函數中,函數返回值必須賦給同類型的指針變量。 表示: float *fun(); float *p; p = fun(a); 注意指針函數與函數指針表示方法的不同,千萬不要混淆。最簡單的辨別方式就是看函數名前面的指針*號有沒有被括號()包含,如果被包含就是函數指針,反之則是指針函數。 來講詳細一些吧!請看下面 指針函數: 當一個函數聲明其返回值為一個指針時,實際上就是返回一個地址給調用函數,以用于需要指針或地址的表達式中。 格式: 類型說明符 * 函數名(參數) 當然了,由于返回的是一個地址,所以類型說明符一般都是int。 例如:int *GetDate(void); int * aaa(int,int); 函數返回的是一個地址值,經常使用在返回數組的某一元素地址上。 #include "stdio.h" int * GetDate(int wk,int dy); main() { int wk,dy; do { printf("Enter week(1-5)day(1-7)\n"); scanf("%d%d",&wk,&dy); } while(wk<1||wk>5||dy<1||dy>7); // wk=2;dy=3 printf("%d\n",*GetDate(wk,dy)); } int * GetDate(int wk,int dy) { static int calendar[5][7]= { {1,2,3,4,5,6,7}, {8,9,10,11,12,13,14}, {15,16,17,18,19,20,21}, {22,23,24,25,26,27,28}, {29,30,31,-1} }; //不釋放空間 return &calendar[wk-1][dy-1]; //1,2 } 程序應該是很好理解的,子函數返回的是數組某元素的地址。輸出的是這個地址里的值。 #include "stdio.h" main(){ int i; char *day_name(int n); printf("input Day No:\n"); scanf("%d",&i); if(i<0) exit(1); printf("Day No:%2d-->%s\n",i,day_name(i)); } char *day_name(int n){ static char *name[]={ "Illegal day", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; return((n<1||n>7) ? name[0] : name[n]); } 2、函數指針是指向函數的指針變量,即本質是一個指針變量。 類型說明符 (*函數名)(參數) int (*f) (int x); /* 聲明一個函數指針 */ f=func; /* 將func函數的首地址賦給指針f */ 指向函數的指針包含了函數的地址,可以通過它來調用函數。聲明格式如下: 類型說明符 (*函數名)(參數) 其實這里不能稱為函數名,應該叫做指針的變量名。這個特殊的指針指向一個返回整型值的函數。指針的聲明必須和它指向函數的聲明保持一致。 指針名和指針運算符外面的括號改變了默認的運算符優先級。如果沒有圓括號,就變成了一個返回整型指針的函數的原型聲明。 例如: void (*fptr)(); 把函數的地址賦值給函數指針,可以采用下面兩種形式: fptr=&Function; fptr=Function; 取地址運算符&不是必需的,因為單單一個函數標識符就標號表示了它的地址,如果是函數調用,還必須包含一個圓括號括起來的參數表。 可以采用如下兩種方式來通過指針調用函數: x=(*fptr)(); x=fptr(); 第二種格式看上去和函數調用無異。但是有些程序員傾向于使用第一種格式,因為它明確指出是通過指針而非函數名來調用函數的。下面舉一個例子: #include "stdio.h" void (*funcp)(); void FileFunc(),EditFunc(); main() { funcp=FileFunc; (*funcp)(); funcp=EditFunc; (*funcp)(); } void FileFunc() { printf("FileFunc\n"); } void EditFunc() { printf("EditFunc\n"); } 程序輸出為: FileFunc EditFunc 例2 #include"stdio.h" //定義一個函數指針,形參為一個char類型,一個int類型,返回類型為void void (*pf)(char, int); void fun(char ,int); //聲明一個函數,形參為一個char類型,一個int類型,返回類型為void int main(void) { pf=fun; //給函數指針pf賦值為fun函數的首地址(函數名代表函數的首地址) (*pf)('c',372); //調用pf指向的函數 } void fun(char a,int b) { printf("the argument is %c and %d\n",a,b); } 主要的區別是一個是指針變量,一個是函數。在使用是必要要搞清楚才能正確使用 二、指針的指針 指針的指針看上去有些令人費解。它們的聲明有兩個星號。例如: char ** cp; 如果有三個星號,那就是指針的指針的指針,四個星號就是指針的指針的指針的指針,依次類推。當你熟悉了簡單的例子以后,就可以應付復雜的情況了。當然,實際程序中,一般也只用到 二級指針,三個星號不常見,更別說四個星號了。 指針的指針需要用到指針的地址。 char c='A'; char *p=&c; char **cp=&p; 通過指針的指針,不僅可以訪問它指向的指針,還可以訪問它指向的指針所指向的數據。下面就是幾個這樣的例子: char **p1=*cp; char c1=**p1; 你可能想知道這樣的結構有什么用。利用指針的指針可以允許被調用函數修改局部指針變量和處理指針數組。 #include "stdio.h" void FindCredit(int **); main() { int vals[]={7,6,5,-4,3,2,1,0}; int *fp=vals; FindCredit(&fp); printf("%d\n",*fp); } void FindCredit(int ** sp) { while(**sp!=0) if(**sp<0) break; else (*fpp)++; } 首先用一個數組的地址初始化指針fp,然后把該指針的地址作為實參傳遞給函數FindCredit()。FindCredit()函數通過表達式**fpp間接地得到數組中的數據。為遍歷數組以找到一個負值,FindCredit()函數進行自增運算的對象是調用者的指向數組的指針,而不是它自己的指向調用者指針的指針。語句(*fpp)++就是對形參指針指向的指針進行自增運算的。但是因為*運算符高于++運算符,所以圓括號在這里是必須的,如果沒有圓括號,那么++運算符將作用于二重指針fpp上。 三、指向指針數組的指針 指針的指針另一用法舊處理指針數組。有些程序員喜歡用指針數組來代替多維數組,一個常見的用法就是處理字符串。 #include "stdio.h" char *Names[]={"Bill","Sam","Jim","Paul","Charles","0"}; main() { char **nm=Names; while(**nm!=‘0’) printf("%s\n",*nm++); } 先用字符型指針數組Names的地址來初始化指針nm。每次printf()的調用都首先傳遞指針nm指向的字符型指針,然后對nm進行自增運算使其指向數組的下一個元素(還是指針)。注意完成上述認為的語法為*nm++,它首先取得指針指向的內容,然后使指針自增。 深圳廣州南寧長沙鄭州嵌入式單片機C語言技術提升聯系郭老師qq754634522,年底優惠多多,添加咨詢可免費領取學習優惠券哦 注意數組中的最后一個元素被初始化為0,while循環以次來判斷是否到了數組末尾。具有零值的指針常常被用做循環數組的終止符。程序員稱零值指針為空指針(NULL)。采用空指針作為終止符,在數組增刪元素時,就不必改動數組的代碼,因為此時數組仍然以空指針作為結束。 #include "stdio.h" main() { char *name[]= {"Follow me","BASIC","Great Wall","FORTRAN","Computer desighn"}; char **p; int i; for(i=0;i<5;i++) { p=name+i; printf("%s\n",*p); } } /* typedef與define之間的區別*/ #include "stdio.h" #define PIN1 int * typedef int * PIN2; void main() { PIN1 a=1,b=1; PIN2 c=3,d=3; printf("%d",a); //a是 指針 1 printf("\n"); printf("%d",a+1); //a地址加1,由于是整型占4個字節 5 printf("\n"); printf("%d",b); //b是 整型 值 1 printf("\n"); printf("%d",b+1); //b的值自增1 2 printf("\n"); printf("%d",c); //c是 指針 1 printf("\n"); printf("%d",c+1); //c地址加1,由于是整型占4個字節 5 printf("\n"); printf("%d",d); //d是 指針 1 printf("\n"); printf("%d",d+1); //d地址加1,由于是整型占4個字節 5 } |