C语言 既然我们在if中将int的值改为10,为什么在第二次fork之后,我得到了33,这两个子对象和它创建的子对象都是33?

jxct1oxe  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(87)

下面是代码:

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();),所以原始的子元素和它的子元素print 10,所以输出是这样的:33 33 10 10 10但是看起来,虽然int的值在if内部发生了变化,但是子进程随后得到了x的原始值,也就是33,并且在第二次分叉之后都打印了33(所以输出是这样的:33 33 10 33 33.为什么会这样?(我相信\n与此无关)here is a photo of what i think is happening but apparently it doesnt

oug3syen

oug3syen1#

if块内的第一个printf中打印的x定义了一个以}结束的局部作用域。第二个printf使用在main主体的作用域中定义的x,该主体仍然具有初始值33
在局部作用域中重新定义一个变量,并使其与封闭作用域中的变量同名,称为 * 隐藏 *。它容易混淆和出错,如果您使用-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;
}

此版本应该以不可预测的顺序打印33两次和10三次。
问题中发布的原始版本应该以不可预测的顺序打印33 4次和10仅一次。

zxlwwiss

zxlwwiss2#

在两个不同的作用域中定义两个x。一个在if内部,当程序退出该作用域时,它就停止存在。
但它仍然只会打印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
我想你也想看到这个结果:)

相关问题