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

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

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;

}

執行程式

[email protected]:~ % make

cc test4.c -o mytest

[email protected]:~ % ./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,原理類似。

[email protected]:~ % 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;

        執行程式

[email protected]:~ % make clean

rm mytest

[email protected]:~ % make

cc test4.c -o mytest

[email protected]:~ % ./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的值交換了。

[email protected]:~ % make clean

rm mytest

[email protected]:~ % make

cc test5.c -o mytest

[email protected]:~ % ./mytest

x:30-y:50

[email protected]:~ % 

我們定義一個數組,然後將陣列指標做為引數進行傳遞。

下面是一段程式完成引數陣列中所有元素之和。

#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;

}

~   

執行結果如下:

[email protected]:~ % make clean

rm mytest

[email protected]:~ % make

cc test6.c -o mytest

[email protected]:~ % ./mytest

15

[email protected]:~ % 

多維陣列指標

指標是一個變數,它指向另一個變數的地址,指標本身的大小相同,但它指向變數的大小不一定相同,比如說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個位元組容納時,程式執行正常。

[email protected]:~ % ./mytest

[email protected]:~ % make

cc test5.c -o mytest

[email protected]:~ % ./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;

}  

[email protected]:~ % make

cc test5.c -o mytest

[email protected]:~ % ./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;

}      

[email protected]:~ % make

cc test6.c -o mytest

[email protected]:~ % ./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;

}

[email protected]:~ % 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

[email protected]:~ % ./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;

}

[email protected]:~ % cc test7.c -o mytest                                          

[email protected]:~ % ./mytest

1   3   5   7   9