[转载]C 指针
                            
                            
                            一、認(rèn)識(shí)存儲(chǔ)單元  指針是C語(yǔ)言最顯著的特色。要理解指針的概念,需要先理解計(jì)算機(jī)讀寫(xiě)內(nèi)存的的方式以及變量的概念。  計(jì)算機(jī)內(nèi)存是以字節(jié)為單位劃分內(nèi)存單元的,每個(gè)內(nèi)存單元占用一個(gè)字節(jié),每個(gè)內(nèi)存單元都有自己的地址編號(hào),操作系統(tǒng)或軟件根據(jù)這個(gè)地址來(lái)識(shí)別內(nèi)存單元,在地址所標(biāo)識(shí)的內(nèi)存單元中存取數(shù)據(jù)。內(nèi)存單元的地址是固定的,內(nèi)存單元中的數(shù)據(jù)是可以修改的。  C語(yǔ)言中,變量名實(shí)質(zhì)上是內(nèi)存單元的地址符號(hào),用戶(hù)使用變量本質(zhì)上是訪問(wèn)該變量所對(duì)應(yīng)的內(nèi)存單元。  二、C指針的概念  1、在C中,將內(nèi)存單元的地址(編號(hào))稱(chēng)為指針,可以通過(guò)一個(gè)變量來(lái)存放指針,這種變量稱(chēng)為指針變量。指針變量中存儲(chǔ)的是內(nèi)存單元的地址。  例如 int a = 10;?假設(shè)存放a的內(nèi)存單元塊為 101,102,103,104,占用四個(gè)字節(jié)。如果再執(zhí)行一個(gè) int *p=&a;那么p的值就成為101了,*p的值就是10,a的值也是10。  &是取地址運(yùn)算符,獲取變量的首地址。  2、創(chuàng)建指針的方法是:類(lèi)型說(shuō)明符 *變量名,這是C定義指針變量的方法。其中*表示這個(gè)變量是指針變量。  C要求,指針必須存放在指針變量中。 一個(gè)指針只能指向同一類(lèi)型的變量。  3、指針的初始化 int *p=NULL; 或 int a=10; int *p=&a;  注意: a)未初始化的指針的系統(tǒng)會(huì)給一個(gè)隨機(jī)的值,沒(méi)有意義,操作可能引起系統(tǒng)崩潰。 b)未初始化的指針應(yīng)該給一個(gè)NULL值,以表明它是個(gè)空指針,表示0值。 c)不允許把常量賦值給指針變量。 d)必須保持指針變量類(lèi)型與所指數(shù)據(jù)的一致性,否則會(huì)發(fā)生不可預(yù)期的效果。(雖然C已允許將任何地址賦值給指針變量)。  4、取地址& 與 取內(nèi)容*  取地址運(yùn)算符是& ; 取內(nèi)容運(yùn)算符是*,注意:區(qū)別定義指針變量類(lèi)型說(shuō)明符*。   int a=10; int *p=&a;??? //定義指針變量p,并指向a; *p=3;?? //將3賦給指針p所指的內(nèi)存單元,則a的值也變?yōu)榱? int b = *p;? //將指針p的所指內(nèi)存單元值賦給變量b;  明白這個(gè)道理后,指針和一般變量一樣可以操作了。  指針的直接操作內(nèi)存,在Java中是沒(méi)有的,Java沒(méi)有指針。Java中的基本變量名實(shí)際上也是內(nèi)存地址的別名。  三、指針操作數(shù)組  1、指向數(shù)組的指針  數(shù)組是保存在一片連續(xù)的內(nèi)存單元中。數(shù)組名是這塊連續(xù)內(nèi)存單元的首地址,是不可改變的常量。因此數(shù)組名也是一個(gè)常量指針。 int a[3]={1,2,3}; int *p=a;? //指向數(shù)組的指針  當(dāng)指針執(zhí)行數(shù)組名或數(shù)組首元素地址時(shí),指針就指向了數(shù)組。  2、指針運(yùn)算 a)自增/自減:C規(guī)定,指針加1,表示指針后一個(gè)指針的類(lèi)型的內(nèi)存單元。 b)加減整數(shù)運(yùn)算,只能加減整數(shù),整數(shù)表示的基類(lèi)型數(shù)據(jù)的寬度倍數(shù)。 c)指針相減,指針間的元素個(gè)數(shù),不是存儲(chǔ)單元數(shù)。 d)指針比較,判斷指針在內(nèi)存中的高低位置關(guān)系。  3、指針操作數(shù)組  下標(biāo)發(fā)和指針?lè)?#xff0c;分五種方式:     #include<stdio.h> 
int main()
{
????????int i,a[5]={1,2,3,4};
????????int *p=a;
????????for(i=0;i<4;i++)
????????????????printf("a[%d]=%d\n",i,a[i]);
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("p[%d]=%d\n",i,p[i]);
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("*(p+%d)=%d\n",i,*(p+i));
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("*(a+%d)=%d\n",i,*(a+i));
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("*p++=%d\n",*p++);
????????getch();
????????return 0;
} a[0]=1
a[1]=2
a[2]=3
a[3]=4
p[0]=1
p[1]=2
p[2]=3
p[3]=4
*(p+0)=1
*(p+1)=2
*(p+2)=3
*(p+3)=4
*(a+0)=1
*(a+1)=2
*(a+2)=3
*(a+3)=4
*p++=1
*p++=2
*p++=3
*p++=4 注意,數(shù)組名雖然是指針,但是數(shù)組名是常量,不可改變,因此不可以a++; 4、指針操作二維數(shù)組 二維數(shù)組是多個(gè)一維數(shù)組組成的數(shù)組,或者說(shuō)是一維數(shù)組的數(shù)組,或者說(shuō)是一維數(shù)組,但是各個(gè)元素還是一維數(shù)組。 這個(gè)概念和java中是一致的。 假設(shè)有二維數(shù)組 int a[x][y]; 那么 a)a表示數(shù)組首地址的指針。 b)a[i]表示第i+1個(gè)一維數(shù)組,其地址為a[i],指向的是一個(gè)一維數(shù)組。 c)a[i][j] 與*(a[i]+j)、*(*(a+i)+j)是相同的,表示同一個(gè)元素。 #include<stdio.h>
int main()
{
????????int a[4][5], i,j;
????????for(i=0;i<4;i++)
????????????????for(j=0;j<5;j++)
????????????????????????a[i][j]=i*5+j;
????????printf("二維數(shù)組的值為:\n");
????????for(i=0;i<4;i++)
????????{
????????????????for(j=0;j<5;j++)
????????????????????????printf("%4d ",a[i][j]);
????????????????printf("\n");
????????}????????????????
????????getch();
????????return 0;
} 二維數(shù)組的值為:
???? 0????????1????????2????????3????????4
???? 5????????6????????7????????8????????9
????10???? 11???? 12???? 13???? 14
????15???? 16???? 17???? 18???? 19 5、數(shù)組指針 數(shù)組指針:變量是指針,指向了一個(gè)數(shù)組。 例如: int *p[3];定義了一個(gè)指針p指向了一個(gè)長(zhǎng)度為3的int數(shù)組。 #include<stdio.h>
int main()
{
????????int a[4][5],i,j;
????????int (*p)[5];
????????p=a;
????????for(i=0;i<4;i++)
????????{
????????????????for(j=0;j<5;j++)
????????????????????????*(*p+j)=i*5+j;
????????????????p++;
????????}
????????printf("二維數(shù)組的值為:\n");
????????p=a;
????????for(i=0;i<4;i++)
????????{
????????????????for(j=0;j<5;j++)
????????????????????????printf("%4d????",*(*p+j));
????????????????printf("\n");
????????????????p++;
????????}????????????????
????????getch();
????????return 0;
} 二維數(shù)組的值為:
???? 0????????1????????2????????3????????4
???? 5????????6????????7????????8????????9
????10???? 11???? 12???? 13???? 14
????15???? 16???? 17???? 18???? 19 6、數(shù)組名參數(shù) 指針變量 p 是空指針的判斷:
if ( p == 0 )
if ( p == '\0' )
if ( p == 3 - 3 )
if ( p == NULL )??/* 使用 NULL 必須包含相應(yīng)的標(biāo)準(zhǔn)庫(kù)的頭文件 */
if ( NULL == p )
if ( !p )
if ( p == q )
...
指針變量 p 不是空指針的判斷:
if ( p != 0 )
if ( p != '\0' )
if ( p != 3 - 3 )
if ( p != NULL )??/* 使用 NULL 必須包含相應(yīng)的標(biāo)準(zhǔn)庫(kù)的頭文件 */
if ( NULL != p )
if ( p )
if ( p != q )
                            
                        
                        
                        int main()
{
????????int i,a[5]={1,2,3,4};
????????int *p=a;
????????for(i=0;i<4;i++)
????????????????printf("a[%d]=%d\n",i,a[i]);
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("p[%d]=%d\n",i,p[i]);
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("*(p+%d)=%d\n",i,*(p+i));
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("*(a+%d)=%d\n",i,*(a+i));
????????printf("\n");
????????for(i=0;i<4;i++)
????????????????printf("*p++=%d\n",*p++);
????????getch();
????????return 0;
} a[0]=1
a[1]=2
a[2]=3
a[3]=4
p[0]=1
p[1]=2
p[2]=3
p[3]=4
*(p+0)=1
*(p+1)=2
*(p+2)=3
*(p+3)=4
*(a+0)=1
*(a+1)=2
*(a+2)=3
*(a+3)=4
*p++=1
*p++=2
*p++=3
*p++=4 注意,數(shù)組名雖然是指針,但是數(shù)組名是常量,不可改變,因此不可以a++; 4、指針操作二維數(shù)組 二維數(shù)組是多個(gè)一維數(shù)組組成的數(shù)組,或者說(shuō)是一維數(shù)組的數(shù)組,或者說(shuō)是一維數(shù)組,但是各個(gè)元素還是一維數(shù)組。 這個(gè)概念和java中是一致的。 假設(shè)有二維數(shù)組 int a[x][y]; 那么 a)a表示數(shù)組首地址的指針。 b)a[i]表示第i+1個(gè)一維數(shù)組,其地址為a[i],指向的是一個(gè)一維數(shù)組。 c)a[i][j] 與*(a[i]+j)、*(*(a+i)+j)是相同的,表示同一個(gè)元素。 #include<stdio.h>
int main()
{
????????int a[4][5], i,j;
????????for(i=0;i<4;i++)
????????????????for(j=0;j<5;j++)
????????????????????????a[i][j]=i*5+j;
????????printf("二維數(shù)組的值為:\n");
????????for(i=0;i<4;i++)
????????{
????????????????for(j=0;j<5;j++)
????????????????????????printf("%4d ",a[i][j]);
????????????????printf("\n");
????????}????????????????
????????getch();
????????return 0;
} 二維數(shù)組的值為:
???? 0????????1????????2????????3????????4
???? 5????????6????????7????????8????????9
????10???? 11???? 12???? 13???? 14
????15???? 16???? 17???? 18???? 19 5、數(shù)組指針 數(shù)組指針:變量是指針,指向了一個(gè)數(shù)組。 例如: int *p[3];定義了一個(gè)指針p指向了一個(gè)長(zhǎng)度為3的int數(shù)組。 #include<stdio.h>
int main()
{
????????int a[4][5],i,j;
????????int (*p)[5];
????????p=a;
????????for(i=0;i<4;i++)
????????{
????????????????for(j=0;j<5;j++)
????????????????????????*(*p+j)=i*5+j;
????????????????p++;
????????}
????????printf("二維數(shù)組的值為:\n");
????????p=a;
????????for(i=0;i<4;i++)
????????{
????????????????for(j=0;j<5;j++)
????????????????????????printf("%4d????",*(*p+j));
????????????????printf("\n");
????????????????p++;
????????}????????????????
????????getch();
????????return 0;
} 二維數(shù)組的值為:
???? 0????????1????????2????????3????????4
???? 5????????6????????7????????8????????9
????10???? 11???? 12???? 13???? 14
????15???? 16???? 17???? 18???? 19 6、數(shù)組名參數(shù) 指針變量 p 是空指針的判斷:
if ( p == 0 )
if ( p == '\0' )
if ( p == 3 - 3 )
if ( p == NULL )??/* 使用 NULL 必須包含相應(yīng)的標(biāo)準(zhǔn)庫(kù)的頭文件 */
if ( NULL == p )
if ( !p )
if ( p == q )
...
指針變量 p 不是空指針的判斷:
if ( p != 0 )
if ( p != '\0' )
if ( p != 3 - 3 )
if ( p != NULL )??/* 使用 NULL 必須包含相應(yīng)的標(biāo)準(zhǔn)庫(kù)的頭文件 */
if ( NULL != p )
if ( p )
if ( p != q )
總結(jié)
 
                            
                        - 上一篇: 两个指针变量可以相减
- 下一篇: 一起谈.NET技术,WPF 基础到企业应
