C语言中ptr与*ptr的概念差异及代码指针部分解析
C语言中ptr与ptr的概念差异、(void)作用及内存表现疑问解答
一、ptr 和 *ptr 的核心概念差异
- ptr:是指针变量本身,存的是另一个变量的内存地址。它的大小由系统架构决定——32位系统占4字节,64位占8字节,本质就是个用来存地址的数值。
- *ptr:是指针的解引用操作,意思是访问ptr指向的内存地址里存的内容。它的类型和大小完全由指针指向的变量类型决定,比如ptr指向int变量,*ptr就是int类型,多数系统下占4字节。
举个直观例子:
int num = 10; int *ptr = #
这里ptr存的是num的内存地址(比如0x7ffeefbff5ac),而*ptr就是num的值10。
二、(void*) 的作用解析
(void*)是C语言里的无类型指针,常见使用场景的作用如下:
- 通用指针容器:可以指向任意类型的变量,是实现通用函数的基础。比如内存操作函数
memcpy、malloc,用void*作为参数或返回值,就能适配所有数据类型的指针。 - 跨类型转换的中间层:强制转成void*后,编译器会暂时跳过指针类型的严格检查,方便不同类型指针之间转换。但要注意:使用时必须转回到原类型才能解引用,不然会触发编译错误或未定义行为。
- 适配特定函数接口:比如多线程函数
pthread_create的参数只能是void类型,这时候就需要把其他类型的指针转成void传递,在线程函数内部再转回来使用。
三、为什么ptr和*ptr的内存表现看似相同?
这种情况大多是特殊场景下的巧合,常见两种情况:
- 指针指向自身地址
比如写这样的代码:
int *ptr; ptr = (int*)&ptr; // 让ptr指向自己的内存地址
此时ptr存的是自己的地址,*ptr解引用后拿到的内容就是ptr本身的值(也就是这个地址),打印出来的数值完全一样,但逻辑天差地别:ptr是指针变量的地址值,*ptr是从该地址里读出来的内容(刚好等于ptr的值)。
2. 结构体起始地址与第一个成员地址重合
比如:
struct Test { int val; char c; }; struct Test t; int *ptr = &t.val;
结构体第一个成员的地址就是结构体的起始地址,所以ptr的值等于&t。如果打印ptr和强转后解引用的*(struct Test*)ptr,数值会有重叠,但这是内存布局的巧合,不是ptr和*ptr本身等价。
还有一种可能是打印格式的问题:用%p打印ptr(地址),用%d打印ptr(假设是int类型),如果地址的数值刚好和ptr的数值一致,也会看起来相同,但这纯粹是巧合。
内容的提问来源于stack exchange,提问作者realwixi
相关产品推荐
相关产品推荐

