C语言中直接修改变量与通过指针解引用修改变量的区别?
直接变量赋值与指针解引用赋值的区别及适用场景
核心区别
x = 99是直接修改:代码编写阶段就明确指定了要修改的变量是x,编译时就固定绑定了x对应的内存地址,运行时只能修改x的值,没有灵活调整的空间。*px = 8是间接修改:修改的是px指针当前存储的地址指向的内存空间的值,具体修改哪个变量完全由px的指向决定,运行时可以通过修改px的指向动态调整修改对象,不需要修改赋值语句本身。
举个简单的例子,如果你在代码中加一行px = &y;,再执行*px = 8,此时修改的就是y的值,而不需要把赋值语句改成y = 8,这是直接赋值做不到的。
需要使用指针解引用修改值的常见场景
1. 函数内部需要修改外部实参的值
C语言默认参数传递是值传递,形参是实参的拷贝,直接修改形参不会影响外部实参,此时就需要传指针,在函数内部解引用修改外部实参的值。最典型的就是交换两个变量值的函数:
// 错误写法:修改的是形参a、b,不会影响外部传入的变量 void swap_wrong(int a, int b) { int temp = a; a = b; b = temp; } // 正确写法:通过指针解引用直接修改外部实参的内存 void swap_right(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 调用方式 int main() { int m = 1, n = 2; swap_right(&m, &n); // 调用后m=2,n=1 return 0; }
2. 操作堆内存
你通过malloc/calloc申请的堆内存没有对应的变量名,只会返回指向这块内存的指针,必须通过解引用才能读写这块内存的值:
int* p = (int*)malloc(sizeof(int)); *p = 100; // 只能通过解引用给堆内存赋值
3. 遍历、修改数组/字符串元素
数组名本质是首元素的地址,通过指针偏移+解引用的方式可以更灵活地操作数组元素,在处理长数组、字符串时非常常用:
char str[] = "hello"; char* p = str; *(p+1) = 'a'; // 等价于str[1] = 'a',修改后字符串变为"hallo"
4. 实现复杂数据结构
链表、二叉树、图等复杂数据结构的节点之间都是通过指针关联的,要修改关联节点的内容,只能通过解引用指针完成:
// 链表节点定义 typedef struct ListNode { int val; struct ListNode* next; } ListNode; // 修改当前节点的下一个节点的值 void modifyNextNodeVal(ListNode* cur, int newVal) { if (cur->next != NULL) { cur->next->val = newVal; // 本质就是解引用cur->next指针修改值 } }
你当前的测试代码里指针px固定指向x,所以两种修改方式效果一致,当你需要用到上面这些场景时,指针解引用的价值就会体现出来。
内容的提问来源于stack exchange,提问作者Hayato Koyama
相关产品推荐
相关产品推荐

