Hatena::ブログ(Diary)

techlog RSSフィード

理解というものは、つねに誤解の総体に過ぎない
 「スプートニクの恋人」とか「かえるくん、東京を救う 」より

こちらになりました → http://sadah.hatenablog.com/

2008-04-07

[][]ポインタとか参照とか、JavaとかCとか

仕事でちょっとだけCを使うので、ちょうどよい機会だと思って勉強している。

参考書としては「やさしいC」を図書館で借りて、勉強している。

文法はJavaに近い(JavaがCに近いのだが)ので、最初のほうは比較的さくさく進められた。


そして今日はポインタを学んだ。ポインタが壁だというのはいろいろ聞いてきた。

でもポインタの概念は、特に問題なく理解できたと思う。もちろんポインタを使いこなすことはできないけど。


ちゃんと理解できていないけど、なんだか引っかかる部分があるので、文章を書きながら考えてみる。

考えながら書いているので、以下の内容には間違いがたくさん含まれている可能性がある。


なにかメソッドがあるとする。

Javaではオブジェクトの参照が渡されたり、プリミティブな値が渡されたりする。

Cではポインタが渡されたり、値が渡されたりする。


なんだか一見同じような感じがするが、実は全然違う。何が違うのか考えてみた。

Javaのオブジェクトは基本的には参照しか渡せなくて、実体を渡すことはできない。

Cでは全ての値や関数はポインタを持っている。


Javaで実体を渡す方法は・・・?Deep Copyを実装するか、シリアライズするか、普通にclone()を実装しただけじゃだめなはずだし。

うーんよく考えてみると、オブジェクトの実体を渡すなんて、やったことがない気がしてきた。

わからなくなってきたぞ。

java.lang.Object#clone()や、Shallow CopyDeep Copyに対する理解が足りない。

仮引数 / 実引数 / 値渡し / 参照渡し の理解も足りない。

仮引数とか実引数、初めて知った。「やさしいC」ではさらっと読み流してしまったが、これが大きな違いのような気がする。

Wikipediaの引数を読んだけど、細かいことがわからない。


なかなか難しいけど、こうやって違う言語を勉強して、いろいろな発見があるのは楽しい。

理解できていると思ったことが、実はちゃんと理解できていなかったことに気付いたし。

本当はわかるまでコードを書きたいところだけど、明日も仕事なので寝る・・・。


ちなみにJavaでは以下のソースを書いて試していた。かなり基本的な感じ。

これを基に、 Cloneable を実装したり、Deep Copyを試しながら、うんうん唸っている。

public class PointerTest{
  public static void main(String args[]){
    
    Obj o1 = new Obj(1);
    Obj o2 = new Obj(2);
    Obj o3 = new Obj(3);
    
    System.out.println("------------");

    System.out.println("o1 : " + o1.getValue());
    System.out.println("o2 : " + o2.getValue());
    System.out.println("o3 : " + o3.getValue());
    System.out.println("------------");
    
    o1 = o3;
    o2 = o3;
    
    System.out.println("o1 : " + o1.getValue());
    System.out.println("o2 : " + o2.getValue());
    System.out.println("o3 : " + o3.getValue());
    System.out.println("------------");
    
    o3.setValue(33);
    
    System.out.println("o1 : " + o1.getValue());
    System.out.println("o2 : " + o2.getValue());
    System.out.println("o3 : " + o3.getValue());
    System.out.println("------------");
    
  }
}

class Obj{
  private int i;
  
  public Obj(int i){
    this.i = i;
  }
  
  public void setValue(int i){
    this.i = i;
  }
  
  public int getValue(){
    return i;
  }
}

o1 = o3 や o2 = o3 では参照が渡されるので、 o3.setValue(33) で、すべてのオブジェクトの値が変わる。

↓実行結果

------------
o1 : 1
o2 : 2
o3 : 3
------------
o1 : 3
o2 : 3
o3 : 3
------------
o1 : 33
o2 : 33
o3 : 33
------------

やさしいC 第3版 [やさしいシリーズ]
高橋 麻奈
価格:¥ 2,625