首页 >  聚焦 >

UC头条:[C语言]带你彻底理解指针(详解)

2023-05-31 15:12:10 来源:个人图书馆-cnzrp

指针的介绍:

指针是一个用来存放地址的变量,可以通过指针存放的地址找到对应位置的值,对其进行使用。

指针在32位平台下的大小是4个字节,在64位平台下是8个字节。(这是因为32位平台下内存地址是由32根地址线组成,一根地址线就是1bit,用4个字节就可以存下,而64位平台有64根地址线,需要八个字节才可以存下)。


(资料图)

如果对指针进行加减与解引用操作,则±的步长与解引用操作的长度由指针类型决定,指针类型是几个字节±步长与解引用就是几个字节。

一、简单指针

char*pc(字符指针)

int*pi(整形指针)

float*pf(浮点型指针)

还有short…double等等,拿部分举例。

1.1指针的定义与使用

这三种指针的用法基本相同,只不过char*指针存放的是char变量地址,int型指针存放的是int变量地址,float指针存放的是float变量地址。

#define_CRT_SECURE_NO_WARNINGS1#includeintmain{chara="a";//定义一个char类型变量char*pa=&a;//*号先与pa结合说明pa是一个指针类型,指向的是char型数据的地址,将a的地址给到pa*pa="b";//通过pa改变a的值printf("%c",a);//bintnum=10;int*pnum=#*pnum=20;printf("%d",num);floatf=9.0;float*pf=&f;*pf=5.0;printf("%d",f);}

我们可以使用指针对指针指向的变量进行使用(修改或输出)。

1.2指针与数组

数组名就是数组的首地址。

代码示例

点击加载图片

得到数组首地址可以通过指针遍历数组

代码示例

点击加载图片

二、指针数组✨

指针数组就是用来装指针的数组

intp1[];//(方便理解拿整形数组对比)p1与[]结合说明p1是数组,装的是int类型的数据int*p2[];//[]优先级比*高p2先与[]结合,说明p2是一个数组里面装的是int*类型的数据

举个例子

#includeintmain{inta=0;intb=0;intc=0;int*arr[3]={&a,&b,&c};//指针数组就是数组的每个位置都存储一个地址(指针)}

三、数组指针

3.1数组指针的定义

数组指针与指针数组名字非常相似但是却截然不同,数组指针是一个指针,指针数组是一个数组

//对比一下指针数组和数组指针int*pa[];//这是指针数组,优先级问题,pa先与[]结合,说明pa是一个数组,装的是int*的数据int(*pa)[]//这是数组指针,优先级更高,pa先与*结合,说明pa是一个指针,指向一个int类型的数组

3.2”数组名“与”&数组名“

前面说了数组名代表数组首元素地址,那&数组名呢?

代码示例

点击加载图片

对数组名与&数组名进行输出,发现地址一样

点击加载图片

对数组名与&数组名+1,发现数组名加了四个字节,而&数组名加了十六进制的28,也就是十进制的40,为整个数组的大小。

结论:数组名与&数组名地址一样,但是数组名代表的是首元素地址,而&数组名代表的是整个数组。

3.3数组指针使用

voidprint(int(*pa)[3]){for(inti=0;i<2;i++){for(intj=0;j<3;j++){printf("%d",arr[i][j]);}}}intmain{intarr[2][3]={0,1,2,3,4,5};print(arr);//二维数组首地址相当于&(第一个一维数组)}

四、函数指针邏

函数指针就是指向函数的指针

函数指针的定义

*函数返回值(pa)(函数参数)

可以看作pa先与*结合,说明pa是个指针,指向一个函数

4.1函数指针的使用

代码示例

intadd(inta,intb){returna+b;}intmain{int(*pa)(int,int)=add;inta=3;intb=4;printf("%d",pa(3,4));//7}

五、函数指针数组

函数指针数组就是用来装函数指针的数组,需要注意每个函数指针数组的返回值和参数必须相同类型

函数指针数组的定义

*函数返回值(pa[])(函数参数)

可以看作pa先与[]结合说明pa是一个数组,每个位置装的是函数指针(地址)

5.1函数指针数组的使用

#includeintadd(inta,intb)//需要注意函数指针数组的每个参数类型与返回值类型必须相同{returna+b;}intsub(inta,intb){returna-b;}intmul(inta,intb){returna*b;}intdiv(inta,intb){returna/b;}voidmenu{printf("***************\n");printf("1:add2:sub\n");printf("3:mul4:div\n");printf("0:quit\n");printf("**************\n");}intmain{intx=0;inty=0;intinput=0;intret=0;int(*p[5])(intx,inty)={NULL,add,sub,mul,div};do{menu;printf("请选择:");scanf("%d",&input);if(input>=1&&input<=4){printf("输入两个数字:");scanf("%d%d",&x,&y);ret=(*p[input])(x,y);}elseif(input==0){break;}else{printf("请输入0-4的数字\n");continue;}printf("%d\n",ret);}while(input);}

点击加载图片

六、指向函数指针数组的指针

函数指针数组的定义为int(*pa[5])(参数),指向函数指针数组的指针就是:

int((*pa)[5])(参数)//用括号把pa括起来使得pa先与*结合,说明pa是一个指针,返回值类型就为函数指针数组

点击加载图片

指向函数指针数组的指针的定义

voidtest(char*str){printf("指针真简单,%s",str);}intmain{//定义一个函数指针数组void(*pa[5])(char*);pa[0]=test;//指向函数指针数组的指针void(*(*ppa)[5])(char*)=&pa;return0;}

七、回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

stdlib头文件下的qsort函数就是一个回调函数,链接:qsort函数详解

完结

创作不易,还请各位小伙伴多多点赞关注✨收藏⭐

标签:

珠宝展示