printf 中的三元运算符
Posted
技术标签:
【中文标题】printf 中的三元运算符【英文标题】:Ternary operator inside printf 【发布时间】:2014-08-23 05:24:22 【问题描述】:阅读this 后,我开始认为我学到了有关printf()
的知识。突然我从this book 中发现了以下代码 sn-p:
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* ,我在我的例子中似乎没有。
【问题讨论】:
第一个参数内的表达式的结果必须是一个指向常量字符数组的指针,所以没什么奇怪的。 你的意思是即使没有双引号也是指向常量字符串的指针 如果你这样写,事情可能会变得更清楚:printf((i>j?"%50s":"%s"), str)
@A.s.Bhullar "%50s"
和 "%s"
实际上都是指向常量字符数组的指针。 i>j?"%50s":"%s"
是一个表达式。该表达式的结果必须是指向常量 char 数组的指针。我认为您将 const char *
与常量表达式混淆了,它们不是一回事
【参考方案1】:
条件运算符:
i>j?"%50s":"%s"
是一个表达式,它必须在函数调用本身被计算之前被计算。我们可以通过查看草案 C99 标准部分 6.5.2.2
函数调用 看到这一点:
参数可以是任何对象类型的表达式。在准备 对函数的调用,对参数进行评估,并且每个 参数被赋予相应参数的值。81)
那么条件运算符的求值结果是什么?如果我们转到 6.5.15
条件运算符部分,它会说(强调我的):
计算第一个操作数;在它之后有一个序列点 评估。仅当第一个比较时才评估第二个操作数 不等于0;仅当第一个操作数被评估时,才评估第三个操作数 比较等于 0; 结果是第二个或第三个的值 操作数(以被评估者为准),转换为描述的类型 95
因此,无论哪种情况,结果都是一个字符串文字,它将衰减为指向 char 的指针,该指针满足 printf
的第一个参数的要求。
【讨论】:
很好的解释!!但是我仍然对表达式 i>j?"%50s":"%s" 表示怀疑,我认为它不是 const char* ,我认为它应该用双引号括起来。不是吗? 好的,现在我明白了,在评估表达式之后,只有“%s”作为参数传递给 printf()【参考方案2】:这段代码是正常的,没有任何特殊情况。 printf
的要求是第一个参数应该是const char*
类型,但这并不一定意味着它必须是像"%s"
这样的字符串字面量。这意味着您需要将const char*
类型的表达式作为第一个参数传递。而i>j?"%50s":"%s"
满足了这一要求。
【讨论】:
你能举出任何没有完全包裹在双引号内的 const char* 的例子吗?i>j?"%50s":"%s"
是 const char *
类型(技术上它是 const char []
但在这里没关系)所以我想这是你的例子。另一个例子是func()
,其中func
是一个返回const char*
的函数。【参考方案3】:
我认为您很了解 printf
语法,但我认为您缺少有关 C 语法的一些内容。
它存在一种“紧凑的 IF like”语句,格式如下:( condition ? true : false )
例如你可以这样做:
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) );
在这种情况下你可以看到:值为真
关于你的例子:
printf(i>j?"%50s":"%s",str);
如果 i 大于 j,则使用“%50s”格式,如果 i 小于 j,则使用“%s”格式
可以这样查看:
if (i>j)
printf("%50s",str);
else
printf("%s",str);
您可以看到紧凑测试的优势。
【讨论】:
【参考方案4】:它是一个三元运算符,在这种情况下,条件 i>j 为 false,因此 %s 将作为参数传递给 printf,printf 将打印字符数组的值,即 hello。
【讨论】:
【参考方案5】:这是否意味着我在解释 printf() 的语法时错了?
不,你没有解释错。
在 printf() 中放置三元运算符是特例吗?
在 C 中,你可以说它是一个表达式而不是一个语句
您的代码相当于:
if (i > j)
printf("%50s", str);
else
printf("%s", str);
【讨论】:
【参考方案6】:三元运算符只是用作表达式的内联if
(而常规if
用于创建块)。你的行是这样的:
if (i > j)
printf("%50s", str);
else
printf("%s", str);
【讨论】:
【参考方案7】:if(i>j)
printf("%50s",str);
else
printf("%s",str);
因此,Hello
在这两种情况下都会被打印出来
【讨论】:
【参考方案8】:问:这是否意味着我在解释 printf() 的语法时出错了? A:不,只需要扩大允许的范围。
问:在 printf() 中放置三元运算符是特例吗?
A:不,?:
并不特别,但乍一看有时会让人困惑。
提供给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;
【讨论】:
【参考方案9】:有一个语句形式为:condition?consequent:alternative。
检查条件,如果为真,您将得到结果。否则,您将获得替代方案。
例如:
5>3 ? 10 : 5
5>3 是真的,所以你会得到 10。
【讨论】:
以上是关于printf 中的三元运算符的主要内容,如果未能解决你的问题,请参考以下文章