日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
遇到指針別害怕!先把這篇筆記看一遍~

指針在C語(yǔ)言中是一塊很重要的內(nèi)容,也是比較難理解的一塊內(nèi)容,我們需要反復(fù)學(xué)習(xí)反復(fù)鞏固才可以對(duì)其有所了解。

之前也分享過(guò)指針相關(guān)的筆記,但是都比較雜,本篇筆記匯總一下指針相關(guān)的內(nèi)容,包含了挺多指針相關(guān)的基礎(chǔ)知識(shí)點(diǎn)。筆記有點(diǎn)長(zhǎng),可以收藏下來(lái)慢慢閱讀。

復(fù)雜類(lèi)型說(shuō)明

以下這部分內(nèi)容主要來(lái)自《讓你不再害怕指針》:

要了解指針,多多少少會(huì)出現(xiàn)一些比較復(fù)雜的類(lèi)型,所以,先介紹一下如何完全理解一個(gè)復(fù)雜類(lèi)型,要理解復(fù)雜類(lèi)型其實(shí)很簡(jiǎn)單。

一個(gè)類(lèi)型里會(huì)出現(xiàn)很多運(yùn)算符,他們也像普通的表達(dá)式一樣,有優(yōu)先級(jí),其優(yōu)先級(jí)和運(yùn)算優(yōu)先級(jí)一樣,所以我總結(jié)了一下其原則: 從變量名處起,根據(jù)運(yùn)算符優(yōu)先級(jí)結(jié)合,一步一步分析。

下面讓我們先從簡(jiǎn)單的類(lèi)型開(kāi)始慢慢分析吧:

int p;

這是一個(gè)普通的整型變量 。

int *p;

首先從 P處開(kāi)始,先與* 結(jié)合,所以說(shuō)明 P 是一個(gè)指針。

然后再與 int 結(jié)合,說(shuō)明指針?biāo)赶虻膬?nèi)容的類(lèi)型為 int 型。所以 P 是一個(gè)返回整型數(shù)據(jù)的指針。

int p[3];

首先從 P 處開(kāi)始,先與[]結(jié)合,說(shuō)明 P 是一個(gè)數(shù)組,然后與 int 結(jié)合,說(shuō)明數(shù)組里的元素是整型的,所以 P 是一個(gè)由整型數(shù)據(jù)組成的數(shù)組。

int *p[3];

首先從 P 處開(kāi)始,先與[]結(jié)合,因?yàn)槠鋬?yōu)先級(jí)比 * 高。所以 P 是一個(gè)數(shù)組,然后再與 * 結(jié)合,說(shuō)明數(shù)組里的元素是指針類(lèi)型。

然后再與 int 結(jié)合,說(shuō)明指針?biāo)赶虻膬?nèi)容的類(lèi)型是整型的,所以P 是一個(gè)由返回整型數(shù)據(jù)的指針?biāo)M成的數(shù)組 。

int (*p)[3];

首先從 P 處開(kāi)始,先與 * 結(jié)合,說(shuō)明 P 是一個(gè)指針然后再與[]結(jié)合與"()"這步可以忽略,只是為了改變優(yōu)先級(jí))。

說(shuō)明指針?biāo)赶虻膬?nèi)容是一個(gè)數(shù)組,然后再與 int 結(jié)合,說(shuō)明數(shù)組里的元素是整型的。所以 P 是一個(gè)指向由整型數(shù)據(jù)組成的數(shù)組的指針。

int **p;

首先從 P 開(kāi)始,先與后再與 * 結(jié)合,說(shuō)明指針?biāo)赶虻脑厥侵羔槪缓笤倥c int 結(jié)合,說(shuō)明該指針?biāo)赶虻脑厥钦蛿?shù)據(jù)。

由于二級(jí)指針以上的指針極少用在復(fù)雜的類(lèi)型中,所以后面更復(fù)雜的類(lèi)型我們就不考慮多級(jí)指針了,最多只考慮一級(jí)指針。

int p(int);

從 P 處起,先與()結(jié)合,說(shuō)明 P 是一個(gè)函數(shù),然后進(jìn)入()里分析,說(shuō)明該函數(shù)有一個(gè)整型變量的參數(shù)然后再與外面的 int 結(jié)合,說(shuō)明函數(shù)的返回值是一個(gè)整型數(shù)據(jù)。

int (*p)(int);

從 P 處開(kāi)始,先與指針結(jié)合,說(shuō)明 P 是一個(gè)指針,然后與()結(jié)合,說(shuō)明指針指向的是一個(gè)函數(shù),然后再與()里的int 結(jié)合,說(shuō)明函數(shù)有一個(gè) int 型的參數(shù),再與最外層的int 結(jié)合。

說(shuō)明函數(shù)的返回類(lèi)型是整型,所以 P 是一個(gè)指向有一個(gè)整型參數(shù)且返回類(lèi)型為整型的函數(shù)的指針。

說(shuō)到這里也就差不多了,我們的任務(wù)也就這么多,理解了這幾個(gè)類(lèi)型,其它的類(lèi)型對(duì)我們來(lái)說(shuō)也是小菜了。

不過(guò)我們一般不會(huì)用太復(fù)雜的類(lèi)型,那樣會(huì)大大減小程序的可讀性,請(qǐng)慎用,這上面的幾種類(lèi)型已經(jīng)足夠我們用了。

分析指針的方法

指針是一個(gè)特殊的變量, 它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。

要搞清一個(gè)指針需要搞清指針的四方面的內(nèi)容:指針的類(lèi)型、 指針?biāo)赶虻念?lèi)型、 指針的值(指針?biāo)赶虻膬?nèi)存區(qū))、 指針本身所占據(jù)的內(nèi)存區(qū)。讓我們分別說(shuō)明。

先聲明幾個(gè)指針?lè)胖隼樱?/p>

(1)int *ptr;
(2)char*ptr;
(3)int **ptr;
(4)int (*ptr)[3];
(5)int *(*ptr)[4];

1、指針的類(lèi)型

從語(yǔ)法的角度看, 你只要把指針聲明語(yǔ)句里的指針名字去掉, 剩下的部分就是這個(gè)指針的類(lèi)型。這是指針本身所具有的類(lèi)型。讓我們看看例一中各個(gè)指針的類(lèi)型:

(1)int*ptr;//指針的類(lèi)型是 int*
(2)char*ptr;//指針的類(lèi)型是 char*
(3)int**ptr;//指針的類(lèi)型是 int**
(4)int(*ptr)[3];//指針的類(lèi)型是 int(*)[3]
(5)int*(*ptr)[4];//指針的類(lèi)型是 int*(*)[4]

2、指針?biāo)赶虻念?lèi)型

當(dāng)你通過(guò)指針來(lái)訪問(wèn)指針?biāo)赶虻膬?nèi)存區(qū)時(shí), 指針?biāo)赶虻念?lèi)型決定了編譯器將把那片內(nèi)存區(qū)里的內(nèi)容當(dāng)做什么來(lái)看待。

從語(yǔ)法上看, 你只須把指針聲明語(yǔ)句中的指針名字和名字左邊的指針聲明符*去掉, 剩下的就是指針?biāo)赶虻念?lèi)型。例如:

(1)int*ptr; //指針?biāo)赶虻念?lèi)型是 int
(2)char*ptr; //指針?biāo)赶虻牡念?lèi)型是 char
(3)int**ptr; //指針?biāo)赶虻牡念?lèi)型是 int*
(4)int(*ptr)[3]; //指針?biāo)赶虻牡念?lèi)型是 int()[3]
(5)int*(*ptr)[4]; //指針?biāo)赶虻牡念?lèi)型是 int*()[4]

在指針的算術(shù)運(yùn)算中, 指針?biāo)赶虻念?lèi)型有很大的作用。

3、指針的值

指針的值是指針本身存儲(chǔ)的數(shù)值, 這個(gè)值將被編譯器當(dāng)作一個(gè)地址, 而不是一個(gè)一般的數(shù)值。

在 32 位程序里, 所有類(lèi)型的指針的值都是一個(gè) 32 位  整數(shù), 因?yàn)?32 位程序里內(nèi)存地址全都是 32 位長(zhǎng)。

指針?biāo)赶虻膬?nèi)存區(qū)就是從指針的值所代表的那個(gè)內(nèi)存地址開(kāi)始, 長(zhǎng)度為 sizeof(指針?biāo)赶虻念?lèi)型)的一片內(nèi)存區(qū)。

以后, 我們說(shuō)一個(gè)指針的值是 XX, 就相當(dāng)于說(shuō)該指針指向了以 XX 為首地址的一片內(nèi)存區(qū)域;我們說(shuō)一個(gè)指針指向了某塊內(nèi)存區(qū)域,就相當(dāng)于說(shuō)該指針的值是這塊內(nèi)存區(qū)域的首地址。

指針?biāo)赶虻膬?nèi)存區(qū)和指針?biāo)赶虻念?lèi)型是兩個(gè)完全不同的概念。在例一中, 指針?biāo)赶虻念?lèi)型已經(jīng)有了, 但由于指針還未初始化, 所以它所指向的內(nèi)存區(qū)是不存在的, 或者說(shuō)是無(wú)意義的。

以后, 每遇到一個(gè)指針, 都應(yīng)該問(wèn)問(wèn):這個(gè)指針的類(lèi)型是什么?指針指向的類(lèi)型是什么?該指針指向了哪里?(重點(diǎn)注意) 。

4、指針本身所占據(jù)的內(nèi)存區(qū)

指針本身占了多大的內(nèi)存?你只要用函數(shù) sizeof(指針的類(lèi)型)測(cè)一下就知道了。

在 32 位平臺(tái)里, 指針本身占據(jù)了 4 個(gè)字節(jié)的長(zhǎng)度。指針本身占據(jù)的內(nèi)存這個(gè)概念在判斷一個(gè)指針表達(dá)式(后面會(huì)解釋?zhuān)?是否是左值時(shí)很有用。

指針的算術(shù)運(yùn)算

指針可以加上或減去一個(gè)整數(shù)。指針的這種運(yùn)算的意義和通常的數(shù)值的加減運(yùn)算的意義是不一樣的, 以單元為單位。

這在內(nèi)存上體現(xiàn)為:相對(duì)這個(gè)指針向后偏移多少個(gè)單位或向前偏移了多少個(gè)單位,這里的單位與指針變量的類(lèi)型有關(guān)。

在32bit環(huán)境下,int類(lèi)型占4個(gè)字節(jié),float占4字節(jié),double類(lèi)型占8字節(jié),char占1字節(jié)。

【注意】一些處理整數(shù)的操作不能用來(lái)處理指針。例如,可以把兩個(gè)整數(shù)相乘,但是不能把兩個(gè)指針相乘。

示例程序

#include 
int main(void)
{
int a = 10, *pa = &a;
float b = 6.6, *pb = &b;
char c = 'a', *pc = &c;
double d = 2.14e9, *pd = &d;
//最初的值
printf("pa0=%d, pb0=%d, pc0=%d, pd0=%d\n", pa, pb, pc, pd);
//加法運(yùn)算
pa += 2;
pb += 2;
pc += 2;
pd += 2;
printf("pa1=%d, pb1=%d, pc1=%d, pd1=%d\n", pa, pb, pc, pd);
//減法運(yùn)算
pa -= 1;
pb -= 1;
pc -= 1;
pd -= 1;
printf("pa2=%d, pb2=%d, pc2=%d, pd2=%d\n", pa, pb, pc, pd);
return0;
}

運(yùn)行結(jié)果為:

pa0=6422268, pb0=6422264, pc0=6422263, pd0=6422248
pa1=6422276, pb1=6422272, pc1=6422265, pd1=6422264
pa2=6422272, pb2=6422268, pc2=6422264, pd2=6422256

解析:

舉例說(shuō)明pa0→pa1→pa2的過(guò)程,其他類(lèi)似。pa0+2*sizeof(int)=pa1,pa1-1*sizeof(int)=pa2。因?yàn)閜a為int類(lèi)型的指針,所以加減運(yùn)算是以4字節(jié)(即sizeof(int))為單位地址向前向后偏移的??聪聢D:

如圖:pa1所指向的地址在pa0所指向地址往后8字節(jié)處,pa2指向地址在pa1指向地址往前4字節(jié)處。

從本示例程序中,還可以看出:連續(xù)定義的變量在內(nèi)存的存儲(chǔ)有可能是緊挨著的,有可能是分散著的。

數(shù)組和指針的聯(lián)系

數(shù)組與指針有很密切的聯(lián)系,常見(jiàn)的結(jié)合情況有以下三種:

  •  數(shù)組指針
  •  指針數(shù)組
  •  二維數(shù)組指針

1、數(shù)組指針

數(shù)組指針:指向數(shù)組的指針。如:

int arr[] = {0,1,2,3,4};
int *p = arr; //也可寫(xiě)作int *p=&arr[0]

也就是說(shuō),p,arr,&arr[0]都是指向數(shù)組的開(kāi)頭,即第0個(gè)元素的地址。

如果一個(gè)指針p指向一個(gè)數(shù)組arr[]的開(kāi)頭,那么p+i為數(shù)組第i個(gè)元素的地址,即&arr[i],那么*(p+i)為數(shù)組第i個(gè)元素的值,即arr[i]。

同理,若指針p指向數(shù)組的第n個(gè)元素,那么p+i為第n+1個(gè)元素的地址;不管 p 指向了數(shù)組的第幾個(gè)元素,p+1 總是指向下一個(gè)元素,p-1 也總是指向上一個(gè)元素。

下面示例證實(shí)了這一點(diǎn):

運(yùn)行結(jié)果為:

0, 1, 2, 3, 4

2、指針數(shù)組

指針數(shù)組:數(shù)組中每個(gè)元素都是指針。如:

int a=1,b=2,c=3;
int *arr[3] = {&a,&b,&c};

示例程序:

#include 
int main(void)
{
int a = 1, b = 2, c = 3;
//定義一個(gè)指針數(shù)組
int *arr[3] = {&a, &b, &c};//也可以不指定長(zhǎng)度,直接寫(xiě)作 int *parr[]
//定義一個(gè)指向指針數(shù)組的指針
int **parr = arr;
printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]);
printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2));
return0;
}

第一個(gè) printf() 語(yǔ)句中,arr[i] 表示獲取第 i 個(gè)元素的值,該元素是一個(gè)指針,還需要在前面增加一個(gè) * 才能取得它指向的數(shù)據(jù),也即 *arr[i] 的形式。

第二個(gè) printf() 語(yǔ)句中,parr+i 表示第 i 個(gè)元素的地址,*(parr+i) 表示獲取第 i 個(gè)元素的值(該元素是一個(gè)指針),**(parr+i) 表示獲取第 i 個(gè)元素指向的數(shù)據(jù)。

指針數(shù)組還可以和字符串?dāng)?shù)組結(jié)合使用,請(qǐng)看下面的例子:

#include 
int main(void)
{
char *str[3] =
{
"hello C",
"hello C++",
"hello Java"
};
printf("%s\n%s\n%s\n", str[0], str[1], str[2]);
return0;
}

運(yùn)行結(jié)果為:

hello C
hello C++
hello Java

3、二維數(shù)組指針

二維數(shù)組指針:指向二維數(shù)組的指針。如:

int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
int (*p)[4] = a;

a [3] [4]表示一個(gè)3行4列的二維數(shù)組,其所有元素在內(nèi)存中是連續(xù)存儲(chǔ)的。

請(qǐng)看如下程序:

#include 
int main(void)
{
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
int i,j;
for( i = 0; i < 3; i++ )
{
for( j = 0; j < 4; j++ )
{
printf("a[%d][%d]=%d\n", i, j, &a[i][j]);
}
}

return0;
}

運(yùn)行結(jié)果為:

a[0][0]=6422216
a[0][1]=6422220
a[0][2]=6422224
a[0][3]=6422228
a[1][0]=6422232
a[1][1]=6422236
a[1][2]=6422240
a[1][3]=6422244
a[2][0]=6422248
a[2][1]=6422252
a[2][2]=6422256
a[2][3]=6422260

可見(jiàn),每個(gè)元素的地址都是相差4個(gè)字節(jié),即每個(gè)連續(xù)在內(nèi)存中是連續(xù)存儲(chǔ)的。

按照以上定義可歸納出如下4個(gè)結(jié)論:

(1)p指向數(shù)組a的開(kāi)頭,也即第1行;p+1前進(jìn)一行,指向第2行。

(2)*(p+1)表示取第2行元素(一整行元素)。

(3)*(p+1)+1表示第2行第2個(gè)元素的地址。

(4)((p+1)+1)表示第2行第2個(gè)元素的值。

綜上4點(diǎn),可得出如下結(jié)論:

a+i == p+i
*(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j)== *(*(p+i)+j)

以上就是數(shù)組與指針常用的三種結(jié)合形式。

指針與數(shù)組的區(qū)別

數(shù)組與指針在多數(shù)情況是可以等價(jià)的,比如:

intarray[10]={0,1,2,3,4,5,6,7,8,9},value;
value=array[0]; //也可寫(xiě)成:value=*array;
value=array[3]; //也可寫(xiě)成:value=*(array+3);
value=array[4]; //也可寫(xiě)成:value=*(array+4)

但也有不等價(jià)的時(shí)候,比如如下三種情況:

  •  數(shù)組名不可以改變,而指向數(shù)組的指針是可以改變的。
  •  字符串指針指向的字符串中的字符是不能改變的,而字符數(shù)組中的字符是可以改變的。
  •  求數(shù)組長(zhǎng)度時(shí),借用數(shù)組名可求得數(shù)組長(zhǎng)度,而借用指針卻得不到數(shù)組長(zhǎng)度。

1、區(qū)別一

數(shù)組名的指向不可以改變,而指向數(shù)組的指針是可以改變的。

請(qǐng)看如下代碼:

#include 
int main(void)
{
int a[5] = {0, 1, 2, 3, 4}, *p = a;
char i;
// 數(shù)組遍歷方式一
for ( i = 0; i < 5; i++ )
{
printf("a[%d] = %d\n", i, *p++);
}
// 數(shù)組遍歷方式二
for ( i = 0; i < 5; i++ )
{
printf("a[%d] = %d\n", i, *a++);
}
return0;
}

數(shù)組遍歷方式一:使用指針遍歷數(shù)組元素,* p++等價(jià)于*(p++),即指針指向的地址每次后移一個(gè)單位,然后再取地址上的值。這里的一個(gè)單位是sizeof(int)個(gè)字節(jié)。

數(shù)組遍歷方式二:使用數(shù)組名自增遍歷數(shù)組元素,編譯出錯(cuò),錯(cuò)誤如下:

error: value required as increment operand

因?yàn)閿?shù)組名的指向是不可以改變的,使用自增運(yùn)算符自增就會(huì)改變其指向,這是不對(duì)的,數(shù)組名只能指向數(shù)組的開(kāi)頭。但是可以改為如下遍歷方式:

for ( i = 0; i < 5; i++ )
{
printf("a[%d] = %d\n", i, *(a+i));
}

這可以正確遍歷數(shù)組元素。因?yàn)?(a+i)與a[i]是等價(jià)的。

2、區(qū)別二

字符串指針指向的字符串中的字符是不能改變的,而字符數(shù)組中的字符是可以改變的。

請(qǐng)看如下代碼:

//字符串定義方式一
char str[] = "happy";
//字符串定義方式二
char *str = "happy";

字符串定義方式一:字符串中的字符是可以改變的。如可以使用類(lèi)似str[3]='q'這樣的語(yǔ)句來(lái)改變其中的字符。原因就是:這種方式定義的字符串保存在全局?jǐn)?shù)據(jù)區(qū)或棧區(qū),是可讀寫(xiě)的。

字符串定義方式二:字符串中的字符是不可以改變的。原因就是:這種方式定義的字符串保存在常量區(qū),是不可修改的。

3、區(qū)別三

求數(shù)組長(zhǎng)度時(shí),借用數(shù)組名可求得數(shù)組長(zhǎng)度,而借用指針卻得不到數(shù)組長(zhǎng)度。

請(qǐng)看如下代碼:

#include 
int main(void)
{
int a[] = {0, 1, 2, 3, 4}, *p = a;
char len = 0;
// 求數(shù)組長(zhǎng)度方式一
printf("方式一:len=%d\n",sizeof(a)/sizeof(int));
// 求數(shù)組長(zhǎng)度方式二
printf("方式二:len=%d\n",sizeof(p)/sizeof(int));
return0;
}

運(yùn)行結(jié)果

方式一:len=5
方式二:len=1

求數(shù)組長(zhǎng)度方式一:借用數(shù)組名來(lái)求數(shù)組長(zhǎng)度,可求得數(shù)組有5個(gè)元素,正確。

求數(shù)組長(zhǎng)度方式二:借用指針求數(shù)組長(zhǎng)度,求得長(zhǎng)度為1,錯(cuò)誤。原因是:

p只是一個(gè)指向int類(lèi)型的指針,編譯器不知道其指向的是一個(gè)整數(shù)還是指向一個(gè)數(shù)組。sizeof(p)求得的是p這個(gè)指針變量本身所占用的字節(jié)數(shù),而不是整個(gè)數(shù)組占用的字節(jié)數(shù)。

下面還需要注意數(shù)組名的一個(gè)問(wèn)題: 聲明了一個(gè)數(shù)組 TYPE array[n] , 則數(shù)組名是一個(gè)常量指針,  該指針的值是不能修改的, 即類(lèi)似 array++的表達(dá)式是錯(cuò)誤的。

指針函數(shù)與函數(shù)指針

函數(shù)、指針這兩個(gè)詞結(jié)合的順序不同其意義也不同,即指針函數(shù)與函數(shù)指針的意義不同。

1、指針函數(shù)

指針函數(shù)的本質(zhì)是一個(gè)函數(shù),其返回值是一個(gè)指針。示例如下:

int *pfun(int, int);

由于“*”的優(yōu)先級(jí)低于“()”的優(yōu)先級(jí),因而pfun首先和后面的“()”結(jié)合,也就意味著,pfun是一個(gè)函數(shù)。即:int *(pfun(int, int));

接著再和前面的“*”結(jié)合,說(shuō)明這個(gè)函數(shù)的返回值是一個(gè)指針。由于前面還有一個(gè)int,也就是說(shuō),pfun是一個(gè)返回值為整型指針的函數(shù)。

指針函數(shù)示例程序如下:

#include 
//這是一個(gè)指針函數(shù)的聲明
int *pfun(int *arr, int n);
int main(void)
{
intarray[] = {0, 1, 2, 3, 4};
int len = sizeof(array)/sizeof(array[0]);
int *p;
int i;
//指針函數(shù)的調(diào)用
p = pfun(array, len);
for (i = 0; i < len; i++)
{
printf("array[%d] = %d\n", i, *(p+i));
}
return0;
}
//這是一個(gè)指針函數(shù),其返回值為指向整形的指針
int *pfun(int *arr, int n)
{
int *p = arr;
return p;
}

程序運(yùn)行結(jié)果如下:

主函數(shù)中,把一個(gè)數(shù)組的首地址與數(shù)組長(zhǎng)度作為實(shí)參傳入指針函數(shù)pfun里,把指針函數(shù)的返回值(即指向數(shù)組的指針)賦給整形指針p。最后使用指針p來(lái)遍歷數(shù)組元素并打印輸出。

2、函數(shù)指針

函數(shù)指針其本質(zhì)是一個(gè)指針變量,該指針變量指向一個(gè)函數(shù)。C程序在編譯時(shí),每一個(gè)函數(shù)都有一個(gè)入口地址,該入口地址就是函數(shù)指針?biāo)赶虻牡刂?。函?shù)指針示例:

/*聲明一個(gè)函數(shù)指針 */
int (*fptr) (int, int);
/* 函數(shù)指針指向函數(shù)func */
fptr = func; // 或者fptr = &func;

func是一個(gè)函數(shù)名,那么func與&func都表示的是函數(shù)的入口地址。同樣的,在函數(shù)的調(diào)用中可以使用:方式一:func(),也可以使用方式二:(*fun)()。這兩種調(diào)用方式是等價(jià)的,只是我們平時(shí)大多都習(xí)慣用方式一的調(diào)用方法。

至于為什么func與&func的含義相同,《嵌入式Linux上的C語(yǔ)言編程實(shí)踐》這本書(shū)中有如下解釋?zhuān)?/p>

  •  對(duì)于函數(shù)func來(lái)說(shuō),函數(shù)的名稱(chēng)就是函數(shù)代碼區(qū)的常量,對(duì)它取地址(&func)可以得到函數(shù)代碼區(qū)的地址,同時(shí),func本身也可以視為函數(shù)代碼區(qū)的地址。因此,函數(shù)名稱(chēng)和對(duì)其取地址其含義是相同的。

函數(shù)指針示例程序如下:

#include 
int add(int a, int b);
int main(void)
{
int (*fptr)(int, int); //定義一個(gè)函數(shù)指針
int res;
fptr = add; //函數(shù)指針fptr指向函數(shù)add
/* 通過(guò)函數(shù)指針調(diào)用函數(shù) */
res = (*fptr)(1,2); //等價(jià)于res = fptr(1,2);
printf("a + b = %d\n", res);
return0;
}
int add(int a, int b)
{
return a + b;
}

程序運(yùn)行結(jié)果如下:

其中,函數(shù)指針廣泛應(yīng)用于嵌入式軟件開(kāi)發(fā)中,其常用的兩個(gè)用途:調(diào)用函數(shù)和做函數(shù)的參數(shù)。

以上就是關(guān)于指針的的一些基礎(chǔ)知識(shí)總結(jié),如有錯(cuò)誤歡迎指出!謝謝


當(dāng)前名稱(chēng):遇到指針別害怕!先把這篇筆記看一遍~
網(wǎng)站地址:http://m.5511xx.com/article/cdggshd.html