sizeof运算符的操作数

4
我理解了“result of”的结果。
int nData = 10;
printf("%d", sizeof(nData + 2.0));

请翻译:

是 "8"

为什么每个结果都是

int nData = 10;
printf("%d", sizeof(nData = 2.0));
printf("%d", sizeof(nData += 2.0));

为什么nData不是8而是4?为什么sizeof(nData += 2.0)不能使nData等于12.012


表达式的类型很重要 - 即 sizeof(double)sizeof(int) - 在您的平台上分别为 84 - Sander De Dycker
%d 不是 sizeof() 的正确格式字符串。sizeof() 返回一个 size_t,正确的格式字符串应该是 %zd。根据C标准,7.21.6.1 fprintf函数,第6段: "z指定后面的d、i、o、u、x或X转换说明符适用于size_t"。 - Andrew Henle
2个回答

5
因为2.0是double类型的常量,根据C标准第6.3.1.8节中规定的“通常算术转换”,表达式nData + 2.0的类型为double

首先,如果任一操作数的相应实浮点类型是长双精度,则将另一个操作数转换为其相应实浮点类型的长双精度类型,而不改变类型域。

否则,如果任一操作数的相应实浮点类型是双精度,则将另一个操作数转换为其相应实浮点类型的双精度类型,而不改变类型域。

因此,sizeof的结果为double的大小。
nData = 2.0nData += 2.0的情况下,每个表达式的类型都是int,因为这是赋值左侧的类型。所以sizeof的结果为int的大小。
此外,sizeof运算符的操作数仅在编译时评估其类型。这意味着任何赋值或增量在运行时不会被评估。因此,在您的第二个示例中,sizeof使用的操作数在两行使用sizeof后仍将具有值10。只有当操作数是可变长度数组时,sizeof运算符的操作数才会在运行时评估。

如果操作数是变长数组或变长数组类型,则会评估 sizeof 的操作数。(仅说它仅在操作数为变长数组时进行评估,这涵盖了对象操作数但不涵盖类型操作数。)C 标准中的措辞是:“如果操作数的类型是变长数组类型,则对操作数进行评估;…” - Eric Postpischil

4

为什么nData不能通过sizeof(nData += 2.0)等于12.012

因为sizeof是一个编译时运算符,它操作的是数据类型而不是值。

换句话说,除非参数是变长数组(VLA),否则sizeof的操作数不会被计算。

引用C11,第§6.5.3.4章节:

sizeof运算符返回其操作数的大小(以字节为单位),该操作数可以是表达式或类型的括号名称。大小由操作数的类型确定。如果操作数的类型是变长数组类型,则对操作数进行求值;否则,不对操作数进行求值,结果是整数常量。

所以,在您的情况下,

  printf("%d", sizeof(nData + 2.0));   // data == int, 2.0 == double

是同样的

 printf("%d", sizeof(double));  //  as the resulting "type" of the addition, 
                                //   'int + double' would be  'double'

应该更好地

 printf("%zu", sizeof(double));   //not %d

sizeof 产生的类型是 size_t

另外,关于 2.0 的类型为 double,来自第 §6.4.4.2 章节:

浮点常量具有一个有效数字部分,可能后跟指数部分和指定其类型的后缀。有效数字部分的组成部分可以包括表示整数部分的数字序列,后跟一个句点(.),后跟表示小数部分的数字序列。[...]

以及

未指定后缀的浮点常量的类型为 double。[...]

因此,像 2.0 这样的常量值的类型为 double


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接