既然我们在 if 中将 int 的值更改为 10,为什么在子项和它创建的子项的第二个分叉之后我都会打印 33?

Since we changed the value of int to 10 inside the if, why do i get 33 printed after the second fork for both child and the child it created?

提问人:Mike Balts 提问时间:9/14/2023 最后编辑:BarmarMike Balts 更新时间:9/28/2023 访问量:38

问:

代码如下:

int main(int argc, char *argv[ ]){
    int x = 33;
    if(!fork()){
        int x = 10;
        printf("%d\n", x);
    }
    fork();
    printf("%d\n", x);
    return 0;
}

我假设因为原始子项的 int 值发生了变化,所以它带有 10 的值,并且在第二个 fork(fork();) 中也是如此,所以原始子项及其子项打印 10,因此输出如下所示: 33 33 10 10 10 但似乎虽然 int 的值在 if 中发生了变化,但子项随后又取回了 x 的原始值,即 33,并且在第二次分叉后都打印了 33(所以输出是这样的:33 33 10 33 33。为什么?(我相信\n与它没有任何关系)这是我认为正在发生的事情的照片,但显然没有

c if 语句 变量 分叉

评论

0赞 BoP 9/14/2023
的值不会改变,你只是有两个同名的不同变量。试着打电话给他们。xy
0赞 Barmar 9/14/2023
或者改为 .然后它分配相同的变量。int x = 10;x = 10;

答:

1赞 chqrlie 9/14/2023 #1

在块内的第一个中打印的局部范围定义,该范围以 .第二个使用在仍具有初始值的正文范围内定义的。xprintfif}printfxmain33

在局部作用域中重新定义与封闭作用域中定义的变量同名的变量称为重影。它令人困惑且容易出错,如果使用 或 启用高级编译器警告,则会报告警告。-Wall -Wextra-Weverything

下面是一个修改后的版本,它应该产生更接近您预期的输出:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int x = 33;
    if (!fork()) {
        x = 10;
        printf("%d\n", x);
    }
    fork();
    printf("%d\n", x);
    return 0;
}

此版本应以不可预测的顺序打印两次和三次。3310

问题中发布的原始版本应以不可预测的顺序打印 4 次,并且只打印一次。3310

评论

0赞 Mike Balts 9/14/2023
谢谢。这是一个考试问题,不是我的程序。因此,一旦 if 结束,孩子就会回到原来的值 33,对吧?
0赞 chqrlie 9/14/2023
@MikeBalts:不是子项,则在块范围内定义的变量消失。第二个中使用的变量是不同的变量,在主体顶部定义为并且在任何过程中从未更改。xifxprintfmain()int x = 33;
0赞 chqrlie 9/14/2023
@0_____:它应该以不可预测的顺序打印两次和 4 次。3310
0赞 Mike Balts 9/14/2023
哦,所以 if 里面的 x 是另一个变量,为了混淆而具有相同的字符。明白了。所以这就像在 main 中有一个 x,然后在 if 中有一个 y,对吗?
1赞 Mike Balts 9/14/2023
你确实非常有帮助。
0赞 0___________ 9/14/2023 #2

在两个不同的作用域中定义两个 s。一个在内部,当程序退出该范围时,它就不再存在。xif

但它仍然只能打印:)33

int main(int argc, char *argv[ ])
{
  int x = 33;
  if(fork())
  {
     x = 10;
     printf("%d\n", x);
  }
  fork();
  printf("%d\n", x);
  return 0;
}

https://godbolt.org/z/PWvGcq5qM

我想你也想看到这个结果:)

评论

0赞 Chris Dodd 9/28/2023
Godbolt 限制了你调用 fork() 的能力(以防止 fork-bomb 扰乱/崩溃服务器)。但是,不确定导致该输出的确切策略是什么。