Насколько я понимаю, печать будет выполняться, только если a = 0 или b = 0
Это назад. Печать произойдет, когда одно из выражений по обе стороны от ||
будет ненулевым . Также кажется, что вы также можете не знать, что выражение в правой части ||
вычисляется только в том случае, если выражение в левой части равно нулю; это называется оценка короткого замыкания . (Аналогично, правая часть &&
оценивается только в том случае, если левая сторона отлична от нуля.)
При условии, что ни один вызов fork
не завершится неудачей, существует только три ветви выполнения, потому что каждый процесс вызывает fork
не более одного раза. printf
вызывается дважды.
оригинальный процесс: a=fork()
устанавливает a
в ненулевое значение
- левая сторона
||
не равна нулю, поэтому правая сторона не оценивается
printf
вызывается с a
ненулевым и b
неинициализированным
дочерний процесс: a=fork()
устанавливает a
в ноль
- левая сторона
||
равна нулю, поэтому правая сторона оценивается
b=fork()
устанавливает b
в ненулевое значение
- правая сторона
||
отлична от нуля
printf
вызывается с a
нулем и b
ненулевым
процесс внука: b=fork()
устанавливает b
на ноль
- левая и правая части
||
равны нулю
- printf не называется
Вывод дочернего и исходного процессов может отображаться в любом возможном порядке. Поскольку printf
вызывается только после , каждый процесс выполняет вызовы fork
, не нужно беспокоиться о дублированном буферизованном выводе.
Из-за "короткого замыкания" поведения ||
и порядка вычисления (x=fork())
вы никогда не сравниваете неинициализированное значение с нулем, но вы передаете неинициализированное значение printf
в одной ветви выполнение. Это ошибка. Вы должны инициализировать оба a
и b
в ноль, когда они объявлены, для удобства чтения. Кроме того, их тип должен быть pid_t
(и вы должны включить unistd.h
, а также stdio.h
).
Кстати, каждый раз, когда вы ставите пробелы внутри скобок или слева от запятой, Бог убивает котенка. Пожалуйста, подумайте о котятах.
Кстати, если у вас fork
, вы работаете в Unix, которая не поддерживает объявление main
с типом возврата void
. Вы должны написать int main(void)
вместо этого. Вы также должны завершить тело main с помощью return 0;
, это технически необязательно в C99 и более поздних версиях, но существует огромное количество компиляторов, которые по умолчанию используют C89, и в любом случае я думаю, что полагаться на неявное возвращение 0 - плохой стиль. .
EDIT , поскольку я вижу, что вы решили эту проблему, изменив код для объявления main()
без какого-либо возвращаемого типа: это технически объявляет, что он возвращает int
, но полагается на устаревшую функцию называется "неявный int". В наши дни это считается вопиюще плохим стилем. Некоторые люди даже скажут вам, что «implicit int» был удален из языка, что верно, если вы идете по букве стандарта, но false, если вы придерживаетесь того, что на самом деле принимают компиляторы. Также неправильно ставить ничего в скобках аргумента; в C это не объявляет функцию, которая не принимает аргументов, она объявляет функцию, которая принимает неопределенное число аргументов. (Опять же, если перейти к букве стандарта, функция определение с пустыми круглыми скобками аргументов объявляет, что она не принимает аргументов, но это не тот случай, когда компиляторы фактически принимают.)