我目前正在修改决赛。做一些考试准备并遇到过这个特别过去的问题,我发现很难掌握。
问题要求写下以下代码的输出:
private static Dictionary<int, string> myDictionary = new Dictionary<int, string>();
private static int value = 0;
static void Main(string[] args)
{
try
{
for (int i = 0; i < 10; ++i)
{
if (i == 0)
{
Test0(); //Test0 = 12
Console.WriteLine("Test0 = " + i.ToString());
}
else if (i == 1)
{
Test1(i);
Console.WriteLine("Test1 = " + i.ToString());
}
else if (i == 2 && i % 2 == 0)
{
Test2(ref i); //i=2
Console.WriteLine("Test2 = " + i.ToString());
}
else if (i == 2)
{
Test1(i); //i=3
Console.WriteLine("Test1 = " + i.ToString());
}
else if (i == 3)
{
Test3(ref i);
}
else if (i == 4)
{
string str;
str = Test4(i);
Console.WriteLine("Test4 = " + (int.Parse(str) + i));
}
else if (i == 5)
{
Test5(i);
Test5(i - 2);
}
else if (i == 6)
{
Test6(ref i);
Console.WriteLine("Added item to dictionary.");
}
else if (myDictionary[i] == "six")
{
Console.WriteLine("Item 6 is in the dictionary.");
}
else
{
Console.WriteLine("Entered else clause");
int zero = 0;
int result = i / zero;
Console.WriteLine("Result is " + result.ToString());
}
}
Console.WriteLine("End of loop reached");
}
catch
{
Console.WriteLine("Catch clause entered");
}
finally
{
Console.WriteLine("Finally clause entered");
}
Console.WriteLine("Finished");
Console.ReadKey();
}
private static void Test0()
{
int result = 0;
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 2; j++)
{
result += i;
}
}
Console.WriteLine("Test0 = " + result.ToString());
}
private static void Test1(int i)
{
i = 3;
}
private static void Test2(ref int i)
{
i = 2;
}
private static void Test3(ref int i)
{
i = Convert.ToInt32(i + "1") % 9;
}
private static string Test4(int i)
{
string str;
str = i.ToString() + i.ToString();
return str;
}
private static void Test5(int i)
{
Program.value -= i; //value = 0
Console.WriteLine("Test5 = " + Program.value.ToString());
}
private static void Test6(ref int i)
{
myDictionary.Add(i, "six");
Console.WriteLine("Test6 = " + myDictionary[i]);
}
}
我的答案是:
Test0 = 12
Test0 = 0
Test1 = 3
Test2 = 2
Test1 = 3
Test5 = -5
Test5 = -3
Test6 = six
Added item to dictionary
End of loop reached
Catch clause entered
Finally clause entered
Finished
这显然是错误的。正确答案是:
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
Catch clause entered
Finally clause entered
Finished
任何人都觉得自己像个傻瓜......?非常感谢解释。这是一个很长的代码...考试中这个问题的大概时间大约是15到20分钟。
由于
答案 0 :(得分:0)
以下是i = 0,1,2,3,4,5,6,7(崩溃)
的痕迹时
i = 0
代码调用Test0()
方法。这种方法只是循环一些“局部”变量并输出结果。 “Test0 = 12”注意:i
变量是“local”,并且与主i
循环计数器中使用的for
变量不同。
if (i == 0) {
Test0(); //Test0 = 12
Console.WriteLine("Test0 = " + i.ToString());
} else...
private static void Test0() {
int result = 0;
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
result += i;
}
}
Console.WriteLine("Test0 = " + result.ToString());
}
代码从Test0()
返回...输出...
Test0 = 12
注意:来自i
的“本地”Test0
变量已超出范围,i
循环中的for
计数器变量已输出...
Test0 = 12
Test0 = 0
当i = 1时
代码继续...循环回到for
循环,递增i = 1
。输入代码......
if (i == 1) {
Test1(i);
Console.WriteLine("Test1 = " + i.ToString());
} else...
private static void Test1(int i) {
i = 3;
}
当i = 1
代码调用Test1(i)
方法时。此方法将int
变量作为参数。当代码进入Test1(int i)
方法时......会创建一个“新LOCAL”变量i
。传递了i
的初始值为1.代码只是将“local”i
变量设置为三(3)然后返回。
代码从Test1(i)
返回后,方法中创建的i
变量不再在范围内,下一行代码将输出i
变量,该变量在{ {1}}循环计数器,仍然是一(1)。输出...
for
当i = 2时
代码继续......分支回Test0 = 12
Test0 = 0
Test1 = 1
循环,递增for
。输入代码......
i = 2
旁注是。
这里变量由if (i == 2 && i % 2 == 0) {
Test2(ref i); //i=2
Console.WriteLine("Test2 = " + i.ToString());
} else...
private static void Test2(ref int i) {
i = 2;
}
(引用)传入。目前,ref
计数器变量for
为2.当代码进入i
方法时,它不会创建自己的“本地”副本。主程序中使用的计数器变量Test2(ref int i)
被“暴露”给这个方法并且它“可以”改变它......因为代码必须对下一行代码进行处理:i
这是幸运的当前值i = 2;
已经是2.以这种方式改变i
是非常气馁的,我认为最坏的情况是崩溃风险。
从i
输出...
i
仍为2
Test2(ref i)
当i = 3时
代码继续......分支回Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
循环,递增for
。输入代码......
i = 3
当if (i == 3) {
Test3(ref i);
} else...
private static void Test3(ref int i) {
i = Convert.ToInt32(i + "1") % 9;
}
代码调用i = 3
方法时。在这里,看起来这个方法试图在主循环中“改变”Test3(ref i)
计数器变量。在我们知道i
...
i = 3
成为
i = Convert.ToInt32(i + "1") % 9;
这将返回四(4),因为31 mod 9 = 4.这是主i = Convert.ToInt32(“31”) % 9;
循环计数器变量for
设置为的值。这意味着代码将在i
时跳过,因为它在此处设置为4 ...当代码分支回到i=4
循环时......它将for
设置为5。另外,当i
...总结时没有输出,因为没有新的输出......它与循环的前一次迭代相同。
i = 3
当i = 5时
代码继续...分支回到Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
循环,记住上一次调用for
已将Test3(ref i)
更改为四(4),因此i
构造增量if
到i
。输入代码......
i = 5
当if (i == 5) {
Test5(i);
Test5(i - 2);
} else...
private static void Test5(int i) {
Program.value -= i; //value = 0
Console.WriteLine("Test5 = " + Program.value.ToString());
}
代码调用i = 5
方法两次时。 Test5(i)
方法需要一个Test5(int i)
参数int
,然后从全局变量i
中减去i
的值。在此阶段,我们“知道”value
,因此value=0
设置为-5。然后输出value
...输出...
value
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
返回,并使用Test5(i);
...
要跟踪,Test5(i - 2);
和i = 5
...因此,使用value = -5
进行上述调用可以重写为...
i-2
在Test5中,Test5(3);
= 3,代码从i
value
中减去3,然后输出...
value = -8
当i = 6时
代码继续...分支回到Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
循环,将for
增加到i
。输入代码......
i = 6
if (i == 6) {
Test6(ref i);
Console.WriteLine("Added item to dictionary.");
} else...
private static void Test6(ref int i) {
myDictionary.Add(i, "six");
Console.WriteLine("Test6 = " + myDictionary[i]);
}
方法将值添加到全局字典Test6(ref int i)
并从字典输出。输出...。
myDictionary
代码从Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
返回后,输出一行......
Test6(ref int i)
当i = 7时
代码继续...分支回到Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
循环,将for
增加到i
。输入代码......
i = 7
以下代码抛出异常。
if (myDictionary[i] == "six") {
Console.WriteLine("Item 6 is in the dictionary.");
}
else {
Console.WriteLine("Entered else clause");
int zero = 0;
int result = i / zero;
Console.WriteLine("Result is " + result.ToString());
}
由于myDictionary[i] == "six"
,i = 7
将失败并抛出字典异常中不存在的“密钥”,这是有道理的,因为我们知道字典中只有一个项目,它是6因此,异常被捕获并且显示更新......
myDictionary[i]
执行try语句的Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
Catch clause entered
子句......。
finally
最后输出最后一行并退出代码。输出...
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
Catch clause entered
Finally clause entered
下面,化合物Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
Catch clause entered
Finally clause entered
Finished
条件(以及之后的条件)没有多大意义。如果if
不等于二(2)那么(由于短路),“和”条件的第二部分将永远不会被评估。因此,评估的唯一时间i
是i % 2 == 0
???我确信modulo(2,2)将始终返回0.这里的重点是第二个条件永远不会被评估,除非i=2
始终为真,因此i = 2
可以重写为{{1} }}。这就是为什么这个if
语句的“else”部分中的“第二个”if (i == 2)
语句永远不会被执行。
if (i == 2)
为了提供帮助,我建议您仔细查看代码中的“红旗”。通过ref传递不是一个大问题,然而,通过ref传递一个循环的“索引”并改变它的值是一个巨大的红旗挥舞着。跟踪代码变得更加复杂。这是你需要完全理解的测试。测试正在做一些你很少在任何环境中看到的东西(改变循环索引)。因此,在跟踪执行此操作的代码时需要格外小心。