Применение оператора «not» к long double в C

#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 логическое значение, символы и целые числа)

  1. …Если int может представлять все значения исходного типа (что ограничено шириной для битового поля), значение преобразуется в int; в противном случае оно преобразуется в unsigned int. Они называются целочисленными повышениями. 58) Все остальные типы не изменяются на целочисленные повышения.

Таким образом, полное выражение эквивалентно

 sizeof( int )
  

Если sizeof( int ) равно 4 , то у вас есть массив, объявленный как

 int arr[4];
  

Его размер равен, 16 то есть 4 * sizeof( int ) .