1.指针变量的类型和意义
既然不同类型的指针变量大小都一样,那么我们为什么不直接规定成一个变量,而是保留了这么多类型呢?其实不同的指针类型是有区别的,
- 指向的数据类型:不同指针变量可以指向不同数据类型的变量。例如,int类型的指针变量可以指向int类型的变量,而char类型的指针变量可以指向char类型的变量。
- 存储的地址:不同指针变量存储的地址是不同的,因此它们可以指向不同的变量。
- 大小和类型:不同指针变量的大小和类型也可能不同,这取决于操作系统和编译器的实现。
- 用途:不同指针变量可以用于不同的操作,比如访问和修改内存中的数据,传递变量的地址给函数等。不同指针变量也可以用于不同的数据结构,如链表、树等。
- 生命周期:不同指针变量的生命周期可能不同,某些指针变量可能只在特定的作用域内有效,而其他指针变量可能在整个程序执行期间都有效。 总之,不同指针变量的区别主要在于指向的数据类型、存储的地址、大小和类型、用途以及生命周期等方面。这些区别决定了它们在程序中的具体用途和限制。
这些我们后边慢慢学习。
a.指针解引用
我们来看下面两个代码
两个代码一模一样一个是int*,一个是char*,那它们有什么区别呢?
先来看int*
这里我们通过监视和查看内存
然后我们设置一个断点,一步一步来,
我们注意这里最后a变成了 00 00 00 00这个现象
然后来看char*
我们用同样的步骤,再来对char*来一遍
首先是监视,内存
接着我们设置一个断点,一步一步调试
通过两个对比,很显然我们可以发现,int*和char*是有明显不同的。指针的类型决定了对指针解引用的权限,也就是一次能操作几个字节,比如:char*一次只能访问1个字节,int*一次能访问4个字节 ,这是不同类型指针的一个很大的区别。
b.指针的加减
先来看一段代码:
#include<stdio.h>
int main()
{
int n = 10;
char* pa = (char*)&n;
int* pi = &n;
printf("%p\n", &n);
printf("%p\n", pa);
printf("%p\n", pa+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0;
}
根据我们之前的认识,我们其实可以自己在心里先猜测一个结果,然后下边给出结果
我们贴张清晰的图看看
这么看是不是很清楚了。char型一次内存加1,就是加了一个字节呗,int型内存一次加4,就是4个字节呗。所以说指针类型决定了指针向前或向后一步走了多大(距离)
c.void*指针
void*指针是一种特殊类型的指针,它可以指向任意类型的数据,包括基本数据类型和用户自定义的数据类型。它是一种通用的指针类型,可以用于不同类型的指针之间的转换。
void指针的声明和使用方式与其他指针类型类似,可以通过指针操作符()来访问指针指向的内存空间。但与其他指针类型不同的是,void*指针不能直接用于解引用操作,也不能进行指针加减,因为它没有具体的数据类型信息,无法确定要访问的数据的大小和类型。
在使用void指针时,通常需要将其转换为具体的类型指针才能进行相关操作。这可以通过类型转换操作符将void指针转换为特定类型的指针来实现。例如,可以将void指针转换为int*指针、char*指针等。
使用void指针的一个常见场景是在函数参数和返回值中,当函数需要接受或返回不同类型的数据时,可以使用void指针作为参数或返回值类型。通过void*指针的转换,可以在函数内部将其转换为具体的类型指针,从而进行相关操作。
需要注意的是,使用void指针需要谨慎,因为它没有类型检查,容易导致类型不匹配的错误。在使用void指针时,应该确保转换为具体类型指针的正确性,以避免出现潜在的问题。
下面我们在VS2022里进行验证
int main()
{
int a = 0;
int* pi = &a;
char* pc = &a;
return 0;
}
我们用char来接受一个int型指针时候,编译器会产生警告,
如果我们用void型来接收,可以发现
int main()
{
int a = 10;
void* pa = &a;
void* pc = &a;
*pa = 10;
*pc = 0;
return 0;
}
void指针类型值可以进行接受,但是不能进行运算。 那我们void类型的指针有什么作用呢?
一般void*用在函数参数部分,用来接受不同类型的数据地址,这样的设计可以 实现泛型编程的效果,使得⼀个函数来处理多种类型的数据。随着我们学习的深入,我们会越来越理解指针。
2.结尾
摆烂好长时间了,再摆烂真废了,都怨被窝,谁叫镇暖和里。睡醒开始不摆烂了,一天两更,加油