在用C#验证哥德巴赫猜想的过程中,注意到了这样一个问题:
下面这样一段代码(代码内不包含num,i,j的定义语句)
1 while (true)i 2 { 3 Console.Write("请输入一个大于2的偶数:"); 4 num = int.Parse(Console.ReadLine()); 5 if (num <= 2 || num % 2 != 0) 6 { 7 Console.Write("输入错误,请重新输入。按回车键继续。"); 8 Console.ReadLine(); 9 Console.Clear(); 10 } 11 else 12 { 13 break; 14 } 15 } 16 for (i = 2; i<=num - 2; i++) 17 { 18 j = num - i; 19 bool isFind = false; 20 for (int k = 2; k < i; k++) 21 { 22 if (i % k == 0) 23 { 24 isFind = true; 25 break; 26 } 27 } 28 if (isFind) 29 continue; 30 else 31 { 32 isFind = false; 33 for (int k = 2; k < j; k++) 34 { 35 if (j % k == 0) 36 { 37 isFind = true; 38 break; 39 } 40 } 41 if (!isFind) 42 { 43 break; 44 } 45 } 46 } 47 string result = num + "=" + i + "+" + j; 48 Console.Write(result);
主要步骤是,首先,定义一个死循环,提示用户输入大于2的偶数num,输入不符合规定的数字出现提示,并清屏进入下一次输入提示,直到输入正确,退出循环。然后,定义整数i以及j=num-i。分别对i,j进行是否是质数的判断,如果都是,则哥德巴赫猜想得到验证,输出num=i+j。最开始,我把i和j直接定义在判断的循环语句内,编译报错,i,j没有定义,好的,我发现了定义域有问题,于是把定义语句提到了15行之后的位置,然而编译器继续报错,说是j没有赋值,也就是说j=num-i,这个语句没有起作用,再往上反推,那也就是说16行的循环没有执行。问题出现了,我明明已经定义了j变量,并且在之前的死循环内也判断过num是否符合条件,这个循环是一定可以执行至少一次的啊。最后,找到了如下解释:
C#的编译器并没有那么智能,它认为的是,只要是循环,那么就存在一次也没有执行的情况,如果没有执行,那么写在循环体中的j变量赋值语句也就不存在了。哪怕我在之前的死循环中对num值有过判断,i<=num - 2是至少能够执行一次的,也就是说j是能够被赋值的,但编译器没有办法判断这一点。与其说这是一个编译错误,我认为它更像是智能性上的一个bug。解决方法也非常简单,直接给j任意赋一个值,"骗"过编译器,就能保证程序正常运行了。
原文地址:http://www.cnblogs.com/ruiuii94/p/7255817.html