C 这个节目应该永远继续下去 #包括 #包括 int main() { int i; 对于(i=0;;) { printf(“%d\n”,((i++)*i)^i); } }

C 这个节目应该永远继续下去 #包括 #包括 int main() { int i; 对于(i=0;;) { printf(“%d\n”,((i++)*i)^i); } },c,for-loop,C,For Loop,编译时,它一直运行到极限并变为负整数。为什么会出现这种行为? 在阅读for语句语法时做这件事是为了好玩 您的程序两次调用未定义的行为,整数溢出和未排序的表达式((i++)*i)^i) 顺序点§B.29: 函数调用和实际调用中函数指示符和实际参数的求值之间。(6.5.2.2) 在下列运算符的第一个和第二个操作数的求值之间:逻辑and&(6.5.13);逻辑或(6.5.14);逗号,(6.5.17) 在条件?:运算符的第一个操作数求值与第二个和第三个操作数求值之间(6.5.15) 在一个完整


编译时,它一直运行到极限并变为负整数。为什么会出现这种行为?

在阅读for语句语法时做这件事是为了好玩

您的程序两次调用未定义的行为,整数溢出和未排序的表达式(
(i++)*i)^i

顺序点§B.29:

  • 函数调用和实际调用中函数指示符和实际参数的求值之间。(6.5.2.2)

  • 在下列运算符的第一个和第二个操作数的求值之间:逻辑and&(6.5.13);逻辑或(6.5.14);逗号,(6.5.17)

  • 在条件?:运算符的第一个操作数求值与第二个和第三个操作数求值之间(6.5.15)

  • 在一个完整表达式的求值和下一个要求值的完整表达式之间。以下是完整表达式:用于可变修改类型的完整声明符;不属于复合文字的初始值设定项(6.7.9);表达式语句中的表达式;选择语句(if或开关)的控制表达式(6.8.4);while或do语句的控制表达式(6.8.5);for语句的每个(可选)表达式(6.8.5.3);返回语句(6.8.6.4)中的(可选)表达式

  • 在库函数返回之前(7.1.4)

  • 与每个格式化输入/输出函数转换说明符(7.21.6、7.29.2)相关联的操作之后

  • 在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为该调用参数传递的对象的任何移动之间(7.22.5)

未定义的行为§3.4.3:

1-未定义的行为-使用不可移植或错误的程序结构或错误的数据时的行为,本国际标准对此没有要求。

2-注1至条目:可能的未定义行为范围从完全忽略情况到结果不可预测,到在翻译或程序执行过程中以环境特有的记录方式(有或没有发出诊断消息)表现,再到终止翻译或执行(随着诊断信息的发布)

3-示例未定义行为的示例是整数溢出的行为


对于GCC,编译默认情况下不会显示任何警告,如果您使用
GCC file.c-Wall-Wextra
序列点警告被发出,整数溢出不是这些通用标志的一部分,我确信有一个专门的标志,您可以查看您的程序调用未定义的行为两次,整数溢出和取消序列ed表达式(
(i++)*i)^i

顺序点§B.29:

  • 函数调用和实际调用中函数指示符和实际参数的求值之间。(6.5.2.2)

  • 在下列运算符的第一个和第二个操作数的求值之间:逻辑and&(6.5.13);逻辑或(6.5.14);逗号,(6.5.17)

  • 在条件?:运算符的第一个操作数求值与第二个和第三个操作数求值之间(6.5.15)

  • 在一个完整表达式的求值和下一个要求值的完整表达式之间。以下是完整表达式:用于可变修改类型的完整声明符;不属于复合文字的初始值设定项(6.7.9);表达式语句中的表达式;选择语句(if或开关)的控制表达式(6.8.4);while或do语句的控制表达式(6.8.5);for语句的每个(可选)表达式(6.8.5.3);返回语句(6.8.6.4)中的(可选)表达式

  • 在库函数返回之前(7.1.4)

  • 与每个格式化输入/输出函数转换说明符(7.21.6、7.29.2)相关联的操作之后

  • 在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为该调用参数传递的对象的任何移动之间(7.22.5)

未定义的行为§3.4.3:

1-未定义的行为-使用不可移植或错误的程序结构或错误的数据时的行为,本国际标准对此没有要求。

2-注1至条目:可能的未定义行为范围从完全忽略情况到结果不可预测,到在翻译或程序执行过程中以环境特有的记录方式(有或没有发出诊断消息)表现,再到终止翻译或执行(随着诊断信息的发布)

3-示例未定义行为的示例是整数溢出的行为


对于GCC,编译默认情况下不会显示任何警告,如果您使用
GCC file.c-Wall-Wextra
序列点警告被发出,整数溢出不是这些通用标志的一部分,我确信有一个专门的标志,考虑到
int
类型为32位,您可以查看o、 它将是这样的:

00000…..32次

在i++之后:

00000000000000000000000001

这将继续增加,直到变成:

0111..(31 1)

在下一个增量y之后
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    for (i = 0;;)
    {
        printf("%d\n", ((i++) * i) ^ i);
    }
}