一个常量被赋值给另一个常量而没有错误

A constant being assigned to another constant without errors

我目前正在学习指针和按值传递的概念,我有这个 C 代码块:

void doSomething(int b){
    b = 6;
    printf("%d", b);
}
    
int a = 5;

int main(void){
    doSomething(a);
    printf("%d",a);
    return 0;
}

我应该得到输出 65,编译和执行都没有错误。通过跟踪代码,我是这样看的:

现在 运行 行 b = 6; 之前,我相当确定 b == 5。所以通过 运行 行,程序有效地读取:

5 = 6;

一个常量(我找不到更好的术语)被分配给另一个常量。在 Python 中,这将因语法错误而失败,并且出现错误是有道理的。为什么它不引发语法错误?

如果您查看调试器,您会发现这里有两个变量在起作用,a 在您的代码中是全局范围的,b 是对于 doSomething() 函数是局部的。

这是两个完全独立的变量。当您调用 doSomething() 函数时,假设发生以下情况:

stack_push(a);
call(doSomething);

编译器在 doSomething() 内部执行类似的操作:

int b = stack_pop();
...

“副本”就是这样制作的。

Note that this model for thinking about variables is an approximation and an optimizing compiler may do something completely different so long as the same result is achieved, as per the C spec.

5 = 6;b = 6;

不同

b = 6; 将值 6 分配给变量 bb 具有自动存储,这是另一回事

5 = 6; 不是 C 中的有效表达式,您误解了认为两者相同的概念。
运行下面的程序看到一个错误:

void doSomething(int b){
    b = 6;
    5 = 6;
    printf("%d", b);
}
    
int a = 5;

int main(void){
    doSomething(a);
    printf("%d",a);
    return 0;
}

现在你会得到第 3 行的错误:

error: lvalue required as left operand of assignment
5 = 6;

参考lvalues and rvalues

我决定将 5 = 6; 放在 main() 中。它产生了一个类似于 Python 中的编译错误,Johnny Mopp 和 Martin James 的评论现在变得有意义了。

b 确实是一个变量而不是实际常数。我的印象是按值传递只是传递变量包含的内容,而忽略了 b 是一个变量的想法,认为该函数只允许整数并且 b 只是一个占位符,不同于变量。

我的印象是 b 完全是 5,而不是 分配给 的变量值 5.

我目前在脑海中看到的是:

  • 整数 a 被赋值为 5
  • 由于 C 严格按值传递,doSomething(a) == doSomething(5).
  • b 在调用 doSomething(5).
  • 时被赋予值 5
  • b 根据行 b = 6;.
  • 分配值 6
  • ...等等。

谢谢大家的评论和回答!

以下是 C 2018 标准所说的函数调用在 6.5.2.2 4 中的执行方式:

In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument…

这意味着,在 void doSomething(int b) 的函数定义中,b 被定义为一个变量(技术上是一个对象),并且,当函数被调用时doSomething(a)doSomething(5)a5 的值被赋值给 b,就像您将 b = ab = 5 赋值一样.这只是一项任务;它不会在 ba5.

之间建立任何持久的联系

函数内部,b是一个变量,当然可以执行赋值b = 6。这只是将 6 分配给变量 b.

这里详细介绍参数如何成为自己的变量。 3.16定义参数为:

… object declared as part of a function declaration or definition that acquires a value on entry to the function,…

6.9.1 9 说:

Each parameter has automatic storage duration; its identifier is an lvalue…