わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

マルチョイ2

関数呼び出しにおいて,実引数と仮引数が同じ変数名であっても,それらは別物とみなされる.なぜなら,______からである.

  1. 有効範囲が異なる
  2. 仮引数は変数でなくてもよい
  3. 関数形式マクロで定義しても適切に動作する必要がある
  4. externをつけていない

今年度の試験問題より.消去法で,正解は1です.3と4は論外で*1,2に関して,変数でなくてもよいのは,仮引数ではなく実引数です.
なのですが,1にも「あれ? これで正解でいいの?」という思いはあります.関数の再帰呼び出しを使えば,問題なく動くけれども,実引数と仮引数の変数が同じ有効範囲になるようなプログラムが書けるからです.

#include <stdio.h>

void countdown(int x)
{
  printf("%d\n", x);
  if (x > 0) {
    x--;
    countdown(x);
  }
}

int main(void)
{
  countdown(3);
  return 0;
}

上のソースコードで,次の2つは,有効範囲の同じ変数です.

  • countdown関数の仮引数として定義した変数x
  • countdown関数の中の「countdown(x);」という呼び出しについて,実引数として書いた変数x

実引数と仮引数が別物であるというのは,このコードを使って説明するのなら,「countdown(x);」という呼び出しをする際の変数xと,その呼び出しを受けて(再帰的に)countdownの関数処理を始める際に確保される変数xとが,異なるという事実によります.
そうすると,「有効範囲が異なる」よりは,「生存期間が異なる」のほうがより正確である,とも言えます.
この紛らわしさは出題時に考慮していて,各小問の前の問題文には,『以下のそれぞれについて,標準的なC言語の規格もしくはプログラミングの心がけとして正しい文になるよう《……》の中から選び,その番号を解答しなさい.』と書いているのでした.「心がけ」として見ると,1が正解,2,3,4は依然として間違いとなります.
関連:

*1:問題作成の立場からは「苦肉の選択肢」と言えます.ちなみにgoo辞書で「苦肉」を引くと,『敵を欺くために自分の身や味方を苦しめること』と書かれています.