Путаница с оператором sizeof в языке C


Меня смущает оператор sizeof В C.

#include <stdio.h>

int main(void)
{
    char num1=1, num2=2, result;
    result = num1 + num2;
    printf("Size of result: %d n",sizeof result);
    printf("Size of result: %d n",sizeof(num1+num2));
}

Результаты равны 1 и 4 соответственно. Почему это происходит?

4 7

4 ответа:

result имеет тип char, поэтому sizeof дает 1, в то время как num1+num2 продвигается к типу int и поэтому дает 4 (размер int).

Обратите внимание, что когда арифметическая операция выполняется над типом, меньшим, чем Тип int, и все его значение может быть представлено int, то результат будет повышен до типа int.

TL; DR ответ:

  • sizeof result совпадает с sizeof(char).
  • sizeof(num1+ num2) то же самое, что sizeof (int) но почему?
В вашем случае они производят 1 (гарантированный стандартом) и 4 (может варьироваться) соответственно.

Вот и все, sizeof выдает результат типа size_t, поэтому для вывода значения необходимо использовать спецификатор формата %zu.


Почему:

Во-первых, для оператора сложения +, цитируя C11, Глава §6.5.6

Если оба операнда имеют арифметический тип, то обычные арифметические преобразования выполняются на их.

Относительно обычных арифметических преобразований , §6.3.1.8/p1

[....] В противном случае целочисленные продвижения выполняются для обоих операндов.[...]

А затем из §6.3.1.1,/p2,

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

Итак, sizeof(num1+num2) то же самое, что sizeof(int).

Num1 + num2 становится целым числом, и, следовательно, выход равен 4, тогда как результат-char, который выводит 1.

Вы можете сослаться на эту статью целочисленное продвижение:

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

Размер одного символа равен 1 байту, символ может содержать значения до 127 (без знака до 255). когда вы говорите что-то вроде (a + b), временная переменная создается и используется для добавления a к b, потому что a и b могут содержать только 127, компилятор продвигает их как int, просто чтобы быть уверенным.

Что логично, потому что если a = 100 и b = 100, пользователь хотел бы видеть 200, когда он добавляет их, а не 73 (что является результатом переполнения).