为什么sizeof(a?true:false,a)运算符打印一个字节?

时间:2017-11-02 07:42:58

标签: c boolean sizeof comma conditional-operator

根据this问题,sizeof(true)sizeof(false)4个字节,因为truefalse是宏,并在{{1}中定义头文件。

但是,这里有趣的程序输出。

#include <stdbool.h>

输出(Live demo):

#include <stdio.h>
#include <stdbool.h>

int main() 
{
    bool a = true;
    printf("%zu\n", sizeof(a ? true : false, a));
                             /* ^^ -> expresion2 */
    return 0;
}

C11 6.5.15条件运算符(P4):

  

评估第一个操作数;它之间有一个序列点   评估和评估第二或第三操作数   (以评估者为准)。 仅当第二个操作数被评估时才会被评估   首先比较不等于0;第三个操作数仅在以下情况下进行评估   第一个比较等于0; 结果是第二个的值   或第三个操作数(以评估者为准),转换为该类型   如下所述.110)

此处,1 a类型且已分配值bool,然后在true运算符内,sizeof运算符执行 expression2 < / strong>因为conditionala

因此,true运算符部分(表达式3)未根据标准进行评估,而表达式2是宏。所以,根据那个问题,宏的输出是comma个字节但是在这里,程序的输出是1个字节。

所以在这里,为什么4只打印sizeof(a ? true : false, a)字节?

4 个答案:

答案 0 :(得分:10)

import Route from '@ember/routing/route'; export default Route.extend({ setupController(controller, model) { this._super(...arguments); //setup controller will be called every time the model refreshes controller.set('foo', 'bar'); } }); 是两个表达式,用逗号运算符分隔。它丢弃三元运算符的结果,并仅评估a ? true : false, a

由于aabool中的stdbool.h_Bool的宏,因此您打印_Bool数据类型的大小。很可能_Bool只是一个字节,因为它需要保持的是值1和0。

为了与链接的问题进行对比,您打印了truefalse,其中stdbool.h定义为1和0的预处理器宏。这两个是int常量,因此它们的大小是int数据类型的大小。

答案 1 :(得分:7)

首先考虑以下简单的示范程序

#include <stdio.h>
#include <stdbool.h>

int main(void) 
{
    printf( "sizeof( _Bool ) = %zu\n", sizeof( _Bool ) );
    printf( "sizeof( bool )  = %zu\n", sizeof( bool ) );

    return 0;
}

它的输出是

sizeof( _Bool ) = 1
sizeof( bool ) = 1

根据C标准(7.18布尔类型和值)

  

2宏

bool
  

扩展为_Bool。

现在让我们考虑一下此调用中sizeof运算符中使用的表达式

printf("%zu\n", sizeof(a ? true : false, a));

根据C标准(6.5.15条件运算符)

  

语法

1 conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression

即条件运算符的优先级高于逗号运算符。

所以这个表达

a ? true : false, a

是一个带逗号运算符的表达式,可以等效地重写为

( a ? true : false ) , ( a )

表达式的结果是逗号运算符的第二个操作数,即表达式( a )

如上所示,此表达式的类型为_Bool,因为变量a声明为

bool a = true;

bool扩展为_Bool。所以sizeof( _Bool )等于1。

如果您将按照本次调用中显示的以下方式重写条件运算符

printf( "%zu\n", sizeof( a ? true : a ) );

然后输出将等于sizeof( int )返回的值(通常等于4),因为类型_Bool的排名低于int类型的排名(扩展宏true的常量整数文字的类型,因此,由于整数提升,表达式a将被隐式转换为类型int

答案 2 :(得分:1)

由于表达式中使用了逗号运算符,您获得(a ? true : false, a));

(a ? true : false, a));

Comma operator

  

在C和C ++编程语言中,逗号运算符(由标记表示)是一个二元运算符,它计算第一个操作数并丢弃结果,然后计算第二个操作数并返回该值(和类型)。

因此,在表达式a中,由于逗号运算符,三元运算符的结果被丢弃,然后它计算第二个操作数并返回a。由于bool的类型为sizeof(bool),因此您的程序的输出为1 false,a

尝试在printf("%zu\n", sizeof(a ? true : (false, a))); 周围加上括号,如下所示:

false, a

当您将表达式()放在方括号(false, a)中时,将首先计算表达式a,并且逗号运算符将返回true,但三元运算符将评估表达式,返回sizeof(1),这是一个宏扩展为整数常量1,程序的输出将是4,即data-target="#undefined"

答案 3 :(得分:0)

Wiki

中的第一个陈述
  

&#34;在C和C ++编程语言中,使用逗号运算符   (由标记表示)是一个二进制运算符,用于计算它   第一个操作数并丢弃结果&#34;

基本上

printf("%zu\n", sizeof(a ? true : false, a));

评估为

printf("%zu\n", sizeof(a));

a是bool类型,rest是你得到的输出。