基础的指针知识~小总结

一级指针

指针是什么?
简单点来说,指针变量是一个用来存放地址的变量。指针变量是一个变量,指针就是地址。
指针的大小?
由于指针是用来存放地址的,地址是唯一标识一块地址空间的。
在32位的机器上,地址是32个0或1组成的二进制序列,那地址就得用4个字节的空间来存储,因此在32位平台下,指针变量的大小为4个字节。
在64位机器上,指针变量的大小为8个字节。

指针的存储形式
int *p;
把这个 4 个字节大小的空间命名为 p,同时限定这 4 个字节的空间里面只能存储某个内存地址,即使你存入别的任何数据,都将被当作地址处理,而且这个内存地址开始的连续 4 个字节上只能存储某个 int类型的数据。
在这里插入图片描述

指针的解引用*操作
对一个指针进行*操作,是为了的到该指针所指向的目标的内容。
int n=10;
int *p=&n;
p的值很明显是10,如果将p比作是n空间的门,那么就是打开这扇门的钥匙。

指针的运算

  • 指针与整数的加减法

指针与整数进行加减法,指针的类型决定了指针先前或向后走一步有多大,指针+1就相当于加上其指向的目标的类型的大小(sizeof(type))。
在这里插入图片描述
从图中我们可以很清楚的看到指针在加1后地址加了4。这是因为指针p指向目标n的类型是int型,所以其加1是加上了sizeof(int)。其他类型也是同样的做法。

  • 两指针相减

两个指针相减的结果是两指针中元素的个数(由两指针的类型决定)
在这里插入图片描述

  • 指针的比较

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针进行比较,但不允许与指向第一个元素之前的那个内存位置的指针进行比较。
(注意:虽然允许与指向数组最后一个元素后面的那个内存位置的指针进行比较,但不允许对其进行赋值操作,这已经越界了。)

int main()
{
	float value[5];
	float *vp;
	for (vp = &value[4]; vp >= &value[0]; vp--)//指针的比较,数组首元素的地址是最小的地址
	{
		*vp = 0;
	}
	system("pause");
	return 0;
}

二级指针

char **p;
定义了一个二级指针变量 p。p 是一个指针变量,在 32 位系统下占 4 个 byte。它与一级指针不同的是,一级指针保存的是数据的地址,二级指针保存的是一级指针的地址。

指针与数组

指针与数组之间没有关系,只是在元素访问时有一定的相似性。

指针访问数组的方式
eg: char a[7];
(1)以指针的形式访问:

*(a+4)。a 这时候代表的是数组首元素的首地址,加上 4 个字符的偏移量,得到新的地址,然后对新地址进行解引用得到他的值。(偏移量 4 代表的是 4 个元素)

(2)以下标的形式访问数组:

a[4]。编译器总是把以下标的形式的操作解析为以指针的形式的操作。a[4]这个操作会被解析成:a 作为数组首元素的首地址,然后加上中括号中 4 个元素的偏移量,计算出新的地址,然后从新的地址中取出值。

注意:a只有在以下两种情况下表示数组的首地址
(1)sizeof(a);
(2)&a;
在其他情况下,均表示数组首元素的地址。

指针数组和数组指针

指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。eg: int *p1[10];

数组指针:首先它是一个指针,它指向一个数组。在 32 位系统下永远是占 4 个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。
eg: int (*p2)[10];
(通过左右两边操作符的优先级来决定是数组还是指针,[ ]的优先级高于 * ,()的优先级高于[ ] )

数组的传参
C 语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素内部类型的指针。

二维数组传参:void fun(char a[3][4]);
把 a[3][4]理解为一个一维数组 a[3],其每个元素都是一个含有 4 个 char 类型数据的数组。因此,我们可以把这个函数声明改写为:
void fun(char (*p)[4]);

函数指针

函数指针就是函数的指针。它是一个指针,指向一个函数。
eg: char * (*fun1)(char * p1,char * p2);
fun1 是一个指针变量,它指向一个函数。这个函数有两个指针类型的参数,函数的返回值也是一个指针。

(*(void( * ) () )0)()------这是什么?
1, void ( * )() 这是一个函数指针类型
2,(void( * ) () )0 在0的前面对这个函数指针类型加(),是对0进行强制类型转换,将0强转成一个函数的地址,也就是说一个函数存在首地址为 0 的一段区域内。
3, ( * (void(*) ())0),这是取 0 地址开始的一段内存里面的内容,其内容就是保存在首地址为 0 的一段区域内的函数。
4, ( * (void( * ) () )0)();调用0地址处所标识的函数。

函数指针数组

char * (*pf[3])(char * p);
这是定义一个函数指针数组。它是一个数组,数组名为 pf,数组内存储了 3 个指向函数的指针。这些指针指向一些返回值类型为指向字符的指针、参数为一个指向字符的指针的函数。

函数指针数组的指针

char * (*(*pf)[3])(char * p);
pf 是一个指针。这个指针指向一个包含了 3 个元素的数组;这个数组里面存的是指向函数的指针;这些指针指向一些返回值类型为指向字符类型的指针、参数为一个指向字符类型的指针的函数。

猜你喜欢

转载自blog.csdn.net/weixin_44930562/article/details/91631074