2017-10-12 111 views
3
#include <stdio.h> 
int main() 
{ 
    short int a; 
    char c; 
    printf("%d %d %d",sizeof(a),sizeof(c),sizeof(c+a)); 
} 

4字节而不是在该函数sizeof一个是炭的2字节大小为1个字节,但我把它们加起来它给4字节。它在表达式中做了什么来使其成为4为什么这个的sizeof(C + A)是给3

+1

旁白:'%D'==>'%zu' –

+4

如何在地球上是这样获得如此多的选票? –

+1

是啊......这真是令人费解......鉴于表达式'sizeof(c + a)'本身就是无意义且无用的。好吧,我想有些人只是对OP的结果感到惊讶。 –

回答

3

sizeof返回对象表示的大小后,它已被评估。表达式c+a显然返回一个int,它是四个字节。我知道你在寻找的是:

sizeof(c) + sizeof(a)

11

添加short intchar导致一个int,这显然是你的系统上的4个字节。

这是一种情况,如果“整数推广”。有关说明,请参见In a C expression where unsigned int and signed int are present, which type will be promoted to what type?。规则相当混乱,但那里的答案解释得很好。

6.3.1.8常见的算术转换the C standard,实际转换规则是:

如果两个操作数具有相同的类型,则没有进一步的转换是需要 。

否则,如果两个操作数已签署整数类型或两者具有 无符号整数类型,具有较小 整数转换等级的类型的操作数转换为操作数 的类型以更大的秩。

否则,如果具有无符号整数类型的操作数具有 秩大于或等于另一 操作数的类型的秩,然后用符号整型操作数是 转换为操作数的类型与无符号整数 类型。

否则,如果操作数的与符号整型类型可以 代表所有与无符号 整型操作数的类型的值,则与无符号整数类型的操作数是 转换为的类型带有符号整数类型的操作数。

否则,两个操作数转换为对应于与签署 整数类型的操作数的类型无符号
整数类型。

结果是4,因为,如@WeatherVane在评论指出:

5.1.2.3第11段实施例2 在执行片段char c1, c2; /* ... */ c1 = c1 + c2;的“整数优惠”要求该抽象机将每个变量的值提升为int大小,然后添加两个整数并截断总和。但是这里没有截断,因为目的地是未知的。

+1

您确定它正在向int而不是一个短? (不是说你错了,我只是想弄清楚标准是如何指定促销的) –

+0

@ChristianGibbons如果发布的代码和输出是正确的,那么它*被*提升为'int'。虽然在我阅读规则时,我也认为这可能是错误的,它应该被提升为“短”。这可能是一个编译器错误。 –

+2

@ChristianGibbons'a + c'尚未分配给任何目标变量。算术计算被提升为“int”。 –

3

当积分类型,如charshort intbool采取小于int的字节数,则这些数据类型时自动对它们进行操作晋升为intunsigned int

C11§6.3.1.1布尔,字符,和整数

如果int可以表示原始类型(如由宽度限制 ,对于一个位字段)的所有值,则值被转换为int; 否则,它被转换为一个unsigned int。这些被称为 整数促销。 58)

所以,c+a转换为类型int并且结果具有操作数即int的这种常见的类型。

此外,您的代码的行为是undefined,因为您使用了错误的格式说明符。

因此,使用%zu代替%d因为sizeof()回报size_tsize_tunsigned

C11标准:§7.21.6.1:第9段:

如果转换规范是无效的,该行为是 未定义。 225)如果任何参数不是 相应转换规范的正确类型,则行为是未定义的。

2

对于数学的(因为它发生,我不知道,当这样的事情可能永远是真实的):

的误解是OP的劳动下是

F( x)+ f(y)= f(x + y)

由于Tom在评论中指出的原因,这对sizeof()肯定是不正确的。

类的对于其真函数被称为Additive Maps

典型实例包括模块向量空间环之间的地图,或者保存的加法群。

+1

有趣,但在“C”中,sizeof是一个编译时操作符,它们不是函数。回到抽象代数,两个“+”运算符是不同的,一个是无符号整数值,另一个是类型,所以我不认为你有一个地图。 –

+1

@ tom-blodget yep只是在用一个愚蠢的问题来获得一些乐趣:)更新了参考你的输入的答案。 –