带你深入了解了解指针(1)

时间:2023-01-15 12:55:17

本次与大家分享一些指针的知识,帮助大家进一步了解指针。废话就不多说了,直接进入正题;

首先,我们先回顾指针初步学习的几个重要的知识。

1.指针就是一个变量,用来存放地址,地址是一块空间的唯一标识

2.指针的大小是固定的,32位的是4字节,64位的是8字节.

3.指针是有类型的,类型决定了指针在加减整数的步长,指针在解引用的时候的权限

4.指针的运算。一般用于数组,两个地址的差的绝对值为元素个数。

char *p="hello";

思考以上这一行代码是什么意思呢?它真实存在吗?

答案是这一行代码在程序中是可以存在的,"hello"这串字符储存空间的首地址被存到了p中。由于"hello"是一个字符串常量,所以p是不能不能被更改的

const char *p="hello";//这样写会更为严谨一些


说到这,我们不得不说说两个程序:

第一个是:

#include<stdio.h>
int main()
{
char *p="hello";
*p='w';//解引用,给p赋值,这里随便举的例子'w'
printf("%s",p);
return 0;
}

编译器在编译的时候,不会报错。但程序运行起来会崩。

当我们在char之前后程序才会报错,所以,我们在编写代码时,要严谨一点,加上const。

const char *p="hello";0

第二个是:

#include<stdio.h>
int main()
{
char Stu1[]="hello";
char Stu2[]="hello";
char *p1="hello";
char *p2="hello";
if(Stu1==Stu2)
printf("Stu1 and Stu2 are the same\n");
else
printf("Stu1 and Stu2 are not the same\n");
if(p1==p2)
printf("p1 and p2 are the same\n");
else
printf("p1 and p2 are not the same\n");
return 0;
}

运行结果为:Stu1 and Stu2 are not the same

                          p1 and p2 are the same

你写对了吗?我们来分析一下原因:首先,两个数组开辟了两个不同的空间,空间不同地址自然也不同。第6行代码,执行把“hello”这个字符串常量常量储存到一个空间后把首元素的地址赋给p1,此时,这个字符串是不是有空间了。当第7行代码执行的时候,会把“hello”这个字符串所在空间的首元素地址赋给p2(这里不会另外再开辟一个空间去储存,你自己想想,同样的东西为啥要再存一遍,还存到一个不同的空间去)。

接下来我们讲讲指针数组

指针数组本质是一个数组。那指针数组怎么定义呢?

首先,定义一个数组arr[10],然后加上*表示数组的每个元素是指针,最后加上指针所对应内容的类型,我们以int为例。

int *arr[10];//首先arr[10],其次,*arr[10],最后int *arr[10]

当然,你也可以这样理解,类比整型数组定义,数组存放的是整型int,所以,定义为int arr[10],而指针数组存放的是指针int *,所以,定义为int *arr[10]

讲完指针数组,我们讲讲数组指针

数组指针本质上是一种指针。我们如何去定义数组指针呢?

我们可以类比其他指针的一个定义方式,我们以整型指针来举例类比

int a=10;
int *p=&a;
//首先,变量p是一个指针变量需加上*表示,得到*p,其次,指针指向的a
//为类型为整型,所以,在*p前面加上int表示指针指向的空间存放的是一个整型数据
int arr[20];
int (*pp)[20]=&arr;
//这是我们用上面思路得出的结果,同样的,首先,变量pp是一
//个指针变量需加上*来表示,得到*pp,其次,该指针指向的空间存放的是一个数组,数
//组的类型是int [20];所以,给*pp加上int [20]便得到了数组指针。为什么要加括号
//把*pp给括起来呢?方括号的优先级大于*,没有括号()的话,pp先与方括号[],就变
//成了指针数组。

函数函数,函数有没有指针呢?

答案是有函数指针

函数指针怎么定义呢?它的方法与数组指针类似。

举个例子:

int txt(int x,int y)
{}//函数txt
//与数组指针相同先给一个变量P,由于是指针需要加上*,得到*p
//然后找该指针指向空间内容的类型,此例题函数的类型是int (int,int)
//的出结果
int (*p)(int,int)=&txt;
//这时,有些人脑洞大开,数组名为首元素地址,函数名是不是也有?
//答案是没有,函数名也表示函数所在空间的地址,即txt与&txt等价
int (*p)(int,int)=txt;//也是对的

好了,到这里我们本次的分享就结束了。感觉对你有帮助的,可以给我点个赞,让我知道你有所收获。如果期待下一次的分享,可以给我点个关注噢。如果有兴趣的可以思考一以下两行代码,它们出自《c陷阱和缺陷》,下一篇文章我会对此做一个简单的分享

(*(void(*)())0)();
void(*signal(int,void(*)(int)))(int);