2016-05-31 2 views
-2

Это вопрос из прошлого документа, с которым у меня возникают проблемы, вопрос и вывод отображаются ниже, но я не понимаю, как это достигается. Может кто-то объяснит.Объясните вывод этого цикла

int main() 
{ 
    int a[5] = { 1 }, b[] = { 3, -1, 2, 0, 4 }; 
    for (int i = 0; i<5; i++) 
    { 
     if (!(a[i] = b[i])) // note: = not == 
      break; 
     cout << a[i] << endl; 
    } 
} 

Выход:

3 
-1 
2 
+0

Когда 'b [i]' равно 0, тогда 'a [i] = b [i] 'также равно 0, а'! 0' истинно, поэтому тело оператора if выполняется. – immibis

+0

Какую часть вы не понимаете? –

+0

Я не понимаю, как я получаю вывод? – david98

ответ

0

Я думаю, что главное, что вам нужно знать, чтобы понять, что часть кода является то, что (a[i] = b[i]) будет оцениваться как любой, который присваивается a[i], поэтому разрыв будет аннулирована когда i равно 3, то есть когда b[i] равно 0. Это также поддерживается выведенным выводом.

3

Цикл работает в большинстве пять раз и каждый раз через петлю, он копирует b[i] к a[i](а). Если эта копия привела к тому, что нуль помещается в a[i], условие оператора if будет истинным, и цикл разобьется. Это потому, что результатом выражения x = y является окончательное значение x.

В вашем случае (a[i] = b[i]) будет нулевым или отличным от нуля в зависимости от b[i]. Если первый, ! превращает это в истинное значение, а тело if работает (происходит break). Если последнее, вы получаете false из !, и цикл продолжает работать.

Этот разрыв происходит с четвертым элементом, поэтому вы видите только три выходные линии.


(а) Вы должны знать, что это справедливо, так как размер b неявно пять (вы явно не установить размер, но он инициализируется с пятью элементами). Размер a также пять, потому что вы указали свой размер с a[5], несмотря на то, что вы только явно инициализировали первый элемент до 1 (остальные неявно инициализируются до нуля).

+0

Означает ли это, что вы можете вывести 'cout << x = (выражение) << endl;' и вывести значение выражения при присвоении ему 'x'? –

+0

@JoelTrauger: Почти. Я думаю, что в этом случае приоритет будет оценивать '(выражение) << endl' * first * и горько жалуется на попытку сдвига влево с помощью' endl'. Вы можете исправить этот приоритет, используя 'cout << (x = (выражение)) << endl;'. – paxdiablo

+0

Возможно, стоит отредактировать, чтобы объяснить OP, что 'int a [5] = {1}' инициализирует 'a', поскольку это является причиной раннего выхода, и не сразу видно непосвященному, что происходит с этим инициализатором скобок , – user4581301

0

Сначала вы должны понять отливку типа в C++, в основном 0 ложна при преобразовании в логический тип (Вы можете увидеть ссылку отсюда: c++ bool question)

Теперь программа делает очень простую вещь для каждой итерации в цикле:

Присвоить b[i] к a[i] и попытаться разыграть эту INT к булева типа (неявное преобразование), и посмотреть, если это правда, ложные, она печатает целое число, если это правда, разорвать петлю от herwise

Таким образом, вы можете понять, почему первые 3 целое число печатается, так как они назначаются a[i], будучи covnerted к булевой, и оказывается, что они стали истинным (да, -1 сбылось, а также , все не равное нулю целое число будет сбылось при преобразовании в булевой)

4-й номер 0, и он, подобным образом приводится к булевой и стал ложным! Таким образом, выполнение прерывает цикл, не более циклов, больше не печатает. (Даже если пятое число отличное от нуля, так как выполнение выходит из цикла уже, оно не будет напечатано)

+0

Только один nitpick - я думаю, что C++-стандарт похож на C-один, в том, что кастинг * всегда * явный - правильный термин для * implicit * "type morphing" является преобразованием. – paxdiablo

+0

@paxdiablo Спасибо, отредактирован. Я называю их неявным и явным приложением в течение длительного времени ... каждый день я что-то узнаю :) – shole

Смежные вопросы