扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
我们一行一行分析:
创新互联专业为企业提供颍上网站建设、颍上做网站、颍上网站设计、颍上网站制作等企业网站建设、网页设计与制作、颍上企业网站模板建站服务,十多年颍上做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
for (x = 5; x 0; x--) //从x=5开始,当x0的值为false时停止循环。每次循环后x自减。
if (x-- 5) printf("%d", x); //x--的值就等于x,也就是说第一次是不执行的。这个语句同时也会将x自减。
else printf("%d", x++); //x++的值也等于x,但同时也会将x自增。第一次会执行这个语句,输出为x-1(等于4),因为在判断语句中x自减了。
所以,第一轮输出为4。
第二轮,x因为for循环自减了,此时x-- 5也已满足,又因为在上一轮循环中加1,因此输出4+1-1-1=2;
第三轮与第二轮相似,不同之处在于没有执行printf("%d", x++),因此x的值减2,输出1
LS注意,不是“没有明确规定”,而是明确规定LZ的这种用法会导致未定义行为(undefined behavior)。未定义行为基于用户对语言或数据的错误使用,具有未定义行为的程序的行为完全不可靠(就算是导致编译器崩溃也是自找的——虽然不会有厂商会让编译器表现出这种不可靠性)。被ISO C/C++定义为未定义行为的用法,可以认为不论给出什么明确的结果都是愚蠢的,于是标准不对其行为作出任何保证,用户也不应该指望有任何结果。
会出现这种问题又不说清楚undefined behavior的教材根本就是不合格。
对于这里的用法为什么属于未定义行为的严格依据(LZ需要补关于序列点的知识):
ISO C99:
3.4.3
1 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
3 EXAMPLE An example of undefined behavior is the behavior on integer overflow.
4. Conformance
2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the
behavior is undefined. Undefined behavior is otherwise indicated in this International
Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition
of behavior. There is no difference in emphasis among these three; they all describe
‘‘behavior that is undefined’’.
5.2.1.3
2 Accessing a volatile object, modifying an object, modifying a file, or calling a function
that does any of those operations are all side effects,11) which are changes in the state of
the execution environment. Evaluation of an expression may produce side effects. At
certain specified points in the execution sequence called sequence points, all side effects
of previous evaluations shall be complete and no side effects of subsequent evaluations
shall have taken place. (A summary of the sequence points is given in annex C.)
6.5
2 Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
题外话,关于表达式求值顺序是未确定行为(unspecified behavior),可以是正确的行为,但具体行为取决于实现(这里就是编译器),不能与此混淆。而入栈出栈顺序涉及函数的调用约定(calling convention),这并不是在语言的规范中决定的,需要找其它的(例如硬件架构)编程模型规范(包括ABI)定义——事实上,C语言根本就没明确函数必需使用栈实现(尽管所有的主流硬件架构乃至虚拟机实现类C语言都使用栈来表达内建静态函数的行为)。 至于结合性,则彻底可以从表达式的语法规则(一大长串,不引用了,太罗嗦)完全、明确地推导出来,只是用来说明哪个操作数进行哪个运算,和具体求值的顺序之类更是没关系。
在C中函数是不可以嵌套定义的,也就是说
在main函数里写自定义函数
这种说法是错误的,你只能在Main外面定义,在Main中调用
比如:
int
max(int
a,int
b)
{if
(ab)
return
a;else
return
b;}
main()
{
printf("%d\n",max(3,7));
}
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流