我目前正在修改决赛。做一些考试准备并遇到这个特别的过去的问题,我发现很难掌握。
该问题要求编写以下代码的输出:
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
任何感觉像challnege ...?非常感谢解释。这是一个很长的代码......在考试中给出这个问题的大概时间大约是15到20分钟。
谢谢
发布于 2019-05-24 10:51:26
下面是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
注意:“local” i
变量from 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)
方法时...... i
创建一个“新的LOCAL”变量。i
传入的初始值为1。代码只是将“local” i
变量设置为三(3)然后返回。
一旦从方法中创建Test1(i)
的i
变量返回的代码不再在范围内,下一行代码将输出循环计数器中i
使用的变量,该变量for
仍为一(1)。输出...
Test0 = 12
Test0 = 0
Test1 = 1
当i = 2时
代码继续......分支回到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
计数器变量i
是2.当代码进入Test2(ref int i)
方法时,它不会创建自己的“本地”副本。i
主程序中使用的计数器变量“暴露”到这个方法,它“可以”改变它......因为代码必须使用下一行代码:i = 2;
这很幸运,i
IS 的当前值已经是2 i
。时尚非常气馁,我认为最坏的情况是充其量风险。
继续...... i
依然是200,从回国后Test2(ref i)
的输出...
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
当i = 3时
代码继续......分支回到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;
变
i = Convert.ToInt32(“31”) % 9;
这将返回四(4),因为31 mod 9 = 4.这是主for
循环计数器变量i
设置为的值。这意味着代码将跳过,i=4
因为它在这里被设置为4 ...当代码分支回到for
循环...它将设置i
为5.此外,当i = 3
...总结时没有输出,因为没有新输出...它与循环的上一次迭代相同。
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
当i = 5时
代码继续...分支回到for
循环,记住上一次调用Test3(ref i)
改为i
四(4),因此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
,因此value
设置为-5。然后输出value
...输出......
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5(i);
返回并进行第二次调用Test5(i - 2);
...
为了跟踪,i = 5
AND value = -5
...因此上面的呼叫使用i-2
可以重写为......
Test5(3);
在Test5中,i
= 3,代码从中减去3 value
value = -8
,然后输出......
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
当i = 6时
代码继续...分支回到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)
method将值添加到全局字典myDictionary
并从字典输出。输出...。
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
代码返回后Test6(ref int i)
,输出一行...
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
当我= 7
代码继续...分支回到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
,myDictionary[i]
将失败并抛出字典异常中不存在的“密钥”,这是有道理的,因为我们知道字典中只有一个项目,它是6.因此,异常被捕获并且显示更新...
Test0 = 12
Test0 = 0
Test1 = 1
Test2 = 2
Test5 = -5
Test5 = -8
Test6 = six
Added item to dictionary.
Catch clause entered
finally
执行try语句的子句......
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
条件(以及之后的条件)没有多大意义。如果i
不等于二(2)那么(由于短路)“和”条件的第二部分永远不会被评估。因此,唯一的时间i % 2 == 0
将被评估是什么时候i=2
??? 我相信模数(2,2)将始终返回0.这里的要点是第二个条件永远不会被评估,除非i = 2
它始终为真,因此if
可以重写为if (i == 2)
。这就是为什么本if (i == 2)
声明的“else”部分中的“第二” 语句if (i == 2)
永远不会被执行。
else if (i == 2 && i % 2 == 0) {
Test2(ref i); //i=2
Console.WriteLine("Test2 = " + i.ToString());
}
else if (i == 2)
{… never get here….
为了提供帮助,我建议您仔细查看代码中的“红旗”。通过ref传递不是一个大问题,然而,通过ref传递一个循环的“索引”并改变它的值是一个巨大的红旗挥舞着。跟踪代码变得更加复杂。这是你需要完全理解的测试。测试正在做一些你很少在任何环境中看到的东西(改变循环索引)。因此,在跟踪执行此操作的代码时需要格外小心。
https://stackoverflow.com/questions/-100005182
复制相似问题