真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C語言學(xué)習(xí)(7)第六章指針6.7-6.13-創(chuàng)新互聯(lián)

目錄

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、常德網(wǎng)絡(luò)推廣、小程序開發(fā)、常德網(wǎng)絡(luò)營銷、常德企業(yè)策劃、常德品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供常德建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com

6.7 指針數(shù)組

6.8 指針的指針

6.9 字符串和指針

6.10 數(shù)組指針

6.10.1 二維數(shù)組

6.10.2 數(shù)組指針的定義方法

6.10.3 各種數(shù)組指針的定義

6.10.4 數(shù)組名字取地址,變成數(shù)組指針

6.10.5 數(shù)組名字和指針變量的區(qū)別

6.10.6 數(shù)組指針取*

6.11 指針和函數(shù)的關(guān)系

6.11.1 指針作為函數(shù)的參數(shù)

6.11.2 指針作為函數(shù)的返回值

6.11.3 指針保存函數(shù)的地址(函數(shù)指針)

6.12 經(jīng)常容易混淆的指針

6.13 特殊指針


6.7 指針數(shù)組

1、指針和數(shù)組的關(guān)系

指針可以保存數(shù)組元素的地址,那么也可以定義一個(gè)數(shù)組,數(shù)組中有若干個(gè)相同類型的指針變量,這個(gè)數(shù)組成為指針數(shù)組,它是若干個(gè)相同類型的指針變量構(gòu)成的集合。

2、定義方法:類型名 * 數(shù)組名[元素個(gè)數(shù)];

int* p[5]; //定義了一個(gè)整形的指針數(shù)組p,數(shù)組名是p,有5個(gè)元素,每個(gè)元素都是整形指針變量int*,它們分別儲(chǔ)存了一個(gè)整形數(shù)據(jù)的地址

int a[5];

p[0] = a;

6.8 指針的指針

指針的指針**p,即指針的地址。我們定義的一個(gè)指針變量本身占用4個(gè)字節(jié),指針變量也有地址編號(hào),但是類型不同,一個(gè)是int*,一個(gè)是int**。

int** p表示*p指向的是int*類型數(shù)據(jù)的地址。無論幾層的指針,其占用的存儲(chǔ)空間大小都是4個(gè)字節(jié)。

int a = 0x12345678;

int* p,**p_p;

p = &a; //p中存放的是a的地址編號(hào),p指向a

p_p = &p; //p_p中存放的是p的地址編號(hào),p_p指向p

int main()

{

int a = 5, b = 7;

int* p, ** p_p;

p = &a; //p中儲(chǔ)存了a的地址

p_p = & p; //p_p中儲(chǔ)存了p的地址

printf("p = %p, *p = %d\n", p,*p);

printf("p_p = %p, *p_p = %p, **p_p = %d\n", p_p,*p_p,**p_p);


return 0;

}

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

p = 006FF8D0, * p = 5

p_p = 006FF8B8, *p_p = 006FF8D0, **p_p = 5

p_p指向p,儲(chǔ)存的是p的地址,取p_p指向的值也就是p的地址,再取值也就是a的值了。

6.9 字符串和指針

1、字符串:以\0結(jié)尾的若干個(gè)字符的集合:比如"helloworld",這個(gè)字符串有11個(gè)字符,分別是h e l l o w o r l d \0。

字符串的地址就是第一個(gè)字符的地址:"helloworld"的地址就是字符串中"h"的地址。

可以定義一個(gè)字符指針變量:char* s = "helloworld";

2、字符串的存儲(chǔ)形式:數(shù)組、文字常量區(qū)、堆?

(1)字符串存放在數(shù)組中

即在內(nèi)存(棧、靜態(tài)全局區(qū))中開辟了一段空間來存放字符串。

char strint[100] = "I Love China";

定義了一個(gè)字符數(shù)組string來存放100個(gè)字符,并且用"I Love China"來給數(shù)組進(jìn)行初始化。普通全局?jǐn)?shù)組,內(nèi)存分配在靜態(tài)全局區(qū),普通局部數(shù)組,內(nèi)存分配在棧區(qū),靜態(tài)數(shù)組(靜態(tài)全局?jǐn)?shù)組、靜態(tài)局部數(shù)組),內(nèi)存分配在靜態(tài)全局區(qū)

(2)字符串存放在文字常量區(qū)

在文字常量區(qū)開辟了一段空間存放字符串,將字符串的首地址賦給指針變量。

char *str = "I Love China";

str只是保存了"I"的地址,也就是字符串的首地址。而這串字符串存放在文字常量區(qū)。

(3)字符串存放在堆區(qū)

使用malloc等函數(shù)在堆區(qū)申請(qǐng)空間,將字符串拷貝到堆區(qū)

char* str = (char*)malloc(10*sizeof(char)); //動(dòng)態(tài)申請(qǐng)了10個(gè)字節(jié)的存儲(chǔ)空間,首地址給str賦值

strcpy(str."I Love China"); //將字符串"I Love China"拷貝到str指向的內(nèi)存里

3、字符串的可修改性

字符串的內(nèi)容是否可以被修改,取決于字符串存放在哪里

(1)存放在數(shù)組中的字符串(數(shù)組沒有被const修飾),內(nèi)容可以被修改

char str[100] = "Hello World";

str[2] = Y;

int main()

{

char str[100] = "Hello World";

str[2] = 'Y';

printf("%s", str);


return 0;

}

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

HeYlo World

(2)存放在文字常量區(qū)的內(nèi)容不可以被修改

char* str = "I Love China";

*str = 'y';//錯(cuò)誤,文字常量區(qū)的內(nèi)容不可以修改

但可以給str重新賦值,讓它指向別的內(nèi)容。

(3)堆區(qū)中的內(nèi)容可以被修改

cahr* str = (char*)malloc(10);

strcpy(str,"I Love China")l

*str = 'y';//正確,堆區(qū)中的內(nèi)容可以被修改

4、初始化

(1)字符數(shù)組的初始化

char buf_aver[20] = "Hello Wolrd";

(2)指針指向文字常量區(qū)初始化

char *buf_point = "hello world";

(3)指針指向堆區(qū),不能初始化,只能先給指針賦值,讓指針指向堆區(qū),再使用strcpy、scanf等方法將字符串拷貝到堆區(qū)

char* buf_heap;

buf_heap = (char*)malloc(15);

strcpy(bug_heap,"helloworld");

scanf("%s",buf_heap);

5、使用時(shí)賦值

(1)字符數(shù)組:使用scanf或strcpy

char buf[20] = "hello world";

buf = "hello kitty"; //錯(cuò)誤,因?yàn)樽址麛?shù)組的名字是數(shù)組的首地址,是個(gè)常量,不能給常量賦值

strcpy(buf,"hello kitty"); //正確,使用strcpy函數(shù)將"hello kitty"賦給buf數(shù)組

scanf("%s",buf); //正確,將鍵盤輸入的字符串賦給buf數(shù)組

(2)指針指向文字常量區(qū)

char* buf_point = "hello world";

buf_point = "hello kitty"; //正確,這是將buf_point指向了一個(gè)新的字符串

strcpy(buf_point,"hello kitty"); //錯(cuò)誤,這時(shí)buf_point指向文字常量區(qū),不能給常量賦值

(3)指針指向堆區(qū)

char* buf_heap;

buf_heap = (char*)malloc(15);

strcpy(buf_heap,"hello kitty");

scanf("%s",buf_heap);

【總結(jié)】

1、指針可以指向文字常量區(qū)

(1)指針指向的文字常量區(qū)的內(nèi)容不可以修改

(2)指針的指向可以改變,即可以給指針變量重新賦值,指針變量指向別的地方。

2、指針可以指向堆區(qū)

(1)指針指向的堆區(qū)的內(nèi)容可以修改。

(2)指針的指向可以改變,即可以給指針變量重新賦值,指針變量指向別的地方。3、指針也可以指向數(shù)組(非const 修飾)

例:

char buf[20]="hello world";

char *str=buf;

這種情況下:

1.可以修改buf 數(shù)組的內(nèi)容。

2.可以通過str修改str指向的內(nèi)存的內(nèi)容,即數(shù)組buf的內(nèi)容

3.不能給buf賦值buf= “hello kitty" ;錯(cuò)誤的。

4.可以給st賦值,及str指向別處。str= “hello kitty'

6.10 數(shù)組指針 6.10.1 二維數(shù)組

二維數(shù)組,可以看成是由多個(gè)一維數(shù)組組成的,有行有列。

int a[3][5];//3行5列的二維數(shù)組,可以看出是由3個(gè)一維數(shù)組組成,可以認(rèn)為a中有3個(gè)元素,每個(gè)元素是一個(gè)一維數(shù)組

a是二維數(shù)組的首地址,a+1指向下一個(gè)元素,即下一行。

int main()

{

int a[3][5] = {

{1,3,5,7,9},

{2,4,6,8,10},

{7,9,1,13,12}

};

printf("a = %p\n", a);

printf("a+1 = %p\n", a+1);

return 0;

}

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

a = 005AFD74

a + 1 = 005AFD88

a是數(shù)組的首地址,一行有5個(gè)整形,占用20個(gè)字節(jié),所以a+1 比 a多20個(gè)字節(jié),它指向下一行。

6.10.2 數(shù)組指針的定義方法

指向的數(shù)組的類型(*指針變量名)[指向的數(shù)組的元素個(gè)數(shù)]

int(*p)[5]; //定義了一個(gè)數(shù)組指針變量p,p指向的是整形的有5個(gè)元素的數(shù)組,p+1往下指5個(gè)整形

注意:如果不加括號(hào)就變成int* p[5],這是一個(gè)指針數(shù)組,是一個(gè)一維數(shù)組,有5個(gè)元素,每個(gè)元素都是整形指針,占用20個(gè)字節(jié),而int(*p)[5]是一個(gè)指針變量,占用4個(gè)字節(jié)。

(1)一維數(shù)組指針主要配合二維數(shù)組使用,此時(shí)一維數(shù)組指針的元素個(gè)數(shù)必須等于二維數(shù)組的列數(shù)。

例如:

int main()

{

int a[3][5] = {

{1,3,5,7,9},

{2,4,6,8,10},

{7,9,1,13,12}

};

int(*p)[5]; //一維數(shù)組指針的元素個(gè)數(shù)必須等于二維數(shù)組的列數(shù)

p = a;

printf("a = %p, p = %p, &a[0][0] = %p\n", a,p, &a[0][0]);

printf("a+1 = %p,p+1 = %p, &a[1][0] = %p\n", a + 1,p + 1, &a[1][0]);


return 0;

}

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

a = 00EFF9A4, p = 00EFF9A4, & a[0][0] = 00EFF9A4

a + 1 = 00EFF9B8, p + 1 = 00EFF9B8, &a[1][0] = 00EFF9B8

(2)常用在函數(shù)傳參上,實(shí)參是n維數(shù)組,必須定義一個(gè)相同類型的n-1維數(shù)組的形參去接。

例如:

void fun(int(*p)[5],int x, int y)

{

p[1][2] = 100;


}


int main()

{

int a[3][5] = {

{1,3,5,7,9},

{2,4,6,8,10},

{7,9,1,13,12}

};

fun(a, 3, 5);

printf("a[1][2] = %d\n", a[1][2]);

return 0;

}

a是數(shù)組的首地址,是數(shù)組地址,或者叫數(shù)組指針,那么形參也必須是相同類型的,所以用int(*p)[5]數(shù)組指針類型去接

6.10.3 各種數(shù)組指針的定義

(1)一維數(shù)組指針,加1后指向下一個(gè)一維數(shù)組

int(*p)[5],配合每行有5個(gè)整形的二維數(shù)組使用,元素個(gè)數(shù)必須與二維數(shù)組的列數(shù)相同。

p指向第一行第一個(gè)元素, p+1指向第二行第一個(gè)元素。

(2)二維數(shù)組指針,加1后指向下一個(gè)二維數(shù)組

int(*p)[4][5],配合三維數(shù)組使用,這個(gè)三維數(shù)組是由若干個(gè)4行5列的二維數(shù)組組成的。

p指向第一個(gè)二維數(shù)組的第一行第一個(gè)元素,p+1指向第二個(gè)二維數(shù)組的第一行第一個(gè)元素。

(3)多維數(shù)組,類似地。

6.10.4 數(shù)組名字取地址,變成數(shù)組指針

int a[10];

a 是數(shù)組的首地址,是int*類型的整形指針,a+1跳一個(gè)元素,是a[1]的地址。

&a 變成了一個(gè)一維數(shù)組指針,是int(*p)[10]類型的一維數(shù)組指針,(&a)+1 和 &a相差一個(gè)數(shù)組,即10個(gè)元素,即40個(gè)字節(jié)

而a 和 &a代表的地址編號(hào)是一樣的,它們都指向同一個(gè)內(nèi)存地址,但所表示的數(shù)據(jù)類型不一樣。

int main()

{

int a[10];

printf("a = %p\n", a);

printf("a+1 = %p\n", a + 1);

printf("&a = %p\n", &a); //&a變成了一維數(shù)組指針類型,int(*p)[10]

printf("(&a)+1 = %p\n", &a+1); //&a+1指向下一個(gè)一維數(shù)組。

return 0;

}

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

a = 00F5FA9C

a + 1 = 00F5FAA0

& a = 00F5FA9C

(&a) + 1 = 00F5FAC4

6.10.5 數(shù)組名字和指針變量的區(qū)別

int a[5];

int* p;

p = a;

數(shù)組名字是數(shù)組的首地址,是a[0]的地址,存放的是地址編號(hào),指向a[0];

p = a;即p保存了a的地址,也指向a[0],所以在引用數(shù)組元素的時(shí)候a和p等價(jià)。

注意

1、a是常量,是a[0]的地址,而p是指針變量,所以可以給p賦值,但不能給a賦值

2、對(duì)a和p的取地址結(jié)果不同,p是指針變量,對(duì)它取地址得到變量p的地址編號(hào),即指針的指針int**,而a是數(shù)組的名字,對(duì)a取地址&a得到數(shù)組指針int(*p)[5],a和&a的地址編號(hào)是一樣的,都指向a[0]。

6.10.6 數(shù)組指針取*

數(shù)組指針取*不是取值的意思,而是指針的類型發(fā)生變化,

一維數(shù)組指針取*,結(jié)果為它指向的一維數(shù)組第0個(gè)元素的地址,它們還是指向同一個(gè)地方。

二維數(shù)組指針取*。結(jié)果為一維數(shù)組指針,它們還是指向同一個(gè)地方。

三維數(shù)組指針取*。結(jié)果為二維數(shù)組指針,它們還是指向同一個(gè)地方。

int main()

{

int a[3][5] = {0};

printf("a = %p\n", a); //a是二維數(shù)組的名字,是第0個(gè)一維數(shù)組的首地址,是個(gè)數(shù)組指針

printf("a +1 = %p\n", a + 1); //a +1是下一個(gè)一維數(shù)組的首地址,即第1個(gè)一維數(shù)組的地址

printf("*a = %p\n",*a); //*a是第0行第0列的元素的地址,即&a[0][0]

printf("*a +1 = %p\n", *a + 1); //*a +1是第0行第1列的元素地址,即&a[0][1]


int(*p)[5];

p = a;

printf("p = %p\n", p);

printf("*p = %p\n", *p);

printf("*p +1 = %p", *p + 1);



return 0;

}

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

a = 00AFFA68

a + 1 = 00AFFA7C

* a = 00AFFA68

* a + 1 = 00AFFA6C

p = 00AFFA68

* p = 00AFFA68

* p + 1 = 00AFFA6C

6.11 指針和函數(shù)的關(guān)系 6.11.1 指針作為函數(shù)的參數(shù)

我們可以給函數(shù)傳一個(gè)整形、浮點(diǎn)型、字符型的數(shù)據(jù),也可以傳一個(gè)地址。

int num;

scanf("%d",&num);

scanf函數(shù)通過鍵盤輸入獲取一個(gè)整數(shù),然后將它存到一個(gè)地址處(這里是num的地址,也就是給num賦值)

函數(shù)傳參

1、傳數(shù)值

void swap(int x, int y) //x,y是形參,是定義被調(diào)函數(shù)時(shí),函數(shù)名括號(hào)里的數(shù)據(jù)

{

int temp;

temp = x;

x = y;

y = temp;

}


int main()

{

int a = 10, b = 20;

swap(a, b); //a,b是實(shí)參,是調(diào)用函數(shù)時(shí)傳的參數(shù)

printf("a = %d, b = %d\n", a, b);

return 0;

}

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

a = 10, b = 20

swap函數(shù)調(diào)換的是x和y兩個(gè)數(shù)的值,而輸出的a和b沒有改變。

所以給被調(diào)函數(shù)傳數(shù)值,只能改變被調(diào)函數(shù)形參的值,不能改變主調(diào)函數(shù)實(shí)參的值。

2、傳地址

例1:

void swap(int* x, int* y)

{

int* temp;

temp = x;

x = y;

y = temp;

}


int main()

{

int a = 10, b = 20;

swap(&a, &b);

printf("a = %d, b = %d\n", a, b);

return 0;

}

結(jié)果是:a = 10; b = 20;

例2:

void swap(int* x, int* y)

{

int temp;

temp = *x;

*x = *y;

*y = temp;

}


int main()

{

int a = 10, b = 20;

swap(&a, &b);

printf("a = %d, b = %d\n", a, b);

return 0;

}

a = 20, b = 10,成功交換了a和b的值。

這里傳給swap函數(shù)的是a和b的地址,swap函數(shù)將地址指向的值相互調(diào)換,從而改變了主調(diào)函數(shù)的實(shí)參

?。?!要想改變主調(diào)函數(shù)中的變量的值,必須通過傳變量地址,并且使用*+地址賦值,無論這個(gè)變量是什么類型的,才能改變主調(diào)函數(shù)實(shí)參的值

void fun(char* q)

{

q = "hello kitty";

}


int main()

{

char* p = "hello world";

fun(p);

printf("%s", p);

return 0;

}

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

hello world

fun函數(shù)中改變的是局部變量q,沒有改變main函數(shù)中變量p,所以p還是指向“hello world”

void fun(char** q)

{

*q = "hello kitty";

}


int main()

{

char* p = "hello world";

fun(&p);

printf("%s", p);

return 0;

}

hello kitty

3、傳數(shù)組

給函數(shù)傳數(shù)組的時(shí)候不能一下將數(shù)組的內(nèi)容作為整體傳進(jìn)去,只能傳數(shù)組的名字進(jìn)去,而數(shù)組的名字是數(shù)組的首地址,即4個(gè)字節(jié)的地址編號(hào)

(1)傳一維數(shù)組的地址,只能傳數(shù)組的名字(首地址),所以要用對(duì)應(yīng)數(shù)據(jù)類型指針去接,用int* p或int p[],編譯器都認(rèn)為是int*的整形指針

//void fun(int p[])

void fun(int* p)

{

printf("p[2] = %d\n", p[2]);

*(p + 3) = 100;


}

int main()

{

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

fun(a);

printf("a[3] = %d\n", a[3]);

return 0;

}

(2)傳二維數(shù)組的地址,要用一維數(shù)組指針去接,用int(*p)[3]或int p[][3],編譯器都認(rèn)為是數(shù)組指針

//void fun(int p[][3], int x, int y)

void fun(int(*p)[3], int x, int y)

{

int i, j;

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

{

for ( j = 0; j< y; j++)

{

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

}

printf("\n");

}

}


int main()

{

int a[2][3] = {

{1,4,5},

{2,8,0}

};

fun(a,2,3);

return 0;

}

(3)傳指針數(shù)組,也只能傳首個(gè)元素的地址,由于每個(gè)元素都是指針,所以傳的是指針的指針,要用指針的指針char**,或指針數(shù)組char* p去接,編譯器都認(rèn)為是指針的指針。

//void fun(char* p[],int x)

void fun(char** p, int x)

{

int i;

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

{

printf("q[%d] = %s\n", i,p[i]);

}

}

int main()

{

char* p[3] = { "hello","world","kitty" }; //定義了一個(gè)指針數(shù)組,數(shù)組的每個(gè)元素都是char*類型的字符指針

fun(p, 3);

return 0;

}

6.11.2 指針作為函數(shù)的返回值
char* fun()

{

char str[100] = "hello world";

return str;

}


int main()

{

char* p;

p = fun();

printf("p = %s\n", p);

return 0;

}

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

p = hello world

注意,雖然在VS中得到了p = hello world,報(bào)了警告:warning C4172: 返回局部變量或臨時(shí)變量的地址: str,

fun函數(shù)中定義的str是局部變量,在fun函數(shù)結(jié)束后被釋放了,所以p在打印時(shí)是一個(gè)野指針,指向的值是不確定的,有可能p指向的數(shù)據(jù)被別的替換了,不再是“hello world”。

修改方法1:

返回靜態(tài)局部數(shù)組的地址,靜態(tài)局部變量的生命周期是從第一次調(diào)用函數(shù)到程序結(jié)束,而不是像普通局部變量一樣函數(shù)結(jié)束就釋放掉。

char* fun()

{

static char str[100] = "hello world";

return str;

}

修改方法2:

返回文字常量區(qū)的地址

char* fun()

{

char* str = "hello world";

return str;

}

修改方法3:

返回堆內(nèi)存的地址,堆區(qū)的內(nèi)容一直存在,直到free釋放。

#include#include#includechar* fun()

{

char* str;

str = (char*)malloc(100);

strcpy_s(str,100, "helloworld");

return str;

}


int main()

{

char* p;

p = fun();

printf("p = %s\n", p);

free(p);

return 0;

}

6.11.3 指針保存函數(shù)的地址(函數(shù)指針)

1、概念

我們定義的函數(shù)在運(yùn)行的時(shí)候,會(huì)將函數(shù)的指令加載到內(nèi)存的代碼段,函數(shù)也有起始地址

C語言規(guī)定:函數(shù)的名字就是函數(shù)的首地址,即函數(shù)的入口地址。

所以可以定義一個(gè)指針變量,存放函數(shù)的地址,即函數(shù)指針變量。

2、函數(shù)指針用處

保存函數(shù)的入口地址,在項(xiàng)目開發(fā)中,經(jīng)常需要便攜或者調(diào)用帶函數(shù)指針參數(shù)的函數(shù)

3、函數(shù)指針變量的定義

返回值類型(*函數(shù)指針變量名)(形參列表);

int(*p)(int,int);//定義了一個(gè)函數(shù)指針變量p,p指向的函數(shù)必須有一個(gè)整形的返回值,且有兩個(gè)整形的參數(shù)。

比如max函數(shù):

int max(int x,int y)

{

}

就滿足這個(gè)條件,所以可以用p來保存類如max函數(shù)的地址

4、調(diào)用函數(shù)的方法

(1)通過函數(shù)的名字調(diào)函數(shù)(最常用)

int max(int x, int y)

{

}

(2)通過函數(shù)指針變量調(diào)用函數(shù)

#includeint max(int x,int y)

{

if (x >y) return x;

else return y;

}

int min(int x, int y)

{

if (x >y) return y;

else return x;

}

int main()

{

int (*p)(int, int);

int num;

num = max(10, 20); //通過函數(shù)名調(diào)用函數(shù)

printf("max = %d\n", num);

p = min;

num = (*p)(10, 20); //通過函數(shù)指針變量調(diào)用函數(shù),使用p或*p都可以

printf("min = %d\n", num);

return 0;

}

5、函數(shù)指針數(shù)組

概念:這個(gè)數(shù)組是由若干個(gè)相同類型的函數(shù)指針變量構(gòu)成的集合,在內(nèi)存中連續(xù)的順序存儲(chǔ)

注意:函數(shù)指針數(shù)組是一個(gè)數(shù)組,每個(gè)元素都是一個(gè)函數(shù)指針變量

定義:類型名(*數(shù)組名[元素個(gè)數(shù)])(形參列表)

int(*p[5])(int,int);

定義了一個(gè)函數(shù)指針數(shù)組,有5個(gè)元素p[0]~p[4],每個(gè)元素都是函數(shù)指針變量,每個(gè)函數(shù)指針變量指向的函數(shù),必須有整形的返回值和兩個(gè)整形參數(shù)

int max(int x, int y)

{

if (x >y) return x;

else return y;

}


int min(int x, int y)

{

if (x >y) return y;

else return x;

}


int add(int x, int y)

{

return x + y;

}


int sub(int x, int y)

{

return x - y;

}


int mux(int x, int y)

{

return x * y;

}


int main()

{

int min_xy;

int(*p[5])(int, int) = { mux,min,add,max,sub };

min_xy = p[1](2, 5);

printf("min_xy = %d\n", min_xy);

return 0;

}

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

min_xy = 2

這些函數(shù)都有一個(gè)共同點(diǎn):返回值是整形int,都有兩個(gè)整形參數(shù)。

6、應(yīng)用舉例

#includeint max(int x, int y)

{

if (x >y) return x;

else return y;

}


int min(int x, int y)

{

if (x >y) return y;

else return x;

}


int add(int x, int y)

{

return x + y;

}


int sub(int x, int y)

{

return x - y;

}


int mux(int x, int y)

{

return x * y;

}


int process(int(*p)(int, int), int x, int y)

{

int ret;

ret = (*p)(x, y);

return ret;

}


int main()

{

int num;

num = process(add, 10, 20);

printf("num = %d\n", num);

return 0;

}

6.12 經(jīng)常容易混淆的指針

int* a[10]; //這是一個(gè)指針數(shù)組,占用40個(gè)字節(jié),數(shù)組a中有10個(gè)元素,每個(gè)元素都是整形指針

int(*a)[10]; //這是一個(gè)數(shù)組指針變量a,占用4個(gè)字節(jié),它指向一個(gè)有10個(gè)元素的一維整形數(shù)組,a+1指向下一個(gè)數(shù)組(即跳過10個(gè)整形)

int** p; //二級(jí)指針,指針的指針,保存指針變量的地址

int* f(void); //這是函數(shù)的聲明,聲明的這個(gè)函數(shù)返回值是整形指針int*類型的

int(*f)(void); //*修飾f,f是一個(gè)函數(shù)指針變量,存放函數(shù)的入口地址,這個(gè)函數(shù)的返回值是整形的,沒有參數(shù)

6.13 特殊指針

1、空類型的指針(void*)

char*類型的指針變量,只能保存char型的數(shù)據(jù)的地址;

int*類型的指針變量,只能保存int型的數(shù)據(jù)的地址;

而void*類型的指針變量,可以指向任何類型的數(shù)據(jù)的地址,同樣在32位系統(tǒng)下占用4個(gè)字節(jié)

2、NULL

空指針:char* p = NULL;

可以認(rèn)為p哪里都不指向,也可以認(rèn)為p指向內(nèi)存編號(hào)為0的存儲(chǔ)單位,p存放的是0x00 00 00 00。

一般用NULL給指針初始化。

3、main函數(shù)傳參

int argc 是傳參的個(gè)數(shù),char* argv[]保存的是傳過來參數(shù)的首地址

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


當(dāng)前文章:C語言學(xué)習(xí)(7)第六章指針6.7-6.13-創(chuàng)新互聯(lián)
標(biāo)題網(wǎng)址:http://weahome.cn/article/dejpgd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部