关注

[c语言]指针

一.什么是指针?

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++
 

调用freedelete后,指针设置为NULLnullptr

五.指针与数组

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

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--