Путаница с оператором 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 ответа:
Обратите внимание, что когда арифметическая операция выполняется над типом, меньшим, чем Тип
result
имеет типchar
, поэтомуsizeof
дает1
, в то время какnum1+num2
продвигается к типуint
и поэтому дает4
(размерint
).int
, и все его значение может быть представленоint
, то результат будет повышен до типаint
.
TL; DR ответ:
В вашем случае они производят 1 (гарантированный стандартом) и 4 (может варьироваться) соответственно.
sizeof result
совпадает сsizeof(char)
.sizeof(num1+ num2)
то же самое, чтоsizeof (int)
но почему?Вот и все,
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 (что является результатом переполнения).