问题描述
今天有人向我展示了一些我不明白的事情。这不是
看起来它应该是有效的C ++。具体来说,我不明白在fprintf函数之后如何接受
逗号。他们在这些括号中有什么影响?
我理解这个或有用的原因以及为什么永远不会这样做,我真的只是
询问该构造(fprintf(stderr,不能打开文件。\ n),
退出(0),1)) ;。
----代码----
#include< stdlib.h>
#include< stdio.h>
int main()
{
FILE * fp =(FILE *) (fopen(file,r)||
(fprintf(stderr,无法打开file.\ n),退出(0),1) );
返回0;
}
---- /代码----
- JFA1
此代码为有效从某种意义上说,它是格式良好的,即它将是b
编译。它的编译只是因为有人强迫它通过将额外的类型转换引入其他完全无意义的代码而形成良好的形式。代码没有任何意义。它不会做任何有用的事情。你确定你正确地复制了吗?
我只能猜测代码的意思如下所示
...
FILE * fp;
(fp = fopen(" file"," r"))||
(fprintf(stderr," ;不能打开文件。\ n"),退出(0),1));
...
这将是工作" ;.简而言之,如果''fopen''成功,该程序将不会尝试评估''||''运算符的第二个操作数和整个
的东西将等同于''fp = fopen(" file"," r")''。
如果''fopen''失败(即返回NULL),程序将继续
评估''||''表达式的第二个操作数:打印错误
消息并终止。
阅读更多关于内置''||''运算符和逗号('','')
运算符的属性以获取更多详细信息。我相信,你可以在FAQ中找到一些有用的
信息。
-
祝你好运,
Andrey Tarasevich
在Perl中,||如果是
非零,则运算符返回其左侧表达式。在C ++中,它返回一个bool,所以虽然代码编译,但是
fp将用(FILE *)1初始化 - 这将导致未定义的
行为,如果它是使用。
这样的代码甚至不会在混淆的C代码竞赛中占有一席之地,因为它甚至不起作用,而且泄漏。一个文件句柄。
",1"是需要的,以便...,exit(0),1表达式的结果
将是一个整数,与||兼容运算符。
(exit(0)有一个void返回类型,并且会出错。)
-
< - 电子邮件联系表格
blockquote>
这实际上属于comp.lang.c,这里没有C ++特定的代码
,但是......
如果你看,整个布尔表达式都是parens。所以如果fopen
成功,那么||语句短路,返回文件指针,
,它被强制转换为FILE *并分配给fp。
如果fopen失败,则返回NULL (或0),这导致||的第二部分
评估。它使用,,运算符,它返回它的RHS的
值。因此,它确实是fprintf [returns int],退出["返回"
void]和1 [int])。请注意,表达式1永远不会被评估,
但是编译器需要它很高兴,因为无法将void转换为
FILE *。
原始编码器试图变得聪明且高效,但是我怀疑这个代码对于这个代码的效率要高得多。
可读:
#include< stdio.h>
#include< stdlib.h>
int main()
{
FILE * fp = fopen(" file"," r");
if(fp = = NULL)
{
fprintf(stderr,无法打开file.\ n);
退出(EXIT_FAILURE );
}
返回EXIT_SUCCESS;
}
Someone showed me something today that I didn''t understand. This doesn''t
seem like it should be valid C++. Specifically, I don''t understand how the
commas are accepted after the function ''fprintf''. What effect do they have
in those parenthesis?
I understand how the or is useful and why never to do it, I''m really just
asking about that construction "(fprintf(stderr, "Can''t open file.\n"),
exit(0), 1))".
---- CODE ----
#include <stdlib.h>
#include <stdio.h>
int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can''t open file.\n"), exit(0), 1));
return 0;
}
---- /CODE ----
- JFA1
This code is "valid" in a sense that it is "well-formed", i.e. it will
compile. It will compile simply because someone forced it to be
well-formed by introducing extra typecasts into otherwise completely
meaningless code. The code doesn''t make any sense. It will not do
anything useful. Are you sure you reproduced it correctly?
I can only guess that the code was meant do look as follows
...
FILE *fp;
(fp = fopen("file","r")) ||
(fprintf(stderr, "Can''t open file.\n"), exit(0), 1));
...
This will "work". In short, if the ''fopen'' succeeds, the program will
not try to evaluate the second operand of ''||'' operator and the whole
thing will be equivalent to ''fp = fopen("file","r")''.
If ''fopen'' fails (i.e. returns NULL), the program will proceed to
evaluating the second operand of ''||'' expression: print the error
message and terminate.
Read more about the properties of built-in ''||'' operator and comma ('','')
operator for more details. I believe, you can find some useful
information in the FAQ.
--
Best regards,
Andrey Tarasevich
In Perl, the || operator returns its left-side expression if it is
non-zero. In C++, it returns a bool, so although the code compiles,
fp will be initialized with (FILE*)1 - which will lead to undefined
behavior if it is used.
Such code would not even have its place in an obfuscated C code contest,
because it doesn''t even work, and "leaks" a file handle.
The ",1" is needed so that the result of the ...,exit(0),1 expression
will be an integer, compatible with the || operator.
( exit(0) has a void return type, and would be an error).
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
This actually belongs on comp.lang.c, there is no C++ specific code
here, but...
If you look, the entire boolean expression is in parens. So if fopen
succeeds, the || statement short-circuits, returning the file pointer,
which is cast into a FILE* and assigned to fp.
If the fopen fails, it returns NULL (or 0), which causes the second part
of the || to evaluate. It uses the "," operator, which returns the
value of it''s RHS. So, it does fprintf [returns int], exit ["returns"
void] and 1 [int]). Note that the expression 1 will never be evaluated,
but the compiler needs it to be happy, since a void cannot be cast to a
FILE*.
The original coder was trying to be clever and "efficient", but I
suspect that the code for this is no more efficient that the much more
readable:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* fp = fopen("file", "r");
if (fp == NULL)
{
fprintf(stderr, "Can''t open file.\n");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
这篇关于为什么这段代码对C ++有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!