一、指针是什么?
计算机分为内存和外存,为了读取速度,运行中的程序都在内存中开辟空间,用于存储信息。
存储信息的地址,就可以简称为指针。
可以通过指针(地址),逆向找到对应的数据。
好比坐车买票,你可以通过班次找到对应的座位;
乘务员也可以通过座位找到你。
二、指针使用
通过元素类型* 指针变量名称 = 地址
来定义指针变量。
int num = 10;
int* p = NULL; // 定义数值指针变量
p = #
printf("%p \n %p", p, &num); // 两个值的地址相同
注意:不同类型的指针变量是不可以存储,需要强制类型转换才能存储。
指针变量存储的是内存中的地址,所以大小是根据计算机操作系统位数来决定的。
不管是字符指针,还是数值指针,大小都是相同的,都是存储数据在内存中的位置。
例如初始位置: 0地址
32位系统: 00000000 00000000 00000000 00000000
每8个比特为1字节。所以32位系统指针变量大小位4字节
64位系统同理: 00000000 00000000 ...
64位系统指针变量大小为8字节
根据上述规律,不管是16位系统,还是8位都可以算出指针变量的大小。
可以通过sizeof()来进行验证
指针类型
类型和定义变量类型相同
char* p;
short* p;
int* p;
long* p;
long long* p;
float* p;
double* p;
指针运算
指针运算只有加减法和比较大小。
指针 ± 整数
指针 ± 整数可以移动指针的位置,偏移量取决于指针类型。
int a = 10;
int* p = &a;
printf("%p\n%p", &a, p + 1);
数组名也是指针变量,同样可以使用这种方式
// 指针类型位int,大小为4,+1向后偏移4个字节
// 恰巧是数组下一个位置的值
int arr[] = { 1,2,3,4,5,6 };
for(int i = 0; i < 6; i++) {
printf("%d ", *(arr + i));
// 注意,指针+-整数后仍是地址,需要取出地址中的内容
// 前|后++也可以使指针进行偏移,但是会改变原来指针的位置
// 使用前需要保留原指针备份
}
指针 - 指针
通常用于确定数组中的元素个数
int arr[] = { 1,2,3,4,5,6 };
printf("%d", &arr[6] - &arr[0]); // 6
指针 - 指针需要同类型的指针变量
指针比较
比较两个指针的大小,毕竟是16进制数。
int arr[] = { 1,2,3,4,5,6 };
printf("%d", &arr[6] > &arr[0]); // 1
printf("%d", &arr[6] < &arr[0]); // 0
printf("%d", arr == &arr[0]); // 1
野指针
指向不明位置的指针。
// 未初始化
int* p; // 随机位置,没人知道p指向什么位置,野指针
// 越界访问
int arr[] = { 1,2,3 };
p = arr;
p += 4; // 向后移动4个整形的位置,但数组只有3个元素
*p; // 没人知道数组之后的地址有没有值存在
// 释放空间
int* tmp = (int*)malloc(8); // 创建两个整形字节的空间
free(tmp); // 释放创建的空间
// 释放空间后tmp虽然指向目标位置,但是值不存在了
总结
简单的说明什么是指针,指针有什么作用,下节会说明二维指针,指针数组等进阶知识。
为什么关于指针的问题都那么绕啊