编译器 vs C语言
第一次printf 结果输出但不显示,这是为什么?后面正常输出;
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include<stdio.h>
int main1(void)
{
int input=0;
char arr[10];
while (1)
{
printf("是否需要检查 是 1 否 0\n");
scanf("%d", &input);
if (input == 1)
{
printf("请输入想要判断的字符\n");
scanf("%s", arr);
}
else
{
break;
}
}
return 0;
}
第6行:int main1(void) ,main() 函数名错误了。
没问题啊(把main1改成main)
为什么叫mian1,是不是你的项目里还有别的cpp文件?一个项目只能有一个主程序。
我开始没意识过来,后来自己算了一遍,算出为“3 6”,这问题就有点大了,开始百度吧。
查了一圈,发现了第一个问题,printf的计算顺序是从右往左的(和栈有关,先入后出),于是再次计算,发现还是不对,第二次算出为“4 2”。所有又是哪里出问题了呢。
忽然想起,vs有反汇编的功能,那我直接看汇编代码看看问题出在哪
(vs的编译器是cl,不同编译器将会有不同结果)
嗯,主体部分都在这,我们一条一条看
char a = 1;
004018E8 mov byte ptr [a],1 ;把立即数1送到a所指向的地址单元(一个字节),ptr表示指针,也就是给变量a赋值
printf("%d %d", a += 2, a *= 2);
004018EC movsx eax,byte ptr [a] ;将变量a的值赋给eax寄存器
004018F0 shl eax,1 ;eax寄存器左移一位,也就是a*2
004018F2 mov byte ptr [a],al ;al表示eax寄存器的低八位,是最低的八位,eax为32位的,这句的意思是把eax的值又赋给a
004018F5 movsx ecx,byte ptr [a] ;a的值赋给ecx寄存器
004018F9 add ecx,2 ;a+2
004018FC mov byte ptr [a],cl ;a=a+2,给a赋值,这是变量a就是4了,同理cl为ecx的低八位
004018FF movsx edx,byte ptr [a] ;a的值赋给edx寄存器,为4
00401903 push edx ;将edx的内容压栈
00401904 movsx eax,byte ptr [a]
;问题出在这句,本来在这句代码之前,eax的内容为2,
;即第一个算式a*=2的内容;这里重新赋值,导致eax变成了4,下图为单步执行时寄存器值的变化
00401908 push eax ;将eax的内容压栈
printf("%d %d", a += 2, a *= 2);
00401909 push offset string "%d %d" (0407B30h)
0040190E call _printf (040104Bh)
00401913 add esp,0Ch
至此,我们可以从汇编代码中可以看出“4 4”结果整个的计算过程
群里大佬的总结:(对应开始时输出两次变量a的值)
最后验证了一下,确实是从右到左算完后,再从左到右输出
(小弟俺第一次使用vs的反汇编动能,也没接触过cl的汇编程序,如有错误恳请纠正)
根据参考资料,可以得出一些结论:
根据以上结论,对于这个问题,可以采取以下措施:
代码示例:
int main() { printf("Hello, world!\n"); fflush(stdout); // 强制刷新控制台输出 // 修改控制台窗口标题 SetConsoleTitle("My Program"); // 后续输出正常 printf("This is my program.\n"); return 0; }