一、數組指針? 1.指向數組元素的指針
1、定義:還是那句話通俗的說指針就是地址
數組指針?????:數組的起始地址
數組元素指針:數組元素的地址
2、定義一個指向數組元素的指針變量的方法,與之前介紹的指針變量相同。
例如:?
??? int a[10];?? /*定義 a 為包含10 個整型數據的數組*/
???? int *p;????? /*定義p為指向整型變量的指針*/
3、指針變量賦值:
p=&a[0]; //或者:p=a; 原因是p,a,&a[0]均指向同一單元
把 a[0]元素的地址賦給指針變量 p。也就是說,p指向 a 數組的第 0 號元素。
4、格式
類型說明符? *指針變量名;
2. 通過指針引用數組元素
?
看圖識字:
1、 p+i 和a+i 就是 a[i]的地址,或者說它們指向 a數組的第 i個元素。
2、*(p+i)或*(a+i)就是p+i或a+i所指向的數組元素, 即a[i]。 例如, *(p+5)或*(a+5)就是a[5]。
3、指向數組的指針變量也可以帶下標,如 p[i]與*(p+i)等價。
根據以上敘述,引用一個數組元素可以用:
1、下標法,即用 a[i]形式訪問數組元素。
2、指針法,即采用*(a+i)或*(p+i)形式,用間接訪問的方法來訪問數組元素,其中 a是數組名,p是指向數組的指針變量,其處值 p=a。
Eg:
1、下標法:
?????????????????
? 2、通過數組名計算元素的地址
????????????????
? 3、指針變量指向元素
??????????? ??
注意的問題
1、指針變量可以實現本身的值的改變。如 p++是合法的;而 a++是錯誤的。因為 a 是數組名,它是數組的首地址,是常量。
2、要注意指針變量的當前值。請看下面的程序。
?
int a[10],i,*p;p=a;//p=&a[0]for(i=0;i<10;i++)*p++=i; //a[i++]=ifor(i= 0;i<10;i++)printf("a[%d]=%d\n",i,*p++);
?
你看看出問題嗎?如果可以別忘了告訴我(雖然書上解釋了“要注意指針變量的當前值”但是還是有點迷糊)
看看運行結果
?????????
?
正確的方法就是把上面注釋的部分拿出來即可,看看結果:
???? ??
?
?
?
?
3.數組名作函數參數
? 數組名可以作函數的實參和形參
main() {int array[10]; …… …… f(array,10); …… …… } f(int arr[],int n); { …… …… } array 為實參數組名,arr為形參數組名。
? Eg:將數組 a 中的 n 個整數按相反順序存放。
1、形參是數組名
main() {//將數組 a 中的 n 個整數按相反順序存放。 int i,a[10]={3,7,9,11,0,6,7,5,4,2};printf("The original array:\n");for(i=0;i<10;i++){printf("%d,",a[i]);}printf("\n");inv(a,10);printf("The array has been inverted:\n");for(i=0;i<10;i++){printf("%d,",a[i]);}printf("\n"); } /*形參是數組名*/inv(int x[],int n) {int temp,i,j,m=(n-1)/2;for(i=0;i<m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp; } }
2、形參x為指針變量
/*形參x為指針變量*/inv2(int *x,int n){int *p,temp,*i,*j,m=(n-1)/2;i=x ;j=x+n-1;p=x+m;for(;i<=p;i++,j--){temp=*i;*i=*j;*j=temp;}return;}
歸納總結:如果有一個實參數組,想在函數中改變此數組的元素的值,實參與形參的對應關系有以下4種:
1、形參和實參都是數組名。
main()??????????????????? f(int x[],int n) {?……}
{int a[10];?
? ……?
? f(a,10)?
? ……
}?
2、實用數組,形參用指針變量
main()???????????????????? ?f(int *x,int n) {??…… }
{int a[10];
? ……
?f(a,10)?
? ……
}
3、 實參、型參都用指針變量
4、實參為指針變量,型參為數組名
4.指向多維數組的指針和指針變量
? 1.? 多維數組的地址 設有整型二維數組 a[3][4]如下:
0?? 1?? 2?? 3?
??? ?? 4?? 5?? 6?? 7
8?? 9? 10? 11
它的定義為:
int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}
? C語言允許把一個二維數組分解為多個一維數組來處理,因此數組 a 可分解為三個一維數組,即 a[0],a[1],a[2]
?? ?
例如 a[0]數組,含有 a[0][0],a[0][1],a[0][2],a[0][3]四個元素。
a[0]是第一個一維數組的數組名和首地址,因此a,a[0],*(a+0),*a,&a[0][0]是相等的。
Eg:
int a[3][4] ={0,1,2,3,4,5,6,7,8,9,10,11}; //0,1,2,3 a[0]行//4,5,6,7 a[1]行//8,9,10,11 a[2]行printf("0\n");printf("%d\n",*(a+0)); printf("%d\n",a); printf("%d\n",*a); printf("%d\n",a[0]); printf("%d\n",&a[0]); printf("%d\n",&a[0][0]); printf("………………………………………………\n");printf("1\n");printf("%d\n",a+1); printf("%d\n",*(a+1)); printf("%d\n",a[1]); printf("%d\n",&a[1]); printf("%d\n",&a[1][0]); printf("………………………………………………\n"); printf("2\n");printf("%d\n",a+2); printf("%d\n",*(a+2)); printf("%d\n",a[2]); printf("%d\n",&a[2]); printf("%d\n",&a[2][0]); printf("………………………………………………\n"); printf("3【a[1]行+1=>1244996+4】\n");printf("%d\n",a[1]+1); printf("%d\n",*(a+1)+1); printf("………………………………………………\n"); printf("取2行值\n");printf("%d,%d\n",*(a[1]+0),*(*(a+1)+0)); printf("%d,%d\n",*(a[1]+1),*(*(a+1)+1)); printf("%d,%d\n",*(a[1]+4),*(*(a+1)+4)); //越界繼續向下取值8*/
?
結果:
?
2.指向多維數組的指針變量
把二維數組 a 分解為一維數組 a[0],a[1],a[2]之后,設 p 為指向二維數組的指針變量。可定義為:?
????? int (*p)[4]
它表示 p 是一個指針變量,它指向包含 4 個元素的一維數組。若指向第一個一維數組a[0],其值等于 a,a[0],或&a[0][0]等。而 p+i 則指向一維數組 a[i]。從前面的分析可得出*(p+i)+j是二維數組 i 行j 列的元素的地址,而*(*(p+i)+j)則是i行 j 列元素的值。
二維數組指針變量說明的一般形式為:
類型說明符? (*指針變量名)[長度]
注意“(*指針變量名)”兩邊的括號不可少,如缺少括號則表示是指針數組
eg:
main(){ int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; int(*p)[4]; int i,j; p=a; for(i=0;i<3;i++) {for(j=0;j<4;j++) printf("%2d ",*(*(p+i)+j)); printf("\n");} }
?
二、字符串指針 1、字符串的表示形式
? C 語言中,可以用兩種方法訪問一個字符串:
1、用字符數組存放一個字符串,然后輸出該字符串
2、用字符串指針指向一個字符串
????????
?
?
?
?
?2、?使用字符串指針變量與字符數組的區別
1、字符串指針變量本身是一個變量,用于存放字符串的首地址,而字符串本身是存放在以該首地址為首的一塊連續的內存空間中并以‘\0’作為串的結束
2、對字符串指針方式 char *ps="C Language";
可以寫為:?
??? char *ps;
ps="C Language";
而對數組方式:?
??? static char st[]={"C Language"};
不能寫為:?
??? char st[20];?
??? st={"C Language"}; 而只能對字符數組的各元素逐個賦值。
?
?三、函數指針
?在C語言中,一個函數總是占用一段連續的內存區,而函數名就是該函數所占內存區的首地址。我們可以把函數的這個首地址(或稱入口地址)賦予一個指針變量,使該指針變量指向該函數。然后通過指針變量就可以找到并調用這個函數。我們把這種指向函數的指針變量稱為“函數指針變量”。
函數指針變量定義的一般形式為:
類型說明符? (*指針變量名)();
其中“類型說明符”表示被指函數的返回值的類型。 “(* 指針變量名)”表示“*”后面的變量是定義的指針變量。最后的空括號表示指針變量所指的是一個函數。
例如:?
??? int (*pf)();
Eg:
main() {int comMax(int a,int b);int (*pmax) ();//定義:類型說明符 (*指針變量名)(); 表示 pmax 是一個指向函數入口的指針變量,該函數的返回值(函數值)是整型。int x,y,z;pmax=comMax;printf("input two numbers:\n");scanf("%d%d",&x,&y);z=(*pmax)(x,y);//調用函數的一般形式為:(*指針變量名) (實參表) 或者 comMax(x,y);printf("max=%d",z); }int comMax(int a,int b) {if(a>b) return a; else return b; }
結果:
??????????
?
從上述程序可以看出用,函數指針變量形式調用函數的步驟如下:?
1、先定義函數指針變量,如后一程序中第 9 行 int (*pmax)();定義 pmax 為函數指針變量
2、把被調函數的入口地址(函數名)賦予該函數指針變量,如程序中第 11 行 pmax=max;
3、用函數指針變量形式調用函數,如程序第 14 行 z=(*pmax)(x,y);
4、調用函數的一般形式為:
? ?(*指針變量名) (實參表)
使用函數指針變量還應注意以下兩點:
a、函數指針變量不能進行算術運算,這是與數組指針變量不同的。數組指針變量加減一個整數可使指針移動指向后面或前面的數組元素,而函數指針的移動是毫無意義的 ?
b、函數調用中"(*指針變量名)"的兩邊的括號不可少,其中的*不應該理解為求值運算,在此處它只是一種表示符號
作者:PEPE
出處:http://pepe.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。