注册 登录
编程论坛 C语言论坛

++i和i++的困惑

纸鸢2022 发布于 2022-11-13 16:54, 1887 次点击
i=3;
printf("%d",i++); 输出值是3,C语言程序是循环执行的吗?在下个周期是不是就输出了4?还是一直输出为3,只有在循环语句里执行完毕一个循环后加1到下一个循环运算?
i=3;
printf("%d",++i);输出值是4,也就是说先把i执行完加1运算后输出。
printf("    ")这个函数对应的头文件是#include<stdio.h>,这个头文件能自定义吗?若不能怎么去查询都有哪些头文件这些头文件分别代表啥功能?若能,大致的方法是什么?

[此贴子已经被作者于2022-11-13 17:00编辑过]

18 回复
#2
菠萝吹雪2022-11-13 22:33
#3
rjsp2022-11-14 09:53
我回答一下我能看懂的部分

i=3;
printf("%d",++i);输出值是4,也就是说先把i执行完加1运算后输出。
是的,因为C语言规定:在参数评估完毕、函数调用之前,有个序列点。
但如果你问 int x = ++i 是不是先把i执行完加1运算后赋值给x的话,那就不一定,因为在C语言中(C++不是这样)这两者之间没有序列点,既可能x先变为4,也可能i先变为4。

怎么去查询都有哪些头文件
https://zh.

这些头文件分别代表啥功能
你打开上面的链接,然后随便选一个 ------ 比如“<stdio.h>     输入/输出”------ 点击进入,就能看到 https://zh.
#4
forever742022-11-15 17:04
触及某些敏感点,有点痒。
R版您确定前置++和序列点之间有关么?是新版本的说法么?
印象中只有postfix ++和序列点有关系吧?
#5
rjsp2022-11-15 18:44
回复 4楼 forever74
对于序列点,无论postfix还是prefix都是一样的,C语言对此自始至终没改过。https://zh.

C++则不再使用“序列点”的说法,改为“按顺序早于”等等;后面又规定operate=的右边早于左边。其它没什么
#6
forever742022-11-15 19:58
以下是引用rjsp在2022-11-14 09:53:15的发言:

但如果你问 int x = ++i 是不是先把i执行完加1运算后赋值给x的话,那就不一定,因为在C语言中(C++不是这样)这两者之间没有序列点,既可能x先变为4,也可能i先变为4。

我是说在这个例子中,一定是i先变为4,x是后变为4的,这件事可以确定。
但无需引用序列点理论。——是这么个“无关”。

浓缩一下就是说,在可以确定先后顺序的操作里,有些先后本来就是确定的,并不是一定要等序列点来裁决。

[此贴子已经被作者于2022-11-15 20:03编辑过]

#7
rjsp2022-11-15 21:05
我是说在这个例子中,一定是i先变为4,x是后变为4的,这件事可以确定。

i变为4、x变为4 都属于「副作用」
++i的结果是4 属于「表达式评估」
而C语言标准只规定「副作用」在顺序点之前完成,没有规定在「表达式评估」之前完成
除非你能用标准中的条款说服我

我还有另外两个不太有说服力的理由
1. 如果保证了你说的这点,那么 ++i + ++i 应当属于「实现定义行为」而不是「未定义行为」
2. C语言的每个条款都有意义,如果你说的成立,除了限制编译器作代码优化这个缺点外,我想不到任何有用的地方
#8
forever742022-11-15 21:48
只有本站会员才能查看附件,请 登录

这句话的意思是说,表达式评估的结果是操作数的新值,也就是说,前置的++的副作用不是在下一个序列点之前,而是在表达式评估之前。
#9
rjsp2022-11-15 22:46
++i 这个表达式的值是i自增后的新值,
一开始i=3,那么 ++i 就是4

并不代表i自增这个行为发生于表达式评估这个行为之前,i值变为4 属于 副作用,C语音只规定 副作用 发生于 下个序列点 之前就行了。
#10
rjsp2022-11-15 22:52
拿 ++i + ++i 为例,按你所讲的话,无论是先评估前者还是后者,都应该是9(不是4+5,就是5+4)
但实际上它是未定义行为
#11
forever742022-11-15 23:07
以下是引用rjsp在2022-11-15 22:46:06的发言:

++i 这个表达式的值是i自增后的新值,
一开始i=3,那么 ++i 就是4

并不代表i自增这个行为发生于表达式评估这个行为之前,i值变为4 属于 副作用,C语音只规定 副作用 发生于 下个序列点 之前就行了。


如果i还没有自增,那它哪来的新值呢?
#12
forever742022-11-15 23:10
我甚至理解为,这个表达式评估的结果被那句话规定为来自变量i,而不是其他来源。
#13
rjsp2022-11-15 23:12
回复 11楼 forever74
x = i+1;
i = i+1;
#14
forever742022-11-15 23:16
只有本站会员才能查看附件,请 登录

另外在后置++的第二段末尾明确描述了副作用与序列点的关系。
而在前置++的同样位置却没有类似描述。
我不认为标准文档的作者会为了避免重复而省略这种描述。
#15
forever742022-11-15 23:20
以下是引用rjsp在2022-11-15 23:12:24的发言:

x = i+1;
i = i+1;


如果是这样的话,那么字斟句酌的标准文档应该描述为评估结果为i原来的值加1的和;而不是描述为i自增以后的新值。
#16
forever742022-11-15 23:26
后置++和前置++的标准文档里都有明确的after字样,明显是用来规定这两种情况下表达式评估和副作用生效的先后次序的。
#17
rjsp2022-11-16 00:06
我说服不了你,但是标准额外要求 后++和后-- 的副作用必须发生在表达式评估之后(我不知道为什么),而前++和前--则没提。
#18
forever742022-11-16 01:42
读了一下cppreference网站的描述,和您说的一致。
相似于我在15楼说的那样,它把prefix ++的求值结果描述为:
前缀自增运算符的结果是将值 1 加到 expr 的值的结果
这明显与标准原文不一致啊。
其他结论依赖于这种不一致。

#19
rjsp2022-11-16 08:31
回复 18楼 forever74
你睡得真晚
我也不敢确定,原文描述有歧义,我都是听别人一直这么讲的
1