NOEMBLEM/エンブレムが設定されていません。

メールの詳細(トピック表示)

ダブルポインタと共用体について

投稿者:nps…さん  2004/03/03 13:54  MLNo.431   [メール表示]

wakaです。

?ポインタを使用して関数間のデータの受け渡しをするのは、
呼び出し先で、変数の値を変えてもらいたいということと、
アドレスだけ渡せばよいので、オーバーヘッドがかからないというのが
理由だと思うのですが、ダブルポインタを使用するのは具体的に
どのような場合なのでしょうか。イメージがつかめません。
?共用体はメンバがメモリアドレスを共有するので、メモリが節約できる
というのがメリットのようですが、どのような場合に共用体を
使用するのでしょうか。

よろしくお願いいたします。


このエントリーをはてなブックマークに追加


  • MLNo.432   FUJIHARA Keiichiさん  (0) 2004/03/03 15:25  [メール表示する]
    藤原と申します。

    This message is reply to nps - san
    (Subject was : [beginers:0431]ダブルポインタと共用体について)

    Message-ID: <664095.1078289691553@…>
    in Wed, 3 Mar 2004 13:54:51 +0900 (JST) ...

    > 理由だと思うのですが、ダブルポインタを使用するのは具体的に
    > どのような場合なのでしょうか。イメージがつかめません。

     ちょっと誤解を招く表現を含みますが、ポインタと配列が、C
    言語では多くの場合相互に変換可能であることを考えると、ポインタの
    ポインタというのは、実は、「ポインタの配列」であることに気付くと
    思います。

     実際、

    int main(int argc, char **argv)
    は、
    int main(int argc, char *argv[])
    と書いても同じように機能します。

     イメージとしては、そういうところでしょう。



    > ?共用体はメンバがメモリアドレスを共有するので、メモリが節約できる
    > というのがメリットのようですが、どのような場合に共用体を
    > 使用するのでしょうか。

     現時点の、特にパソコン以上のプログラムでは、共用体を使う必要はほとん
    どないと考えた方がよいでしょう。
     グローバル変数が、(どこで値が書き換えられたか把握しにくいので)諸悪
    の根源であるのと同じように、他の型で(ついでに、違う名前で)同じ領域を
    書き換えることが可能な共用体は、諸悪の根源です。
     これは、多少のメモリの節約では追いつきません。

     あと、組み込みの方では、「別の型で本質的に同じもの」をアクセスする
    場合に今でも使うことがあります。

     たとえば、特定のメモリに書き込みを行うと、ビットパターンに応じて、
    LED が点灯するようなシステムで、

    struct bit_type
    {
    unsigned b0:1;
    unsigned b1:1;
    unsigned b2:1;
    unsigned b3:1;
    unsigned b4:1;
    unsigned b5:1;
    unsigned b6:1;
    unsinged b7:1;
    };

    union
    {
    unsigned char byte;
    struct bit_type bit;
    }
    LEDPort;

    などとして、

    LEDPort.byte = 0; // 全消灯
    LEDPort.bit.b3 = 1; // ひとつだけ点灯

    のように使われることはあります。


    --
    _/ -- Last 3924 hours until ATHENS 2004 Olympic Games -----------------
    _/ FUJIHARA Keiichi
    _/ E-Mail : keiichi@… <or> nagi@…
    _/ URL : http://www.keiichi.fujihara.name/
    ----------------------------------------------+----- Luna Phase 11.10 --
    PGP FingerPrint = 7CC3 4F95 8CC7 87D3 7178 C348 CD65 7F08 D68F 69F6



  • MLNo.433   "Isao SHIMAKURA"さん  (0) 2004/03/03 16:27  [メール表示する]
     島倉です。

    > 理由だと思うのですが、ダブルポインタを使用するのは具体的に
    > どのような場合なのでしょうか。イメージがつかめません。

     引数をポインタにする理由はおっしゃるとおりなのですが、ポイ
    ンタを使う理由としてはそれだけではありません。

     ポインタは、動的に確保されたメモリをアクセスするのに使いま
    す。その際、動的に確保されたメモリは配列と同様に扱うことがで
    きます。
     よって、ポインタは配列にアクセスする手段のひとつということ
    で、ダブルポインタは二次元配列を指していることになります。

     アクセスする際には、配列と同様のコードでアクセスできますが、
    ダブルポインタが示す先は『ポインタの配列』です。
     ポインタを中継することで、添字毎に必要最小限の要素を動的に
    確保することができます。

     C言語ではmain関数の二番目の引数がダブルポインタです。
     コマンドライン引数の数は不定、ひとつひとつのコマンドライン
    引数の長さも不定、なのでダブルポインタが使われています。


    > ?共用体はメンバがメモリアドレスを共有するので、メモリが節約できる
    > というのがメリットのようですが、どのような場合に共用体を
    > 使用するのでしょうか。

     近頃では一般的に共用体を使うことはなくなっていると思います。
    過去にはメモリの確保・解放を繰り返すと分断化により再利用でき
    なくなったりすることが圧倒的に多かったので、静的に確保された
    メモリを多目的に使い回すことがしばしば行われていました。

     例えばゲームソフトでは、いろんな種類のキャラクタが現れては
    消えていきますが、予め登場するキャラクタ数の上限を決めておい
    て、キャラクタの管理データは構造体にして、全てのキャラクタの
    構造体を共用体に詰め込んで、その共用体で上限の数分のメモリを
    確保しておきます。新たにキャラクタが現れるときは、使っていな
    い要素(共用体)を探して、見付かったらそれ以後はそのキャラクタ
    の構造体としてアクセスするといったことをしていました。
     余談ですが、構造体を入れ子にして、共通部分を構造体の先頭に
    おくことで、キャラクタの種類に依存しない管理ルーチンを書くこ
    とができます。


    Isao SHIMAKURA (ISLe)
    isle.shimakura@…

    ----- Original Message -----
    From: <nps@…>
    To: <beginers@…>
    Sent: Wednesday, March 03, 2004 1:54 PM
    Subject: [beginers:0431] ダブルポインタと共用体について



メールへの返信はMLのメンバーしかできません。

更新順メールリスト