【C语言】深入解开指针(一)1:https://developer.aliyun.com/article/1474257
2.2.2 解引⽤操作符
解引用运算符( * )
将指针变量所指向的对象的值赋给左值变量。当使用指针变量时,使用解引用运算符来访问指针变量所指向的对象。
#include <stdio.h> int main() { int a = 100; int* pa = &a; *pa = 0; printf("%d", a); return 0; }
*pa
的意思就是通过pa中存放的地址,找到指向的空间,
*pa
其实就是a变量了;所以*pa = 0
,这个操作符是把a
改成了0
#include <stdio.h> int main() { int num1 = 10; int *ptr1 = &num1; printf("The value of num1 is %d\n", num1); printf("The address of num1 is %d\n", &num1); printf("The value of ptr1 is %d\n", ptr1); printf("The value of *ptr1 is %d\n", *ptr1); return 0; }
变量 num1 的值为 10,因为它被赋值为 10。
变量 num1 的地址为 13629256,因为它在内存中的位置是 13629256。
变量 ptr1 的值为 13629256,因为它被赋值为 num1 的地址。
变量 *ptr1 的值为 10,因为它是 ptr1 所指向的对象的值。
2.3 指针变量的⼤⼩
指针变量的⼤⼩取决于地址的⼤⼩
• 32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。
32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。
#include <stdio.h> int main() { int* a = 10; short* b = 10; char* c = 10; double* d = 10; printf("%d\n", sizeof(a)); printf("%d\n", sizeof(b)); printf("%d\n", sizeof(c)); printf("%d\n", sizeof(d)); return 0; }
在debug X86也就是调试状态下的32位环境下:
在debug X64也就是调试状态下的64位环境下:
三、 指针变量类型的意义
当你看到这里,你发现指针变量的⼤⼩和类型⽆关,只要是指针变量,在同⼀个平台下,⼤⼩都是⼀样的, 那还要那么多的指针类型干嘛呢?统一归为一种指针类型不就好了,就没那么麻烦了,bug或许可能就没有那么多了!同学带着你的疑问,让我们一起走下去。看看为什么这么设计的?
3.1 指针的解引⽤
首先,我们观察两组代码的变化环境为debug x86
- 代码1:
#include <stdio.h> int main() { int n = 0x66778899; int* pk = &n; *pk = 0; return 0; }
- 代码2:
#include <stdio.h> int main() { int n = 0x66778899; char* pk = (char*)&n; *pk = 0; return 0; }
调试我们可以看到,代码1会将n的4个字节全部改为0,但是代码2只是将n的第⼀个字节改为0。
结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。
⽐如: char*
的指针解引⽤就只能访问⼀个字节,⽽ int*
的指针的解引⽤就能访问四个字节
3.2 指针+ - 整数
指针加减整数的语法如下:
ptr + n ptr - n • 1 • 2
其中,ptr 是
指针变量,n
是整数。
当我们向一个指针加减整数时,我们实际上是在向指针所指向的内存地址加减整数。这意味着,如果我们向一个指针加 1,则指针会指向内存中下一个字节的位置。如果我们向一个指针减 1,则指针会指向内存中上一个字节的位置。
以下是不同类型的指针加减整数的示例:
整数指针:
int *p = 0; p++; // 指向内存中下一个字节的位置 p--; // 指向内存中上一个字节的位置
指针数组:
int arr[] = {1, 2, 3, 4, 5}; int *p = arr;//int*类型加4 p++; // 指向内存中下一个元素的位置 p--; // 指向内存中上一个元素的位置
下是指针加减 1 的示例:
#include <stdio.h> int main() { int n = 10; char* pc = (char*)&n; int* pi = &n; int* arr[] = { 1,2,3,4,5 }; int* pk = arr; printf("%p\n", &n); printf("%p\n", pc); printf("%p\n", pc + 1); printf("%p\n", pi); printf("%p\n", pi + 1); printf("%p\n", pk); printf("%p\n", pk + 1); return 0; }
运行结果:
可以看到,
char类型的指针变量+1跳过1个字节,int类型的指针变量+1跳过了4个字节。这表明指针变量的类型差异会导致步长的变化。
结论:指针的类型决定了指针向前或向后移动一步的距离。
3.3 void* 指针
void
指针是 C 语言中一种特殊的指针,它可以指向任何类型的数据。void
指针的类型是 void
,它不指向任何特定的数据类型。
void* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算。
void 指针也可以用来解引用,但必须在解引用之前使用类型转换。void` 指针可以用来存储指向任何类型数据的指针。
#include <stdio.h> int main() { int a = 88; void* p=&a; int* q = (int*)p;//类型转换 printf("n = %d\n", *q); return 0; }
void* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算。