亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

C語(yǔ)言 百分網(wǎng)手機(jī)站

C語(yǔ)言指針用法詳解

時(shí)間:2020-09-20 19:16:07 C語(yǔ)言 我要投稿

C語(yǔ)言指針用法詳解

  指針可以說(shuō)是集C語(yǔ)言精華之所在,一個(gè)C語(yǔ)言達(dá)人怎么可以不會(huì)指針呢。下面小編給大家介紹C語(yǔ)言指針用法,歡迎閱讀!

  C語(yǔ)言指針用法詳解

  (1)關(guān)于指針與數(shù)組的存儲(chǔ)

  a、指針和數(shù)組在內(nèi)存中的存儲(chǔ)形

  數(shù)組p[N]創(chuàng)建時(shí),對(duì)應(yīng)著內(nèi)存中一個(gè)數(shù)組空間的分配,其地址和容量在數(shù)組生命周期內(nèi)一般不可改變。數(shù)組名p本身是一個(gè)常量,即分配數(shù)組空間的地址值,這個(gè)值在編譯時(shí)會(huì)替換成一個(gè)常數(shù),在運(yùn)行時(shí)沒(méi)有任何內(nèi)存空間來(lái)存儲(chǔ)這個(gè)值,它和數(shù)組長(zhǎng)度一起存在于代碼中(應(yīng)該是符號(hào)表中),在鏈接時(shí)已經(jīng)制定好了;而指針*p創(chuàng)建時(shí),對(duì)應(yīng)內(nèi)存中這個(gè)指針變量的空間分配,至于這個(gè)空間內(nèi)填什么值即這個(gè)指針變量的值是多少,要看它在程序中被如何初始化,這也決定了指針指向哪一塊內(nèi)存地址。

  b、指針和數(shù)組的賦值與初始化

  根據(jù)上文,一般情況下,數(shù)組的地址不能修改,內(nèi)容可以修改;而指針的內(nèi)容可以修改,指針指向的內(nèi)容也可以修改,但這之前要為指針初始化。

  如:

  int p[5];

  p=p+1; 是不允許的

  而p[0]=1; 是可以的;

  //

  int *p;

  p=p+1; 是允許的

  p[0]=1; 是不允許的,因?yàn)橹羔槢](méi)有初始化;

  //

  int i;

  int *p=&i;

  p[0]=1; 是允許的;

  對(duì)于字符指針還有比較特殊的情況。

  如:

  char * p="abc";

  p[0]='d'; 是不允許的

  為什么初始化了的字符指針不能改變其指向的內(nèi)容呢?這是因?yàn)閜指向的是“常量”字符串,字符串"abc"實(shí)際是存儲(chǔ)在程序的靜態(tài)存儲(chǔ)區(qū)的,因此內(nèi)容不能改變。這里常量字符串的地址確定在先,將指針指向其在后。

  而

  char p[]="abc";

  p[0]='d'; 是允許的

  這是因?yàn),這個(gè)初始化實(shí)際上是把常量直接賦值給數(shù)組,即寫(xiě)到為數(shù)組分配的內(nèi)存空間。這里數(shù)組內(nèi)存分配在先,賦值在后。

  (2)關(guān)于一些表達(dá)式的含義

  char *p, **p, ***p;

  char p[],p[][],p[][][];

  char *p[],*p[][],**p[],**p[][],*(*p)[],(**p)[],(**p)[][];

  能清晰地知道以上表達(dá)式的含義嗎?(知道的去死!)

  第一組:char *p, **p, ***p;

  分別為char指針;char*指針,即指向char*類型數(shù)據(jù)地址的指針;char**指針,即指向char**類型數(shù)據(jù)的指針;他們都是占4字節(jié)空間的指針。

  如:

  char c='a';

  char *p=&c;

  char **p1=&p;

  char ***p2=&p1;

  cout<<***p2<

  第二組:char p[],p[][],p[][][];

  分別為一維,二維和三維char型數(shù)組,即數(shù)組,數(shù)組的數(shù)組,<數(shù)組的數(shù)組>的數(shù)組?梢匀缦碌姆绞竭M(jìn)行初始化:

  char pp[3]="ab";

  char pp1[3][3]={"ab"};

  char pp2[3][3][3]={{"ab"}};

  現(xiàn)在我們嘗試使用第二組三個(gè)數(shù)組名對(duì)應(yīng)為第一組三個(gè)指針賦值,直接賦值的結(jié)果如下:

  p=pp; //正確

  p1=pp1; //錯(cuò)誤

  p2=pp2; //錯(cuò)誤

  為什么p1和p2的賦值會(huì)出錯(cuò)呢?原因是數(shù)組名為給指針賦值的規(guī)則不是遞歸的,即數(shù)組的數(shù)組可以為數(shù)組的指針賦值,而不可以為指針的指針賦值。這里先了解到這個(gè)抽象的規(guī)則,下面講完第三組表達(dá)式,等我們知道數(shù)組的指針和指針的數(shù)組如何書(shū)寫(xiě)后再對(duì)這一問(wèn)題舉例說(shuō)明。

  第三組:char *p[],*p[][],**p[],**p[][],*(*p)[],(**p)[],(**p)[][];

  這一類表達(dá)式的解析方法如下:

  首先把整個(gè)表達(dá)式分為三部分,

  數(shù)據(jù)類型和星號(hào)部分+p或括號(hào)內(nèi)內(nèi)容部分+中括號(hào)部分

  如:char *(*p)[]分為char* ,(*p) 和 []

  “char*”表示最內(nèi)層存儲(chǔ)的數(shù)據(jù)類型“(*p)”表示最外層指針“[]”表示中間層數(shù)組(維數(shù)=中括號(hào)數(shù)目),因此上式表示一個(gè)一維數(shù)組的指針p,數(shù)組中的元素的數(shù)據(jù)類型是指針char*。同理,char (**p)[][]表示,一個(gè)二維數(shù)組的指針的指針,數(shù)組元素的數(shù)據(jù)類型是char。這里如果表達(dá)式中間沒(méi)有括號(hào)(如**p[]),則實(shí)際上是一個(gè)數(shù)組,如果最右沒(méi)有中括號(hào)(如**p),則實(shí)際上是一個(gè)指針。下面通過(guò)賦值表達(dá)式來(lái)理解這些表達(dá)式的含義:

  char c='a';

  char *pc=&c;

  char *p[3],*p1[3][3],**p2[3],**p3[3][3],*(*p4)[3],(**p5)[3],(**p6)[3][3],(*(*p7))[3];

  p[1]=pc;

  p1[0][0]=pc;

  p2[0]=&pc;

  p3[0][0]=&pc;

  (*p4)[0]=pc;

  (**p5)[0]=c;

  (**p6)[0][0]=c;

  (**p7)[0]=c;

  注意,(*(*p7))[3]和(**p5)[3]是等價(jià)的。

  這里再繼續(xù)上一小節(jié)講一下數(shù)組名給指針賦值的問(wèn)題。

  事實(shí)上可以對(duì)等賦值的數(shù)組和指針關(guān)系如下(——>表示“賦值給”):

  數(shù)組——>指針 : p[]——>*p

  指針的數(shù)組——>指針的指針 : *p[]——>**p

  指針的指針的數(shù)組的——>指針的指針的指針 : **p[]——>***p

  或

  數(shù)組的數(shù)組——>數(shù)組的指針 : p[][]——>(*p)[]

  數(shù)組的數(shù)組的數(shù)組的——>數(shù)組的數(shù)組的'指針 : p[][][]——>(*p)[][]

  總之,最外層的數(shù)組可以轉(zhuǎn)換指針,往內(nèi)層不遞歸。

  (3)關(guān)于上述表達(dá)式的長(zhǎng)度

  求一個(gè)表達(dá)式的“長(zhǎng)度”,首先分清表達(dá)式實(shí)際表示的是一個(gè)數(shù)組還是一個(gè)指針;如果是指針,則長(zhǎng)度為4byte;如果為數(shù)組則要計(jì)算實(shí)際存儲(chǔ)的總元素個(gè)數(shù)和元素的數(shù)據(jù)類型。另外要注意要求的是數(shù)組元素個(gè)數(shù)還是數(shù)組總字節(jié)數(shù);

  如:

  *(*p)[3][3]

  由上文可知上式表示一個(gè)指針,因此長(zhǎng)度為4byte;而

  **p3[3][3]

  表示一個(gè)二維數(shù)組,數(shù)組元素類型為指針的指針,因此長(zhǎng)度為3*3*4=36;

  注意,標(biāo)準(zhǔn)C中sizeof函數(shù)求得的是總字節(jié)數(shù)而非數(shù)組長(zhǎng)度。

  (4)關(guān)于函數(shù)的指針?lè)祷刂岛椭羔槄?shù)

  指針作為返回值要注意的地方是不要返回局部數(shù)據(jù)的指針。

  如:

  char * fun(void)

  {

  char i='a';

  return (&i);

  }

  調(diào)用函數(shù)fun得不到值'a',原因是函數(shù)返回后,局部數(shù)據(jù)(在棧中)被析構(gòu),數(shù)據(jù)內(nèi)存被回收,指針指向的數(shù)據(jù)沒(méi)有意義;

  可以改為:

  char * fun(void)

  {

  char i='a';

  char *p=(char *)malloc(5);

  If(p!=NULL) {p[0]=i, p[1]='