#c #sizeof #integer-promotion #long-double #not-operator
#c #sizeof #целочисленное продвижение #long-double #не-оператор
Вопрос:
Ниже приведен код C, в котором я применил оператор not к длинной переменной double:
#include <stdio.h>
int main()
{
long double a;
signed char b;
int arr[sizeof(!a b)];
printf("n%d",sizeof(arr));
return 0;
}
Этот код выводит 16. У меня проблема с пониманием того, что происходит, когда мы применяем оператор not к long double, как мы сделали с a
.
Пожалуйста, помогите мне понять, что происходит с этим кодом.
Спасибо!
Комментарии:
1. Почему вы пишете подобный код?
2. Какой результат вы получите, если не отрицать?
3.
!a
имеет типint
;(!a) b
имеет типint
… OTOH, в зависимости от приоритета (о котором я даже не собираюсь думать),!(a b)
имеет типint
==> конечный результат тот же:sizeof (!a b) == sizeof ((!a) b) == sizeof (!(a b)) == sizeof (int)
, так что у вас естьint arr[4]
4. Что не так с этим кодом? Я что-то не так написал?
5. «когда мы применяем оператор not к long double», мы получаем либо
0
либо1
типаint
Ответ №1:
Из стандарта C (6.5.3.3 Унарные арифметические операторы)
5 Результат оператора логического отрицания! равно 0, если значение его операнда сравнивается неравным 0, 1, если значение его операнда сравнивается равным 0. Результат имеет тип int. Выражение !E эквивалентно (0==E).
Итак, в этом выражении
sizeof(!a b)
подвыражение !a
имеет тип int
.
Используются целочисленные повышения операнда b
до типа int
в выражении !a b
, потому что ранг типа signed char
меньше ранга типа int
, а тип int
может представлять все значения типа signed char
.
Из стандарта C (6.3.1.1 логическое значение, символы и целые числа)
- …Если int может представлять все значения исходного типа (что ограничено шириной для битового поля), значение преобразуется в int; в противном случае оно преобразуется в unsigned int. Они называются целочисленными повышениями. 58) Все остальные типы не изменяются на целочисленные повышения.
Таким образом, полное выражение эквивалентно
sizeof( int )
Если sizeof( int )
равно 4
, то у вас есть массив, объявленный как
int arr[4];
Его размер равен, 16
то есть 4 * sizeof( int )
.