一.什么是指针?
1.1概念
指针是一种编程语言中的变量,其值为另一个变量的内存地址。通过指针可以直接访问或操作该内存地址中存储的数据,可以理解为指针就是地址。
看下边一串代码
int a = 10;
int *p = &a; // p存储变量a的地址
1.2解析
1.int* p表示声明一个指针变量p,存储a这个变量的指针
2.* 为解引用操作符(也可以叫间接访问操作符),说明了p为指针变量
3.& 取地址操作符,用于获取变量在内存中的地址,&a表示取出a的地址,
注意:取地址操作符只能用于左值(如变量、数组元素等),不能用于常量或表达式(如&3或&(a+b))
4.int 说明p指向的变量类型是int
二.指针变量
2.1概念
指针变量是一种特殊类型的变量,用于存储内存地址,它指向内存中的某个位置,可以通过该地址访问或修改存储在该位置的数据。
指针变量归根结底还是变量,这种变量是用来存放地址的。
2.2指针变量与解引用操作符
解引用操作符(*)用于访问指针所指向的内存地址中的值。通过解引用,可以读取或修改指针指向的变量内容。
看下边代码
int y = *ptr; // y的值为10(读取ptr指向的值)
*ptr = 20; // 修改ptr指向的变量x的值为20
*后面跟一个指针名或地址,就表示存在ptr指向那个地址的值,这里表示将20赋给ptr
2.3小结
指针变量存放地址,解引用操作符通过地址访问数据
2.4注意
1.未初始化的指针解引用会导致未定义行为
2.解引用空指针(NULL或nullptr)是非法操作
三.指针运算
3.1指针的加减
指针加减整数时,地址的实际偏移量由指针类型决定。
1.指针 + 整数:
看下边代码
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // 指向arr[0]
ptr = ptr + 3; // 现在指向arr[3],地址实际增加3*sizeof(int)
解析:int*指针加3,实际地址增加sizeof(int)字节,由于ptr为int类型的指针,所以ptr + 1跳过4个字节
那ptr + 3跳过12个字节。
如果ptr为char类型的指针,ptr + 1跳过一个字节。
2.指针 - 指针
看下边代码
int *ptr1 = &arr[1];
int *ptr2 = &arr[4];
ptrdiff_t diff = ptr2 - ptr1; // 结果为3
同类型指针相减得到的是元素间隔数,而非字节差
3.2 .指针的比较
指针主要比较地址的高低(详情参考汇编语言)
指针1 > 指针2,表示指针1指向的存储地址大于2指向的地址。
指针1 == 指针2,表示指针1和2在同一个存储单元。
指针1 == 0,表示是空指针。
四.野指针
4.1概念
野指针是指指向已释放或无效内存的指针。这些指针未被置空,仍保留原先的地址,但该地址可能已被系统重新分配或回收
4.2成因
1.指针未初始化,声明后未赋值,其值随机指向内存中的某个地址。
2.内存释放,指针被释放,第二次操作为野指针。
3,超出作用域,指向局部变量的指针在函数返回后变为野指针。
4.3避免方法
1.初始化指针
声明指针时立即初始化为NULL或合法地址
2.释放后置空
看下边代码
free(p);
p = NULL; // C
delete q;
q = nullptr; // C++
调用free或delete后,指针设置为NULL或nullptr。
五.指针与数组
5.1 指针数组
首先要明确,指针数组是数组,这个数组用来存放指针
-数组名的理解
数组名为数组首元素地址,不过有两个例外
1.sizeof(数组名)这里朱祖明表示整个数组
2.&数组名,这里数组名表示整个数组,取出是整个数组地址
除此之外,声明数组时,数组名在表达式中通常退化为指针:
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // arr退化为&arr[0]
定义:
指针数组是由指针变量构成的数组,每个元素都是一个指针,可以指向相同或不同类型的数据。其声明形式为 type *array_name[size],其中 type 为指针指向的数据类型,size 为数组大小。
静态初始化实例:
int a = 1, b = 2, c = 3;
int *ptr_array[3] = {&a, &b, &c}; // 每个元素指向一个整型变量
动态初始化示例:
char *str_array[3];
str_array[0] = malloc(10 * sizeof(char));
strcpy(str_array[0], "Hello");
5.2指针算术与数组访问
for (int i = 0; i < 5; i++) {
printf("%d ", *(ptr + i)); // 等价于ptr[i]
}
ptr[i]本质是*(ptr + i)的语法糖,编译器自动计算偏移量。
5.3多维数组与指针
int matrix[3][4];
int (*p)[4] = matrix; // 指向包含4个int的数组的指针
访问元素时:
matrix[i][j] ≡ *(*(matrix + i) + j)
5.4指针数组与数组指针的区别
指针数组:本质是数组,元素为指针。例如 int *arr[5] 表示包含 5 个整型指针的数组。
数组指针:本质是指针,指向一个数组。例如 int (*arr)[5] 表示指向包含 5 个整型元素的数组的指针。
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2502_92932605/article/details/152774188



