任何人都可以解释和追踪这个,因为我的老师不能

Bob*_*j-C 1 c linux trace operating-system

考试中的问题是:

写下面程序的输出:

int i = 2 ;
int main () {

    int j = 10, p ;
    while (i-- && p == fork())
        if ( p < 0 ) exit(1);
    j += 2;
    if (p == 0) {
        i *= 3;
        j *= 3;
    }
    else {
        i *= 2;
        j *= 2;
    }

    printf("i = %d, j = %d \n",i,j);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用xcode从控制台输出包括以下行int i = 2;:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
Run Code Online (Sandbox Code Playgroud)

输出:

i = 3, j = 36 
i = 0, j = 36 
i = -3, j = 36 
Run Code Online (Sandbox Code Playgroud)

注意:我注意到如果我们使用Ubuntu,输出会有所不同.

我认为这是Ubuntu的输出:

i = 2 , j = 24
i = 2 , j = 24
Run Code Online (Sandbox Code Playgroud)

任何简短的解释或追踪都会很棒谢谢

sha*_*oth 10

p没有初始化,从未改变过.

int j = 10, p;  //uninitialized
while (i-- && p == fork()) //comparison - no changes
if ( p < 0 ) exit(1); //comparison - no changes
if (p == 0) { //comparison - no changes
Run Code Online (Sandbox Code Playgroud)

所以p碰巧存储内存中的任何值以及编译器为未初始化的变量分配的内容.

  • @ Bobj-C:输出只是随意的.访问未初始化的变量如"p"是未定义的行为,所以不要指望任何一致.通常你所看到的'p`的值只是随机数据,因为它留在那个位置.BTW一个体面的编译器应该告诉你`p`没有被初始化.您的老师至少应该在教学平台上告诉您编译器的相应警告选项. (3认同)

jke*_*ian 5

假设这是一个错字,并且while (i-- && p == fork())确实是while (i-- && (p = fork())),那么输出取决于OS调度程序.

主要流程用于分离流程

  • i = 1 p = 0 < - 处理A,parent.p = A.
  • i = 0 p = 0 < - 过程B,parent.p = B.
  • i = -1 p = B < - 父进程,parent.p = B.

进程A和B不会继续循环,因为它们的p=fork()计算结果为false.

每个进程将2添加到j(也可能是j = 12).综上所述:

A: i=+1 p=0    j=12
B: i= 0 p=0    j=12
P: i=-1 p=*B*  j=12
Run Code Online (Sandbox Code Playgroud)

在p = 0的情况下,i和j乘以3,p!= 0的那些(父进程)将它们乘以2.这为我提供了以下完全合理的输出:

i = -2, j = 24
i = 3, j = 36
i = 0, j = 36
Run Code Online (Sandbox Code Playgroud)

(订单会有点随机)

正如尖锐的指出,你编写的代码只是产生随机结果,取决于一块未初始化的内存.