
❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、C/C++干货分享&学习过程记录
🍉学习方向:C/C++方向
⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平
C++的两个参考文档:
老朋友(非官方文档):cplusplus
官方文档(同步更新):cppreference

目录
一、指针解引用的本质
指针解引用(*操作)实际上是通过地址访问内存的过程。每次解引用都相当于一次"寻址-取值"操作。记住这个核心原则:
解引用前必须确保指针指向有效的内存区域

大厂常见坑点案例
这里我们以腾讯2023面试题为例:
int *p = NULL;
*p = 10;
问:会发生什么?
答案:触发段错误(Segmentation Fault),因为试图访问0地址的内存。
实际工程项目中指针解引用的正确用法:
int value = 100;
int *p = &value; // 先让指针指向有效地址
printf("%d", *p); // 安全解引用
二、二级指针的实战理解

二级指针就是“指向指针的指针”,在以下场景特别有用——
1、需要修改指针本身时;
2、处理指针数组时;
3、动态分配二维数组时。
这里展示一个阿里巴巴高频面试案例:
void allocate_memory(char **ptr, int size)
{
*ptr = (char*)malloc(size); // 通过二级指针修改外部指针
}
int main()
{
char *str = NULL;
allocate_memory(&str, 100); // 传入指针的地址
strcpy(str, "Alibaba");
free(str);
}
二级指针与二维数组

下面这个字节跳动2024年的一道笔试真题:
int arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int (*p)[4] = arr; // 数组指针
int **pp = (int**)arr; // 这种转换是否正确?
printf("%d", arr[1][2]); // 正确
printf("%d", *(*(arr+1)+2)); // 正确
printf("%d", pp[1][2]); // 可能崩溃!
关键点:注意二维数组不是二级指针!它们的内存布局完全不同。
三、指针解引用案例

1、结构体指针解引用
下面这道题是美团的一个真实工程案例:
typedef struct
{
int id;
char name[20];
} Employee;
Employee e = {1001, "张三"};
Employee *p = &e;
// 两种访问方式对比
printf("%s", (*p).name); // 传统方式
printf("%s", p->name); // 更推荐的箭头语法
2、指针解引用与类型转换
下面这道是华为安全部门的一道考题:
float f = 3.14;
int *p = (int*)&f;
printf("%d", *p); // 输出什么?
答案:输出浮点数的二进制表示(IEEE 754编码)的整数值。
四、二级指针经典应用

1、动态字符串数组
下面是腾讯云面试实战的一道题:
char **create_string_array(int count)
{
char **arr = (char**)malloc(count * sizeof(char*));
for(int i=0; i<count; i++)
{
arr[i] = (char*)malloc(50 * sizeof(char));
sprintf(arr[i], "String%d", i+1);
}
return arr;
}
// 释放时也要二级指针操作
void free_string_array(char **arr, int count)
{
for(int i=0; i<count; i++)
{
free(arr[i]);
}
free(arr);
}
2、修改外部指针
下面是百度搜索部门的考题:
void change_pointer(int **pptr)
{
static int value = 100;
*pptr = &value; // 修改外部指针的指向
}
int main()
{
int *ptr = NULL;
change_pointer(&ptr);
printf("%d", *ptr); // 输出100
}
五、指针操作技巧掌握要领
1、指针偏移解引用
下面是拼多多2023年的一道笔试题:
int arr[] = {10,20,30,40,50};
int *p = arr;
printf("%d", *(p + 2)); // 30
printf("%d", p[2]); // 30 (等价写法)
printf("%d", 2[p]); // 30 (这种写法也是合法的!)
2、多级解引用
下面是阿里“双11”的一道压测题:
int value = 999;
int *p1 = &value;
int **p2 = &p1;
int ***p3 = &p2;
printf("%d", ***p3); // 999
// 解析过程:
// 1. *p3得到p2
// 2. *p2得到p1
// 3. *p1得到value
六、常见错误及排查方法
1、悬垂指针问题:
int *create_int()
{
int x = 10;
return &x; // 返回局部变量地址!
} // 函数结束后x的内存被回收
// 正确做法:使用static或动态分配
2、指针运算错误:
char str[] = "hello";
int *p = (int*)str;
p++; // 移动了4字节!可能破坏字符串结构
3、解引用未初始化指针:
int *p; // 未初始化
*p = 10; // 随机写入内存,是非常危险的!
七、性能优化
1、减少不必要的解引用操作:
// 不好的写法
for(int i=0; i<100; i++)
{
sum += *ptr;
ptr++;
}
下面就是优化之后的写法——
// 优化写法
int temp = *ptr;
for(int i=0; i<100; i++)
{
sum += temp;
temp = *(++ptr);
}
2、使用restrict关键字(C99):
void copy_array(int *restrict dest, int *restrict src, int n)
{
// 告诉编译器两个指针不会重叠
for(int i=0; i<n; i++)
{
dest[i] = src[i];
}
}
往期回顾:
详解C语言指针(上):(含大厂面试实战哦!)指针运算、指针和数组、多级函数
结语:本期内容到这里就结束了,希望对大家有帮助!
:指针解引用,二级指针(结合近些年笔面试的实际例子)&spm=1001.2101.3001.5002&articleId=150221661&d=1&t=3&u=24a54ed2d615475ea5eb412079d80f02)
1505

被折叠的 条评论
为什么被折叠?



