1. 程式人生 > >C指針原理(18)-C指針基礎

C指針原理(18)-C指針基礎

指針的指針 就會 數字 cas std vim distinct res 輸出

5、指針數組

指針數組就是數組裏存放的是指針。


#include?<stdio.h>

int?main(void){

????????int?i;

????????char?x[10]="ABCDEFGHIJ";

????????char?*p_x[10];

????????for?(i=0;i<10;i++){

????????????????p_x[i]=x+i;

???????????????//p_x[i]=&x[i];

????????}

????????for?(i=0;i<10;i++){

????????????????printf("%c?",*p_x[i]);

????????}

????????return?1;

}

上面定義了一個指針數組,數組的每個元素都是指針,每個指針指向x數組的相應元素。

其中,p_x為指針數組,通過for循環中的p_x[i]=x+i完成指針數組每個元素的賦值。這裏也可以寫成p_x[i]=&x[i]。最後以數組下標的方式訪問數組,輸出元素。

我們讓這個程序更復雜一些,加入指針的指針。

定義pp_x,讓它指向指針數組的第一個元素,然後向後移動指針,輸出元素。源程序如下:

#include?<stdio.h>

int?main(void){

????????int?i;

????????char?x[10]="ABCDEFGHIJ";

????????char?*p_x[10];

????????for?(i=0;i<10;i++){

???????????????p_x[i]=x+i;

???????}

????????char?**pp_x=NULL;

????????for?(i=0;i<10;i++){

????????????????printf("%c?",*p_x[i]);

????????}

????????printf?("\n");

????????for?(pp_x=p_x;pp_x<(p_x+10);pp_x++){

????????????????printf("%c???",**pp_x);

????????}

????????return?1;

}

運行程序

myhaspl@myhaspl:~?%?make

cc?test4.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

A?B?C?D?E?F?G?H?I?J?

A???B???C???D???E???F???G???H???I???J??

最後我們定義一個更復雜的例子,指針的指針的數組,名字有些長。在例子的最後代碼使用了指向指針的指針的指針***ppp_x,用它來最後輸出10個元素中的5個元素(每隔一個元素輸出一個元素。類似的還使用temp_x,原理類似。

myhaspl@myhaspl:~?%?vim?test4.c


//code:[email protected]

#include?<stdio.h>

int?main(void){

????????int?i;

????????char?x[10]="ABCDEFGHIJ";

????????char?**pp_x[5];

????????char?*p_x[10];

????????for?(i=0;i<10;i++){

???????????????p_x[i]=x+i;

???????}

????????char?***temp_x=pp_x;

????????for?(i=0;i<10;i+=2){

????????????????*temp_x=&p_x[i];

????????????????temp_x++;

????????}

????????printf?("\n");

????????char?***ppp_x;

????????for?(ppp_x=pp_x;ppp_x<(pp_x+5);ppp_x++){

????????????????printf("%c???",***ppp_x);

????????}

????????return?1;

????????運行程序

myhaspl@myhaspl:~?%?make?clean

rm?mytest

myhaspl@myhaspl:~?%?make

cc?test4.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

A???C???E???G???I???程序每隔一個元素對x數組的內容進行輸出。

5、函數參數中使用指針

指針也是一種變量,其實,C語言的函數還是傳值,所謂傳址只是把指針值傳給函數而已,本質上仍然是傳值,如下面程序,交換兩個數字

#include?<stdio.h>

int?main(void){

????????int?result;

????????int?x=50;

????????int?y=30;

????????myswap(&x,&y);

????????printf("x:%d-y:%d\n",x,y);

}

int?myswap(int?*a,int?*b){

????????int?temp=*a;

????????*a=*b;

????????*b=temp;

}

~?????

運行後,X和Y的值交換了。

myhaspl@myhaspl:~?%?make?clean

rm?mytest

myhaspl@myhaspl:~?%?make

cc?test5.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

x:30-y:50

myhaspl@myhaspl:~?%?

我們定義一個數組,然後將數組指針做為參數進行傳遞。

下面是一段程序完成參數數組中所有元素之和。

#include?<stdio.h>

int?x[5]={1,2,3,4,5};

int?main(void){

????????int?result;

????????result=mysum(5,x);

????????printf("%d\n",result);

}

int?mysum(int?length,int?*data){

????????int?myresult=0;

????????int?i;

????????for(i=0;i<length;i++){

????????????????myresult+=*(data+i);

????????}

????????return?myresult;

}

~???

運行結果如下:

myhaspl@myhaspl:~?%?make?clean

rm?mytest

myhaspl@myhaspl:~?%?make

cc?test6.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

15

myhaspl@myhaspl:~?%?

多維數組指針

指針是一個變量,它指向另一個變量的地址,指針本身的大小相同,但它指向變量的大小不一定相同,比如說char指針和int指針就不一樣,32位系統中,char指針指向的變量僅有1字節,而int指針指向的變量有4個字節,這意味著將char指針指向int指針將有風險,值將被截斷。比如:

//code:[email protected]

#include?<stdio.h>

int?main(void){

????????char?*i;

????????int?x=127;

????????i=(char*)&x;

????????printf("%d",*i);?

????????return?1;

}???????????

上面程序中當x值可用1個字節容納時,程序運行正常。

myhaspl@myhaspl:~?%?./mytest

127myhaspl@myhaspl:~?%?make

cc?test5.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

127

但當x值較大時(不在-128~127以內),就會出問題:

//code:[email protected]

#include?<stdio.h>

int?main(void){

????????char?*i;

????????int?x=250;

????????i=(char*)&x;

????????printf("%d",*i);?

????????return?1;

}??

myhaspl@myhaspl:~?%?make

cc?test5.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

-6m????

????

多維數組的指針定定義比一維數組更錄活,因為它可以指定指向變量的最後一維的維數,下面定義的指針指向變量的大小是最後一維的5個元素,每次指針移動都以5個元素為單位:

//code:[email protected]

#include?<stdio.h>

int?main(void){

????????int?i;

????????int?x[2][5]={1,2,3,4,5,6,7,8,9,10};

????????int?(*p_x)[5];

????????for?(p_x=x;p_x<=(&x[1]);p_x++){

????????????????printf("%d???",*p_x[0]);?

????????}

????????return?1;

}??????

myhaspl@myhaspl:~?%?make

cc?test6.c?-o?mytest

myhaspl@myhaspl:~?%?./mytest

1???6?

下面定義的指針僅指向一個元素?,也通過改變指針指向變量的尺寸,將數組以5*2大小的方式進行訪問,這樣,編譯器會給出警告,但能編譯通過。

?//code:[email protected]

#include?<stdio.h>

int?main(void){

????????int?i;

????????int?x[2][5]={1,2,3,4,5,6,7,8,9,10};

????????int?(*p_x)[2];

????????for?(p_x=x;p_x<&x[1][5];p_x++){

????????????????printf("%d???",*p_x[0]);

????????}

????????return?1;

}

myhaspl@myhaspl:~?%?cc?test8.c?-o?mytest??????????????????????????????????????????

test8.c:?In?function?‘main‘:

test8.c:7:?warning:?assignment?from?incompatible?pointer?type

test8.c:7:?warning:?comparison?of?distinct?pointer?types?lacks?a?cast

myhaspl@myhaspl:~?%?./mytest

1???3???5???7???9???

並不贊成這種做法,如果需要每隔2個元素進行訪問,可以將指針指向多維數組的一個元素,每次移動加上2即可。

//code:[email protected]

#include?<stdio.h>

int?main(void){

????????int?i;

????????int?x[2][5]={1,2,3,4,5,6,7,8,9,10};

????????int?*p_x=&x[0][0];

????????for?(;p_x<&x[1][5];p_x+=2){

????????????????printf("%d???",*p_x);

????????}

????????return?1;

}

myhaspl@myhaspl:~?%?cc?test7.c?-o?mytest??????????????????????????????????????????

myhaspl@myhaspl:~?%?./mytest

1???3???5???7???9 ?

C指針原理(18)-C指針基礎