目录
一、取地址操作符(&)
二、解引用操作符(*)
三、指针变量
1、 指针变量的大小
2、 指针变量类型的意义
2.1 指针的解引用
2.2 指针 +- 整数
2.3 调试解决疑惑
认识指针,指针比较害羞内敛,我们需要通过他的好朋友们认识他
一、取地址操作符(&)
//VS2022 x86
#include <stdio.h>
int main()
{
int i = 1314;
int* p = &i; // & 取地址操作符;将 i 里的地址取出来放到 p 里
//int* 表示p是整型指针变量,指针是用来存放地址的
printf("%p\n", p);
printf("%p\n", &i);
return 0;
}
把平台换成 x86 好观察(x64也可以,只是长一些,为了这篇文章后面统一都是x86平台)
运行后可以看到之这一长串数字加字母,不用管他,知道这是地址就行,可以看出:
指针p 里存放的地址和从 变量i 中取出来的地址是一样的;每次编译地址都会变,但 p == &i 。
二、解引用操作符(*)
#include <stdio.h>
int main()
{
int i = 1314;
int* p = &i;
printf("%d\n", i);
*p = 20; // * 解引用操作符
printf("%d\n", i);
return 0;
}
可以看到 变量i 的值被改变了,这是因为 *p 的意思是将 p 里存放的地址通过解引用从而找到 变量i,然后赋值20;
可以这么理解,i 是一个宝藏,p 就是这个宝藏所在坐标,然后你通过正确的解读宝藏在地图上的位置(*)最终找到了宝藏,随后把它挖走并往里面放了个石头埋起来戏耍后面的人,i 就变成了石头。
三、指针变量
前面通过对他朋友的认识,顺便知道了指针变量是用来存放地址的,那这里我们需要了解他的特点
1、 指针变量的大小
#include <stdio.h>
int main()
{
printf("%zd\n", sizeof(char *));
printf("%zd\n", sizeof(short *));
printf("%zd\n", sizeof(int *));
printf("%zd\n", sizeof(double *));
return 0;
结论:
- 32位平台下地址是32个bit位,指针变量大小是4个字节;
- 64位平台下地址是64个bit位,指针变量大小是8个字节;
- 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。
不管给他任何修饰词(int*、char*),在我们面前(32位平台)就是腼腆得很,在朋友面前(64位平台)就是开放得很,所以和他交上朋友才能更了解他嘿嘿。
那就疑惑了,变量规定类型是因为有字节大小区分,指针变量大小在不同类型下字节大小都一样,那为什么要规定指针变量的类型呢?
2、 指针变量类型的意义
2.1 指针的解引用
通过代码就能很清楚的看出来啦,好好看好好学
#include <stdio.h>
int main()
{
int n = 0x11223344; //十六进制,两个数字代表一个字节
char* p = (char*) &n; //不强转会报警告
*p = 0;
printf("%x", n); //%x 打印十六进制整数
return 0;
}
#include <stdio.h>
int main()
{
int n = 0x11223344; //十六进制,一个数字代表一个字节
int* p = &n;
*p = 0;
printf("%x", n);
return 0;
}
可以看到,int* p 会将n的4个字节全部改为0,但是 char* p 只是将n的第⼀个字节改为0。
结论:指针的类型决定了,对指针解引用的时候有多大的权限(一次能操作几个字节)。
2.2 指针 +- 整数
#include <stdio.h>
int main()
{
int n = 10;
printf("%p\n", &n);
printf("=================\n");
char* pc = (char*)&n;
printf("%p\n", pc);
printf("%p\n", pc + 1);
printf("=================\n");
int* pi = &n;
printf("%p\n", pi);
printf("%p\n", pi + 1);
return 0;
}
我们可以看出, char* 类型的指针变量 +1 跳过 1个字节, int* 类型的指针变量 +1 跳过了 4个字节。 这就是指针变量的类型差异带来的变化。指针 +1 ,其实跳过1个指针指向的元素。指针可以+1,那也可以-1。
结论:指针的类型决定了指针向前或者向后走一步有多大(距离)。
2.3 调试解决疑惑
诶不对哇,3.2中 cha* p 怎么改第一个字节把0x11223344的44改了,不应该是改11吗,来,跟我调试起来
(1)
(2)Ctrl+Fn+F10(或者Ctrl+F10)进入调试
(3)
(4)
(5)注意左边的箭头,Fn+F10 箭头会指向下一条语句,下到图片位置
看到了吧,内存中的0x11223344是倒着存进内存里的,所以第一个字节是44,继续按Fn+F10就可以看到 44 变为 00。
完