2014-07-02 73 views
6

读完后this我开始以为我已经学会了一个关于printf()的赃物。突然,我发现下面的代码片段从this书:printf中的三元运算符

int main() 
{ 
    char str[]="Hello"; 
    int i=5,j=10; 
    printf(i>j?"%50s":"%s",str); //unable to understand this 
    return 0; 
} 

令人惊讶上面的代码无故障运行,并将其打印Hello。 按以下我的知识是printf()语法:

int printf(const char *format,argument_list); 

所以根据这个语法,printf()应与格式字符串开始。但是,正如你在上面的代码printf()中看到的,以i>j开头。 这是否意味着我在解释printf()的语法时出错? 在printf()中放置三元运算符是一种特殊情况吗?

编辑

我知道三元操作,我问的printf()第一个参数应该是为const char *,我似乎没有在我的例子。

+5

第1个参数内部表达式的结果必须是一个指向常量char数组的指针,所以没有什么让人惊讶的。 –

+0

你的意思是什么,即使没有双引号是指向常量字符串 –

+1

也许事情变得更清晰,如果你这样写:'printf((i> j?“%50s”:“%s”),str)' –

回答

6

条件运算符:

i>j?"%50s":"%s" 

是一个表达式,它必须被评估前的函数调用自身可以被评估。

的参数可以是任何对象类型的表达式:我们可以通过转到C99标准草案6.5.2.2函数调用它说看到这一点。在准备调用函数 时,将对参数进行评估,并为每个参数分配相应参数的值。 81)

那么什么是条件操作符的评估结果?如果我们去部分6.5.15条件运算它说(重点煤矿):

第一个操作数计算;在它的 评估之后有一个序列点。第二个操作数仅在第一个操作数比较 不等于0;第三个操作数仅在第一个 与0比较时才被评估; 结果是第二个或第三个 操作数(取其评估对象)的值,转换为下面描述的 类型。

所以在任一情况下,结果是文字的字符串,将衰减到字符指针,其满足的第一个参数printf要求。

+0

不错的解释! 但我仍然怀疑表达式i> j?“%50s”:“%s”,我认为它不是const char *,我认为它应该用双引号括起来。不是吗? –

+0

好了,现在我明白了 就是在评估表达式之后,只有“%s”作为参数传递给printf() –

+0

@ A.s.Bhullar,这是正确的。 –

1

这是否意味着我在解释printf()的语法时出错?

不,你没有解释错误。

将三元运算符放在printf()中是否是特例?

在C语言中,你可以说,它的表达,而不是一份声明中

您的代码就相当于:

if (i > j) 
    printf("%50s", str); 
else 
    printf("%s", str); 
1

三元运算符是简单的,这些会用来作为一种表达内嵌if (而常规的if用于创建块)。你的线等于:

if (i > j) 
    printf("%50s", str); 
else 
    printf("%s", str); 
3

这段代码是正常的,没有特殊情况。对printf的要求是第一个参数应该是const char*类型,但它并不一定意味着它需要是像"%s"这样的字符串文字。所有这一切意味着你需要传递一个const char*类型的表达式作为第一个参数。并且i>j?"%50s":"%s"满足这个要求。

+0

你可以给出一个const char *的例子吗?它不能完全包裹在双引号内? –

+1

'i> j?“%50s”:“%s”'类型为'const char *'(技术上它是'const char []',但这里没关系),所以我猜这就是你的例子。另一个例子是'func()',其中'func'是一个返回'const char *'的函数。 –

0

有一种形式的陈述:condition?consequent:alternative。

检查条件,如果它是真的,你会得到结果。否则你会得到另一种选择。

例如:

5>3 ? 10 : 5 

5> 3是真实的,所以你会得到10个。

1
if(i>j) 
    printf("%50s",str); 
else 
    printf("%s",str); 

因此,Hello在这两种情况下

1

获取打印我觉得你很好理解printf语法,但我认为你缺少一些关于C语法。

它存在的一种形式 “紧凑型IF像” 语句格式这样的:(?条件

例如,你可以这样做:

int a=5; 
int b=(a==5 ? 128 : 256); 
int c=(a!=5 ? 8 : 9); 

在这种情况下,b = 128和c = 9。

的其他例子:

int flag=1; 
printf("The value is: %s", (flag!=0 ? "true" : "false)); 

在这种情况下,你可以看到:值为true

在您的例子:

printf(i>j?"%50s":"%s",str); 

如果i大于j上你使用“%50s”格式,如果我较低,则使用“%s”格式

它可以被视为像:

if (i>j) 
    printf("%50s",str); 
else 
    printf("%s",str); 

你可以看到紧凑测试的优点。

1

问:这是否意味着我在解释printf()的语法时出错?答:不,只需要扩大允许的范围即可。

问:将三元运算符放入printf()是否是一种特殊情况?
答:没有?:不是特别的,但有时第一眼就会感到困惑。

提供给printf()的格式不需要是文字。它可能是任何字符串变量。

int main() { 
    char str[]="Hello"; 
    char *format; 
    int i,j; 

    i = 5; j = 10; 
    format = i > j ? "%50s" : "%s"; 
    printf(format, str); 

    i = 10; j = 5; 
    format = i > j ? "%50s" : "%s"; 
    printf(format, str); 
    return 0; 
} 
2

它是一种三元运算符并且在这种条件I> j是false,所以%s将作为参数给printf它将打印字符阵列为hello的值来传递。