Почему такой вывод программы C
Я пытался запустить следующий код и наткнулся на некоторые результаты. Может кто-нибудь объяснить:
int number = {12,13,14};
printf("%d",number);
Приведенный выше код выводится в виде 12
. Если я попытаюсь выполнить следующий код:
int number = (12,13,14);
printf("%d",number);
Выводится как 14
, но со следующим кодом выводится как 12
:
int number;
number = 12,13;
printf("%d",number);
3 ответа:
number = {12,13,14}
это скалярная инициализация, но вы предоставляете больше элементов, чем должны, компилятор выдаст предупреждение, которое, я полагаю, вы проигнорировали, и первый элемент 12 присваивается переменнойnumber
.Когда вы используете
number = (12,13,14)
,Оператор Comma (
Таким образом, здесь 12 отбрасывается, а 13 оценивается до 13 и возвращается. Теперь это возвращаемое значение 13 является первым операндом для следующего оператора запятой. Теперь он вычислит 13 к 13 и отбросит этот результат 13 и оценит второй операнд, т. е. 14, и вернет результат как 14, который назначен переменной,
) вычисляет первый операнд и отбрасывает результат, затем вычисляет второй операнд и возвращает результат.number
.Когда вы делаете следующее
number = 12,13; printf("%d",number);
Это выведет 12, поскольку приоритет
=
больше, чем,
, поэтому сначалаnumber = 12
будет вычислено и=
вернет присвоенное значение, т. е. 12. Теперь оператор запятая получил два операнда, повторяющие значение=
операция 12 и 13. С запятой оператор 12 будет оценен как 12 и отброшен. 13 оценивается и возвращается. Вернулся в себя? Никто. Не назначеноnumber
, потому что назначение уже выполнено. Так чтоnumber = 12,13;
выглядит как(number=12),13;
Попробуйте и это.
int num1,num2; num2 = (num1 = 13,14); printf("%d %d",num1,num2);
Это выведет
13 14
в соответствии с аргументом, приведенным для вывода предыдущего кода.
int number = {12,13,14};
number
являетсяint
, который не ожидает такого инициализатора, поэтому синтаксис C является незаконным.int number = (12,13,14);
Оператор запятой возвращает в результате правильный операнд, он эквивалентен
int number = ((12,13),14)
, поэтомуnumber
имеет значение14
.int number = 12,13;
Это инициализация, а не присвоение. Поэтому оператор запятой не должен использоваться здесь, незаконный синтаксис C.
После редактирования этот код
int number; number = 12,13;
- оператор выражения, это оператор запятой, первый операнд присваивание
number = 12
, которое присваиваетnumber
с12
в качестве побочного эффекта, второй операнд13
также является оператором выражения, который ничего не делает, поскольку у него нет побочного эффекта.
Первое выражение:
int number = {12,13,14};
Является неопределенным поведением , если мы рассмотрим раздел проекта стандарта C99
6.7.8
инициализация абзац 2 говорит:Ни один инициализатор не должен пытаться предоставить значение для объекта, не содержащегося в сущности. инициализация.
В этом случае intitializer состоит из двух элементов. Второй случай опирается на оператор запятой , раздел которого
6.5.17
абзац 2 говорит (Курсив мой):Левый операнд оператора запятой вычисляется как пустое выражение ; существует точка последовательности после ее оценки. Затем вычисляется правый операнд ; результат имеет свой тип и значение.97
Второй случай:
int number = (12,13,14);
Эквивалентно:
int number = ((12,13),14);
Следуя правилам, изложенным в
6.5.17
, результатом(12,13)
будет13
, а результатом13,14
будет14
. В последний случай:number = 12,13;
Поскольку
=
связывается сильнее( имеет более высокий приоритет), чем,
, значение12
будет присвоеноnumber
, а затем13
будет вычислено без побочных эффектов.