“指针是 C 语言的灵魂,也是初学者的噩梦。”
你是不是也曾在*、&、->中迷失方向?别担心!今天通过4 个亲手敲过的强化练习,带你一步步揭开指针的神秘面纱——不仅看懂,还能用它高效操作内存!
练习一:用指针交换两个数
问题:为什么下面的代码不能交换a和b?
void swap(int a, int b) { ... }答案:因为传的是值的副本!函数内部修改的是副本,不影响原变量。
✅ 正确做法:传地址!
void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }👉关键理解:
*a不是“a 的值”,而是“a 所指向位置的值”。通过地址,我们直接修改了主函数中的变量!
💡 小提醒:C 语言没有“引用”,
int &a是 C++ 特性哦!
练习二:指针遍历数组求和
在 C 语言中,数组名就是首元素的地址!
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int *p = arr; // p 指向 arr[0] int sum = 0; for (int i = 0; i < 10; i++) { sum += *p; p++; // 指针自动跳到下一个 int! }👉神奇之处:
p++不是加 1 字节,而是加sizeof(int)字节!这就是指针算术(Pointer Arithmetic)的力量。
📌 补充:
*(p + i)等价于p[i],甚至i[p]在语法上也合法(虽然不推荐 😅)。
练习三:双指针原地反转字符串
想把"Hello World"变成"dlroW olleH"?不用新数组!
void reverse_str(char *str) { char *left = str; char *right = str + strlen(str) - 1; // 跳过 '\0' while (left < right) { char tmp = *left; *left = *right; *right = tmp; left++; right--; } }👉双指针技巧:
一个从头,一个从尾,边走边换,直到相遇。
**空间复杂度 O(1)**,效率拉满!
⚠️ 注意:必须用
char str[] = "Hello World";定义可修改的字符数组。
如果直接传字符串字面量(如reverse_str("abc")),程序可能崩溃(因为字面量在只读内存区)!
练习四:返回最大值的地址,并修改它!
函数不仅能返回值,还能返回地址!
int *find_max(int *arr, int len) { int *max_p = arr; // 假设第一个最大 for (int i = 1; i < len; i++) { if (*(arr + i) > *max_p) max_p = arr + i; } return max_p; // 返回最大值的地址! }调用后:
int arr[] = {1, 2, ..., 10}; int *p = find_max(arr, 10); printf("最大值:%d\n", *p); *p = 999; // 直接修改原数组! printf("修改后:%d\n", *p);👉指针的终极威力:
拿到地址,就拥有了对那块内存的读写权!
但切记:不要返回局部变量的地址(会变成悬空指针)!
总结:指针到底是什么?
| 概念 | 说明 |
|---|---|
int *p; | p 是一个指针,存储某个int变量的地址 |
&a | 取变量 a 的地址 |
*p | 解引用:访问 p 所指向的内存中的值 |
p++ | 指针移动到下一个同类型元素(不是 +1 字节!) |
✅ 指针让 C 语言既灵活又高效,但也要求你对自己写的每一行负责!
互动时间 🎯
你第一次学指针时卡在哪一步?
是*和&分不清?还是怕“野指针”?
欢迎在评论区分享你的“指针故事”!
如果你觉得这 4 个练习有帮助,别忘了点赞 + 转发给正在学 C 的朋友!