为何取地址运算符&在scanf函数中能够正常工作?
为什么scanf中使用&var是可行的?
首先得明确你混淆了两个关键概念:指针变量和地址常量,这是问题的核心。
先看你的代码:
int a = 5; int *ptr_a = &a;
ptr_a是一个指针变量:它本身是一个变量,存储的是a的内存地址。你给它赋值ptr_a = 6,本质是修改这个变量里存储的地址值,让它指向地址为6的内存(这通常是无效地址,会导致崩溃或未定义行为)。&a是一个地址常量:它就是a所在内存的地址本身,是固定不变的,你根本不能给它赋值(比如写&a = 6会直接编译报错)。
接下来看scanf的工作逻辑:scanf的第二个及后续参数要求传入变量的内存地址,因为它需要通过这个地址找到对应的内存空间,把用户输入的值写入进去。你写scanf("%d", &a)时,并不是给&a赋值,而是把a的地址传递给scanf,scanf内部会对这个地址进行解引用操作(相当于*(&a) = 输入值),最终修改的是a的值,而非&a本身。
再对比你混淆的两种操作:
ptr_a = 6:修改的是指针变量ptr_a自身存储的地址,和a的值无关。scanf("%d", &a):传递a的地址给scanf,让它通过地址修改a的值,和地址本身无关。
如果用ptr_a代替&a传给scanf也是可行的,比如:
scanf("%d", ptr_a);
这时候ptr_a存储的是a的地址,传给scanf后,效果和传&a完全一样——scanf通过这个地址修改a的值。但如果你写scanf("%d", &ptr_a),那就是另一回事了,这会让scanf修改ptr_a本身存储的地址,就像你之前写的ptr_a = 6一样,大概率会出问题。
总结一下:你错误地认为scanf是在给&a赋值,但实际上它是通过&a这个地址去修改a的值,这和修改指针变量的地址是完全不同的操作。
内容的提问来源于stack exchange,提问作者Terra Green
相关产品推荐
相关产品推荐

