Результат "sizeof" зависит от расположения скобок. Почему?

Есть код:

 float x=-8.92;
 int y=5;
 printf("%u\n", sizeof x+y);
 printf("%u\n", sizeof (x+y));

Заключение:

9
4

Почему это происходит (результат 9)? Ведь это простые унарные операции.

sizeof x+y = sizeof(x)+y = 4+5 =9
Krishna Kanth Yenumula 24.12.2020 14:44
sizeof x == 4 -> y == 5 -> 4 + 5 == 9
Cid 24.12.2020 14:44
sizeof скобки не нужны. Скобки необходимы только для типа данных, например. sizeof (int).
i486 24.12.2020 14:44

Пожалуйста, смотрите этот пост здесь о том, когда использовать скобки.

costaparas 24.12.2020 14:45

@ i486 sizeof скобки не нужны. Скобки необходимы только для типа данных, например. sizeof (int) Это означает, что вы всегда должны использовать их. Неважно, они делают ошибки, подобные тем, которые демонстрирует эта программа, невозможными.

Andrew Henle 24.12.2020 15:00

касательно; float x=-8.92; Буквальное: -8.92 объявляет значение double, которое затем преобразуется в значение float. Чтобы объявить значение float, используйте: -8.92f Обратите внимание на трейлинг f

user3629249 25.12.2020 04:28

относительно: printf("%u\n", sizeof x+y); printf("%u\n", sizeof (x+y));sizeof возвращает size_t, который является unsigned long int A u не является допустимым спецификатором выходного формата для size_t Предложите использовать: %zu

user3629249 25.12.2020 04:31

@AndrewHenle Скобки не могут помочь тому, кто пишет sizeof (x+y).

i486 25.12.2020 11:14

@ i486 Значение sizeof (x+y) понятно. Какая помощь там нужна? Если это не то, что имел в виду программист, это не проблема с синтаксисом языка, и это не проблема замены x + y на x / y.

Andrew Henle 25.12.2020 16:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
9
171
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Это выражение

sizeof x+y

эквивалентно выражению

( sizeof x ) + y

Так как sizeof x равно sizeof( float ), то есть 4, то результат исходного выражения равен 9.

Оператор sizeof является унарным оператором, а его операнд, в свою очередь, является унарным выражением. То есть оператор, в частности, определяется как

sizeof unary-expression

x + y является аддитивным выражением, а переменная x в качестве первичного выражения, в свою очередь, является унарным выражением. Таким образом, оператор применяется к переменной x.

С другой стороны, выражение ( x + y ) является первичным выражением и в силу обычных арифметических преобразований имеет тип float. Таким образом, в этом случае, когда выражение записывается как sizeof( x + Y ), оператор sizeof снова применяется к первичному (унарному) выражению и эквивалентен sizeof( float ).

Обратите внимание, что вместо спецификатора преобразования %u в вызовах %zu следует использовать спецификатор преобразования printf. Типом обоих выражений sizeof x + y и sizeof( x + y ) является size_t, который является типом, определенным реализацией, который обычно является псевдонимом для типа unsigned long. Для типа size_t определен спецификатор преобразования zu, который вы должны использовать. В противном случае вызов printf с неправильным спецификатором преобразования может привести к неопределенному поведению.

Спасибо за подробный ответ. Не могли бы вы подсказать, почему следует использовать «%zu» вместо «%u»?

The person with the question 24.12.2020 15:04

@Thepersonwiththequestion Смотрите мой приложенный ответ.

Vlad from Moscow 24.12.2020 15:07

Оператор sizeof имеет более высокий приоритет, чем оператор двоичного сложения +. Итак, это:

sizeof x+y

Разбирает как:

(sizeof x)+y

Таким образом, в первом выражении вы получаете размер float, который в вашей системе равен 4, и добавляете к нему значение 5, в результате чего получается 9. Во втором выражении подвыражение x+y имеет тип float из-за обычных арифметических преобразований, поэтому результат равен 4, что и напечатано.

Спасибо. Я действительно забыл о приоритете унарных операций.

The person with the question 24.12.2020 14:48

sizeof x+y совпадает с (sizeof x) + y, то есть sizeof имеет более высокий приоритет, чем +.

Ваш компилятор должен был предупредить вас о несоответствии между строкой формата printf() (%u) и аргументом (size_t, int или другим) — если вы используете GCC, вы должны добавить -Wall -Wextra в команду компиляции.

Обязательно изучу "- Wall-Wextra". Спасибо за совет .

The person with the question 24.12.2020 14:57

Фактический тип аргумента — size_t в обоих вызовах, правильный спецификатор формата — %zu.

zwol 24.12.2020 14:58

@zwol, int + size_t не обязательно size_t. Но да, я получил x и y неправильно - теперь исправлено.

Toby Speight 24.12.2020 15:00

@TobySpeight Думаю, технически size_t может быть меньше, чем int (минимальный максимум для size_t равен 65536, как и unsigned short, и unsigned int), но мне это кажется действительно странным ABI. Вы знаете настоящий ABI, который делает это?

zwol 24.12.2020 16:55

О да, это звучит очень маловероятно, соглашусь. Нет, я не знаю о таких системах (но я, как правило, работаю с обычными рабочими станциями Unix, так что вряд ли буду). Кроме того, я изо всех сил пытаюсь запомнить общий тип значений со знаком и без знака для арифметики. В любом случае, спасибо, что указали, что я забыл, какая переменная была float.

Toby Speight 24.12.2020 16:57

Результат «sizeof» зависит от расположения скобок. Почему?

Потому что «скобки» переопределяют приоритеты операторов.

Другие вопросы по теме