"血をもって書け。そうすればあなたは、血が精神だということを経験するだろう。"

ポインタ

Perlのリファレンスはすぐに理解できたのに、Cのポインタは勉強するたびに何かが気持ち悪くて、いつも身につかないでいたんだけど、なんでかようやく分かった。
二つの変数を入れ替える有名な関数を書いてみる。

VB

Module Main
  Private Sub Swap(ByRef A As Integer, ByRef B As Integer)
    Dim Temp As Integer = A
    A = B
    B = Temp
  End Sub

  Public Sub Main()
    Dim A As Integer = 2, B As Integer = 3
    Swap(A, B)
    Debug.Print(A & " " & B)
  End Sub
End Module

perl

sub swap {
  my ($a_ref, $b_ref) = @_;
  ($$a_ref, $$b_ref) = ($$b_ref, $$a_ref);
}

my ($a, $b) = (2, 3);
swap (\$a, \$b);
print "$a $b";

C

void swap (int *pa, int *pb) {
  int temp = *pa;
  *pa = *pb;
  *pb = temp;
}

int main (void) {
  int a = 2, b = 3;
  swap (&a, &b);
  printf ("%d %d", a, b);
}
  • VBでは(参照渡しの)値を渡して、(参照渡しの)値を受け取る
  • Perlではリファレンス(ポインタ)を渡して、リファレンス(ポインタ)を受け取る
  • 一方Cではポインタを渡して、(参照渡しの)値を受け取る(ように見える)

呼び出し元と呼び出し先でのこの食い違いが混乱のもとだったようだ。これ以上詳しい説明はまだできないけど、ちょっと理解の助けにはなったかも。