首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >具有不同函数调用的嵌套for-循环

具有不同函数调用的嵌套for-循环
EN

Stack Overflow用户
提问于 2019-05-24 01:29:57
回答 1查看 0关注 0票数 0

我目前正在修改决赛。做一些考试准备并遇到这个特别的过去的问题,我发现很难掌握。

该问题要求编写以下代码的输出:

    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分钟。

谢谢

EN

回答 1

Stack Overflow用户

发布于 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;这很幸运,iIS 的当前值已经是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构造递增ii = 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 = 5AND 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循环,递增ii = 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循环,递增ii = 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 = 7myDictionary[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传递一个循环的“索引”并改变它的值是一个巨大的红旗挥舞着。跟踪代码变得更加复杂。这是你需要完全理解的测试。测试正在做一些你很少在任何环境中看到的东西(改变循环索引)。因此,在跟踪执行此操作的代码时需要格外小心。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100005182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档