|
首先要明白,并非所有能通过编译的代码都是正确的代码
这种时点有问题的代码,gcc会给警告的
我强烈推荐新人用-Wall -ansi -pedantic参数编译自己的代码,学习一两星期后可以考虑用-Werror -ansi -pedantic参数
然后要明白,像++i,i--这种代码,并没有想象中的那么简单
i--确实是先取i的值,然后把i的值减少1。但是减少这一步,在什么时候去做呢?
ISO C仅仅规定,必须在下一个时序点(sequence point)前完成这步操作
例如 i++; 分号有一个时序点,所以可以确认,在分号后面,i的值已经改变了
再比如 i=1; i=++i, i--; 逗号有一个时序点,所以可以确定,在i--的时候,i的值已经是2了
但是例如i=1; i=i++; 只有分号的一个时序点,++带来的自增在什么时候处理?是=处理之前还是之后?不知道,标准没有规定这时候该怎么办,只是说这是未定义行为(undefined behavior)
什么是未定义行为?如果在看这个帖子的你不是小学生,学过初中教的函数,请回答这个问题:
y = x (x > 0) 在x = -2 时的函数值是多少?
出了定义域?这个问题本身是错的?是的,
printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n",i,++i,--i,i++,i--,-i++,-i--);
的输出结果是性质类似的问题
如果不理解函数定义域的概念,小学数学里也有类似概念
5 / 0 = ? 如果你觉得是题目印错了,那么到这里就可以了
如果你觉得是无穷大,那么只能告诉你,除以0得无穷大是高等数学没学懂的人以讹传讹搞出来的说法
未定义行为隐含的语义是,一个合格的程序员不应该写出这种不合理的代码,编译器这时候没义务给你产生正确的汇编/机器码,也没义务告诉你这代码是有问题的 |
|