一.指針常量與常量指針

1. 指針常量

指針本身為常量且有const屬性

特點:指針指向的地址不變,指向的值可以改變(這裡的改變指通過指針進行改變)。

格式:類型 * const 變數1=&變數2

變數的數據類型—類型*

/*test1.c*/

#include<stdio.h>

main()

{

int i=2;

int j=3;

int * const p=&i;

*p = 8; /*正確,指針指向的值可以改變*/

p=&j; /*錯誤,指針指向的地址不變*/

}

2. 常量指針

指針指向的變數為常量且有const屬性

特點:指針指向的值不變,指向的地址可以改變。

格式:const 類型 * 變數1=&變數2

變數的數據類型—const 類型 *

/*test2.c*/

#include<stdio.h>

main()

{

int i=2;

int j=3;

const int * p=&i;

*p=8; /*錯誤,指針指向的值不變*/

p=&j; /*正確,指針指向的地址可以改變*/

}

錯誤1:消除const屬性

int a=6;

const int *p=&b; 正確

const int a=6;

int *p=&a; 錯誤,消除了const的屬性

3. 指向常量的常量指針

特點:指針指向的值和地址都不變。

格式:const 類型 * const 變數1=&變數2

二.按值傳遞和按地址傳遞

1.按值傳遞

在實參和形參之間以值的形式傳遞,改變形參值對實參無影響。

在調用函數時,將實參的值進行拷貝傳遞給形參,對形參的任何操作本質上是在對拷貝進行操作。

注意:在調用過程中,實參的地址不會改變

/*test.c*/

#include<stdio.h>

void fun(int q)

{

q=25;

}

main()

{

int i=10;

fun(i);

printf(「%d
」,i); /*實參i的值不變*/

}

2.按地址傳遞

在實參和形參之間以地址形式傳遞,可以通過改變形參值今進而改變實參值。

在調用函數時,將實參的地址傳遞給形參,對形參操作本質上是對實參地址的值進行操作(即間接定址)。

注意:在調用過程中,實參的地址可能發生改變(空調用地址不變),用const防止其地址改變。

/*test2.c*/

#include<stdio.h> #include<stdio.h>

void fun(int * q) void fun(int * const q)

{ *q=25; { int j=0;

} *q=25;

main() q=&j; /*錯,q指針為只讀*/

{ }

int i=10;

fun(&i);

printf(「%d
」,i); /* 實參i的值改變*/

}

函數調用期間,修改主調函數中的數組,被調函數需要的參數:

(1) 數組第一個元素的地址(即第一個位元組的地址)

(2) 數組的長度

三.指針數組與數組指針

1.指針數組(存儲指針的數組)

首先它是一個數組,然後是指針,是i個具有指針類型的數組元素。

一維數組:

如int arry[i],int *p[i]。p[i]是一個數組,數組中的每個元素(不是元素的值)又是一個指針;p[i]中每個元素的值是arry數組元素的地址(如p[2]=&arry[2])。

在int *p[i]中,p是p[i]數組的數組名(即指針常量),因此有:

*(p+k)=p[k]=&a[k],*(*(p+k))=a[k]。

*p=p[0]=a, **p=a[0],

二維數組:

p[k]=a[k]=&a[j][k],*p[k]=a[j][k];

*p=a[k],p=&p[0]=&a[0]。

注意:

1.p和a都是數組名,但p=a錯誤,因為p=&p[k],a=&a[k];*(p+k)=&a[k]。

2.在計算p[k]=&a[k]時,一定要用循環使每一項相對應,否則只是對第一項處理。

/*test1.c*/

#include<stdio.h>

main()

{

int i=0;

int a[5]={10,11,12,13,14};

int *p[5];

for(i=0;i<5;++i) /*使p和a中每一項相對應*/

p[i]=&a[i];

for(i=0;i<5;++i)

printf("%p
",p[i]);

for(i=0;i<5;++i)

printf("%d
",*p[i]);

}

2.數組指針

一般用於二維數組。首先它是一個數組,指針指向整個數組,int (*p)[i].

int (*p)[i] p(指針變數名)

int a[i][j];

int (*p)[i].

p=a=&a[0];a[0]=&a[0][0];

*(*p+k)=a[k][0];

p++,;該語句執行後,p=p+1,此時p=a[1]。以此類推……

注意:p沒有p[i]形式,p是以p的增量訪問數組的。

四.數組名作參數

本質是按地址傳遞,一般數組名作實參,形參可以是數組、指針。當數組作實參時,一維數組可以不指定維數,因為實參傳遞給形參的是數組元素的首地址,並不對形參數組的維數檢查;二維數組的第二維必須指定。

五.字元串指針

以char *p=」guoyongxin」為例解釋字元串指針原理。在C語言中,字元串都是按數組來處理的。

在指針數組中,內存先開闢一塊內存並以數組形式存儲str[]=」guoyongxin」,然後指針p指向數組str的首地址,即p=str。所以可以通過訪問指針來訪問字元串。

1. main() main()

{ {

char *p=」guoyongxin」; char *p;

printf(「%s
」,p); char str[]=」guoyongxin」;

} p=str;

printf(「%s」,p);

}

結果:guoyongxin 結果:guoyongxin

2. 指針數組形式的字元串

main()

{

char *p[]={

「guoyongxin」,

「yong」,

「xin」

}

printf(「%s
」,p[i]);

printf(「%s
」,*(p+i));

}

結果:guoyongxin guoyongxin


推薦閱讀:
相关文章