int main()
{
int i, c;
i:
for (i = 0; i < 3; i++) {
c = i &&&& i;
printf("%d\n", c);
}
return 0;
}
Вывод вышеуказанной программы составлен с использованием gcc
является
0
1
1
Как оценивается c в вышеуказанной программе?
Использование меток в качестве значений является gcc
расширение (см. Вот). Ваш сегмент выражения:
c = i &&&& i;
приравнивается к:
с = я && (&&я);
где &&i
это адрес этикетки i
,
Имейте в виду, что вы объединяете два совершенно разных i
«объекты» здесь. Во-первых, это i
переменная, которая циклически 0, 1, 2
в то время как вторая метка i
, для которого адрес всегда какое-то ненулевое значение.
Это означает, что результат, помещенный в C, будет 0
(ложно) только когда переменная i
является 0
, Вот почему вы получаете 0, 1, 1
последовательность.
Кроме того, я серьезно подумываю о «практике управления сотрудниками», если один из моих миньонов купил мне такой код для производственного использования. Все, что устраняет возможность таких чудовищ, было бы хорошей вещью, на мой взгляд 🙂
В этом случае это также анализируется как &&
а также &&
,
Первый logical AND
но второе &&
это адрес этикетки i
не адрес переменной i
, (это расширение GCC)
Это будет проанализировано как c = (i) && (&&i)
; // скобка просто для того, чтобы сделать ее читабельной.
&
дает вам адрес переменной i
, Который вы только что задали несколько минут назад в этом вопросе.
Подробнее об адресе метки и значениях увидеть это расширение gcc.
РЕДАКТИРОВАТЬ : поскольку &&
Логическое И всегда следует за коротким замыканием утверждения. Поэтому в первом случае это будет 0
так как он нашел i=0
так что не пойдет &&i
(вторая часть логического выражения).
Но во всех последующих случаях i
не является 0
так что даст TRUE
и перейдем к следующему выражению &&i
который является адресом этикетки i
(И адрес i
всегда буду оценивать TRUE
.)
Таким образом, результат полного выражения всегда будет TRUE
средства 1
кроме первого случая, когда i
является 0
, Следовательно, вы видите результат
0
1
1