オブジェクト指向プログラミング初級者に出した問題

C#の勉強会などというものを部内でやっています。そのとき、本当に理解しているのかなという意地悪な気持ちで、非常に簡単なプログラムの出力結果を、一年生に問うて見ました。

オブジェクト指向プログラミングの壁

オブジェクト指向プログラミングの最初の壁でもあります、参照型と値型の理解ができているかを問います。ソースはC#で書かれていますが、Javaなどでも通用する考え方になります。

第一の課題

これは参照型の意味を理解しているかどうか自体を問うています。

class ArrayTest
{
    static void Main(string[] args)
    {
        int[] a = new int[] { 1, 2, 3 };
        Test(a);
        System.Console.WriteLine(a[2]);
    }
    static void Test(int[] b)
    {
        b[2] = 4;
    }
}

出力は「4」になります。

第二の課題

先ほどの課題の後に出すことで、より間違えさせることができます。stringの連結についての知識もないと解けない問題ですが、そこは本質でないのでヒントとして添えました。これでも、私の後輩はまんまと間違ってくれました。

class StringTest
{
    static void Main(string[] args)
    {
        string a = "abc"; // 等価:string a = new string("abc");
        Test(a);
        System.Console.WriteLine(a);
    }
    static void Test(string b)
    {
        b = b + "def"; // 等価:b = new string(b + "def");
    }
}

この出力結果は、何でしょうか。ここでは「abc」が出力されます。

C言語風に説明すると、Test(a)で渡されるのは、”abc”が配置されているメモリの先頭番地です。それをbが受け取りました。ここで確認すると、変数bには”abc”の先頭アドレスが入っています。そのbを、”abcdef”の先頭番地に書き換えます(ここで、最初に確保された”abc”の領域と、”abcdef”の領域は待ったく別のものです)。しかし、結局aに格納されている”abc”には何の影響もないことに気づきます。

結論

オブジェクト指向プログラミング初級者で、参照型を勉強している人に出すと、その理解度をチェックすることができると思います。メモリにどのように配置されるか(と、メモリの番地のような考え方)を説明すると、よく理解してもらえました。結局、C/C++言語で直接ポインタを扱ったことがあるのとないでは、想像力が変わってくるのでは、と感じています。

コメントを残す

メールアドレスが公開されることはありません。