指针,指向指针的指针,指针数组,数组指针,函数指针,函数指针数组

1.指针

指针;一个变量的地址称之为指针,但是不能说地址就是指针
指针变量,存放变量地址的变量叫做指针变量

指针有类型,有大小。
int a=66;
int * p= &a; 这个时候我们就定义了一个指向a这个整形变量的指针
这个指针叫做整形指针, 你可以把int * 当作一个类型,与int char等类似的类型,只不过这个类型用于存储整形变量的地址,他会前进四个字节,也就是一个int类型的大小。(在51单片机里int类型并非四个字节)

char b=‘a’;
char * pp=&b;
这个指针叫做字符指针,我们定义了一个指向b的字符指针,需要切记的是,我们指向那个变量,就需要定义与变量相符合的指针类型 ,a是整形,所以我们需要定义成int *,b是字符型,所以我们需要定义成char *

int * p=NULL,在c语言里,这条语句的意思是为指针给一个初值,这个初值为null,也就是空,也就是空指针,我们在声明一个指针的时候,因为编译器并不会完成他的初始化,他指向的内存区域是不确定的,所以我们需要先将其初始化。

需要知道的是,指针变量声明后,编译器就会开辟一段内存空间,也就是说,指针存储了一段指向变量的地址,同时自身也是有一段内存地址。也就是下面的这一串代码
int a =66;
int *p=&a;
int **pp=&p;
//这三行代码,我们定义了一个整形变量a,并且定义了一个一级指针p指向这个变量的地址,同时我们定义了一个二级指针指向这个一级指针的地址。 在vs里我们进行打印这三个变量的值,以及地址。

在这里插入图片描述
看上面这行代码以及运行的结果,我们发现a等于66,*p=66,**pp=66
需要注意的是,我们没有打印换行,因此地址后面都会带两个数字66 这是因为a=66
而&a,与&p的地址是不一样的,为什么呢?就如上面所说的

指针本身是有地址的因此&p的地址就是p本身的地址,而如果
我们打印的是p,就会显示出a的地址。

对于指向指针的指针,也就是上面的**pp,这个也叫做二级指针
对于二级指针来说,pp存储了p的地址,一个星号,也就是*pp,我们根据地址取出内容

取出了p存储的a的地址,又一个星号,我们又根据p存储的a的地址取出了a的值也就是66

int a[3]={66,77,88};
int *p=a;//需要知道的是,数组名就是该数组的首地址,等价于&a[0]
p++;
printf("%d",*p);//结果为77
程序是这么分析的,首先我们指向了a[0]的地址,然后我们进行了指针加加,第一行说过,指针不仅有类型也有大小,这时候加加,就是偏移了一个指针所指向的int类型的大小,也就是4个字节,从a[0]指向了a[1],我们通过*运算符取出了p存储a[1]的地址的内容,所以有了77这个结果。







``那么,指针能加加,能减减,可以两个指针进行

相加或者相减吗?能相互比较吗?

1.指针是可以相互比大小的,比较了指针所指向变量在内存区域里面存储的先后。
2.2个指针可以相减,2个指针相减返回值是一个有符号的整数

这个是两个指针指向的变量所在的内存区域的差除以指针类型所占用的字节数。

2.数组指针与指针数组****
int a[3][4]; 这是一个二维数组,有三行四列,我们知道指针可以指向一片内存地址
那么,我们如何指向编译器为二维数组所分配的这一片内存呢?这个时候我们需要的指针就叫做数组指针
其定义的一般形式为:int(*P)[4]; 对照二维数组,我们定义的指针,其他方面都不变。唯一的是后面加上了[4],也就是数组列的大小。
在这里需要明确的几个概念是,
1.p=a,意思是把a的地址赋值给p,a等价于a[0]等价于&a[0][0]
对于一片内存来说,二维数组一共分配了三行四列,每一行都有每一行的首地址
每一列都有每一列的首地址,
a[0]即是第一行的首地址,a[1]第二行,以此类推

指针数组;即这个数组存储的变量都是指针变量。
char *p[3]={“notepad”,“calc”,“much”);
p[0]就是字符串notepad的首地址,p[1]就是calc,p[2]就是much的首地址。
对于指针数组来说,我们可以使用它指向一个二维数组,存储二维数组每一行的地址
也可以用于保存很多字符串。

3.函数指针
函数指针,在c语言里,每一个函数都有编译器为其划分的一片内存空间。而函数指针就是指向这一片内存空间起始地址的指针。
一般形式为;

在这里插入图片描述

`

观看这段代码指向函数,我们就需要函数指针,函数指针定义方法是这样的
一个函数比如add,我们int add(int a ,int b);我们想指向这个函数的内存。
我们就需要这么做,首先将add挖空,变成*指针名,
也就是int (*p)(int a,int b);注意,在形式参数里,ab是可以省略的也就是上图的代码
上面这段代码我们要怎么分析呢?
首先我们定义了一个加函数,对传递过来的2个参数进行相加,以及定义了一个减函数,对传递过来的参数进行相减。其次定义了一个函数,用于传递2个值,以及一个函数的地址,在c语言里,对于函数来说函数名就是地址。
第一句打印我们传递了add函数的地址,并且传递了ab的值所以我们打印出了20+10等于30
第二局打印我们传递了jian函数的地址,且传递了ab的值,于是打印出了10

4;函数指针数组
何为函数指针数组?存储一片函数地址的数组就叫函数指针数组
其定义的一般形式为:int(*p[5])(int,int); 这是一个怎么样的函数指针数组呢?
存储了5个函数,这五个函数都有2个整形的形式参数。比如上图的代码,我们定义了加减函数那么我们如何缩短一行,就是少打印一次就可以输入相加相减的结果呢?

这样。
在这里插入图片描述

我们通过函数指针数组,保存了三个函数的地址,并且调用了这三个函数。

发布了3 篇原创文章 · 获赞 3 · 访问量 69

猜你喜欢

转载自blog.csdn.net/m0_46300070/article/details/105440239
今日推荐