C言語関係掲示板

過去ログ

No.942 ポインタを使う理由とポインタを理解するコツ

[戻る] [ホームページ]
No.11979

ポインタについて
投稿者---BBM(2004/01/20 21:05:40)


何度も繰り返して、ポインタの章を読んだり
過去ログのポインタ関係を読みましたが・・・
自分の理解力が乏しいので・・・いまだに納得いかないです

ポインタを使った方が処理速度が速いってことは分かりました
でも、それだけではポインタを使う理由にはならないのかと・・・

私と同じような疑問にぶつかり、ポインタを初めのころは理解できなかった
分かるようになる方法があるのでしたら、教えてください
過去ログはほとんど見たので、それ以外の説明をおねがいします

No.11980

Re:ポインタについて
投稿者---gb(2004/01/20 21:37:55)


http://black.sakura.ne.jp/~third/programming/c/c20.html

No.11981

Re:ポインタについて
投稿者---senshou(2004/01/20 21:47:00)


>何度も繰り返して、ポインタの章を読んだり
>過去ログのポインタ関係を読みましたが・・・
>自分の理解力が乏しいので・・・いまだに納得いかないです
>
>ポインタを使った方が処理速度が速いってことは分かりました
>でも、それだけではポインタを使う理由にはならないのかと・・・
>
>私と同じような疑問にぶつかり、ポインタを初めのころは理解できなかった
>分かるようになる方法があるのでしたら、教えてください
>過去ログはほとんど見たので、それ以外の説明をおねがいします

私も同じ経験があります。(今もちゃんと理解しているとはいいがたいですが・・・)
入門書なんかのポインタの説明を見ると、


int x;
int *x_ptr;

x = 10;
x_ptr = &x;

printf("x=%d\n", x);
printf("x_ptr=%d\n", *x_ptr);

*x_ptr = 5;

printf("x=%d\n", x);
printf("x_ptr=%d\n", *x_ptr);



などのただポインタの説明をするだけのプログラムしか載っていなくて、
だから?って思いました。

ポインタを知るにはポインタの説明のみをした本を
読んでみるのがいいと思います。
2冊ばかり挙げてみると

・秘伝C言語問答ポインタ編第二版 柴田望洋著 ソフトバンク
・C言語ポインタ完全制覇 前橋和弥著 技術評論社

がいいかな、と。
ただ後者は書かれているコードが若干むずかしめです。
前者はかなり基礎的な話もしてくれるので、
自身がないなら前者、
地震があるなら後者、
がいいと思います。

他にも出ていたと思いますので、本屋などで何冊か読んでみてはいかがでしょうか?


No.11982

Re:ポインタについて
投稿者---senshou(2004/01/20 21:48:59)


>地震があるなら後者、

「地震」があるならって何だ?w
自信ですね。

No.11984

Re:ポインタについて
投稿者---あかま(2004/01/20 22:13:33)


>何度も繰り返して、ポインタの章を読んだり
>過去ログのポインタ関係を読みましたが・・・
>自分の理解力が乏しいので・・・いまだに納得いかないです
ポインタはもう慣れじゃないかと。
ポインタを使ったプログラムを読んでるうちに慣れます。
慣れてきた時にポインタを使った美しいプログラムを発見するとCやってて良かったなと思えるときが来ます。たぶん。

>ポインタを使った方が処理速度が速いってことは分かりました
>でも、それだけではポインタを使う理由にはならないのかと・・・
速さに命をかけるプログラマーがいるのです。
てかプログラマーは無駄を嫌いますが、ポインタを使うと無駄がなくなるのです。
実際、ポインタは使ってみると便利だなと思いますよ。
関数間の配列の値渡しとかはポインタ様様ですし。

>私と同じような疑問にぶつかり、ポインタを初めのころは理解できなかった
>分かるようになる方法があるのでしたら、教えてください
>過去ログはほとんど見たので、それ以外の説明をおねがいします
ひたすら自分でプログラムを書く。
はじめはまず間違いなくメモリ外参照してcore dumpedとかエラー出しますけどね(笑


これだけ憶えとけば使えるんじゃないかってのを説明すると

int a[100];
int b,i;
int *p;
1. &bなど変数名に&をつけるとその変数のアドレスを表す
2. だから&a[0]とすると配列aの先頭アドレス。&a[1]とするとその次のアドレスを指す
3. 配列の場合、配列名だけ書くと配列の先頭アドレスを指す。だからaと&a[0]は同じ。
4. *aみたいにアドレスに*をつけると、そのアドレスの中身を指す。だから*aはa[0]と同じ。*(a+1)とa[1]は同じ。
5. ポインタとはそのアドレスを格納して使用する変数だと思え。

p = a;//ポインタに配列の先頭アドレスをセット
for(i=0;i < 99;i++){
    b = a[i];//この3行は
    b = *(a+i);//同じことを
    b = *(p+i)//している。
}
でもこの3行みたいに同じことをしているならa[i]と書くのが一番分かりやすい。
たぶん*(a+i)とか書く人はポインタを理解してない。てか昔、自分がやりました。すいません。

for(p = a;p < a+100;p++){
    b = *p;//上の2行と同じことをしている
}
こんな感じだとポインタっぽい。かも。
5. p++とやると次の要素のアドレスを指せる
ので毎回(a+i)みたいな足し算をしなくてすむ。
ちなみにポインタが4byteのint型のポインタならp++で4byte先のアドレスを指すし、
1byteのchar型のポインタならp++で1byte先のアドレスを指します。
型のサイズに合わせて進んでくれるので便利。

長くなったけど大体こんな感じ。



No.11992

Re:ポインタについて
投稿者---かずま(2004/01/21 11:44:18)


> ポインタを使った方が処理速度が速いってことは分かりました
> でも、それだけではポインタを使う理由にはならないのかと・・・
ポインタを使う理由は速度の問題だけではありません。
次のプログラムをポインタを使わずに簡単に効率よく書けますか?

1. 複数の値を、関数の呼び出し元に返す。

void muldiv(int a, int b, int *seki, double *sho)
{
    *seki = a * b;
    *sho = (double)a / b;
}

int main(void)
{
    int x;  double y;
    muldiv(3, 7, &x, &y);
    printf("%d %g\n", x, y);
    return 0;
}


2. ひとつの構造体オブジェクトを複数の関数で参照する。

    FILE *fp = fopen("file.txt", "r");
    while ((c = getc(fp)) != EOF)
        putchar(c);
    fclose(fp);


3. 配列を効率よく関数に渡す。

   int sum(int *a, int n)
   {
       int i, s = 0;
       for (i = 0; i < n; i++) s += a[i];
       return s;
   }


4. 動的な配列を確保する。

    double *a;  int n, i;
    scanf("%d", &n);
    a = malloc(sizeof(double) * n);
    for (i = 0; i < n; i++) scanf("%lf", &a[i]);


5. 連結リストやツリーなどのデータ構造を使用する。

    struct Node {
       int data;
       struct Node *next;
    };


No.11994

Re:ポインタについて
投稿者---NykR(2004/01/21 12:25:44)


>何度も繰り返して、ポインタの章を読んだり
>過去ログのポインタ関係を読みましたが・・・

こことかここは

読まれましたか? 読んでいたら

>ポインタを使った方が処理速度が速いってことは分かりました
>でも、それだけではポインタを使う理由にはならないのかと・・・

というような疑問はわかないのではないかと思うのですが。。。

ちゃんと勉強するなら、
「C言語 ポインタ完全制覇」とか「Cプログラミング専門課程」とか「エキスパートCプログラミング−知られざるCの深層」
などがおすすめです(一応簡単な方から順に並べたつもり)。

http://black.sakura.ne.jp/~third/programming/c/c20.html
の説明はかなりいい加減なので読まない方が良いかと。

No.12144

Re:ポインタについて
投稿者---NykR(2004/01/26 09:28:32)


>こことかここは

ってどこだよ(今気が付いた)。

http://www9.plala.or.jp/sgwr-t/c/sec15-5.html
http://f1.aaa.livedoor.jp/~pointc/log666.html
http://f1.aaa.livedoor.jp/~pointc/log786.html

いや、まあ過去ログなんですけどね。

No.11995

Re:ポインタについて
投稿者---nop(2004/01/21 12:30:17)


>何度も繰り返して、ポインタの章を読んだり
>過去ログのポインタ関係を読みましたが・・・
>自分の理解力が乏しいので・・・いまだに納得いかないです

簡単に説明すると、

 プログラム上で扱うオブジェクト(変数や関数、malloc()などで動的に確保された領域など)を指し示すもの

です。
理解に乏しいのは、「何を指しているか?(何をポイントしているか?)」
が曖昧なだけでしょう。


>ポインタを使った方が処理速度が速いってことは分かりました
>でも、それだけではポインタを使う理由にはならないのかと・・・

 ポインタ=速度が速い

は迷信です。
ポインタを使えば「多くの場合は速くなる」が、
「必ず速くなる」とは限りません。

No.12044

どうもありがとうございます
投稿者---BBM(2004/01/22 19:58:04)


みなさんどうもありがとうございました
ポインタがどういうものなのか
このレスを書く前よりかは理解できるようになりました
ただ、ポインタを頭では少し理解できてきたのですが
プログラムを書くとなると話は別なので
本を買おうと思います
みなさんが、お勧め書籍を載せてくださっていたので、参考になりました
ところで、「ドリル&ゼミナールC言語」はどうなのでしょうか?
買った人がいましたら是非教えてください
Amazonのレビューを見たら、好評価でした!

No.12131

Re:どうもありがとうございます
投稿者---ともじ(2004/01/25 17:04:05)


>ところで、「ドリル&ゼミナールC言語」はどうなのでしょうか?

残念ながら、「ポインタ」に絞った説明はしていません。
入門書の範囲で、一通りの説明をしているだけで、ポインタのポインタや、
関数を指す場合などは説明していません。けれども、No.11992でかずまさん
が挙げているようなポインタの使い方については細かく説明しています。
平易な書き方で、ポインタへ持っていくまでの説明は丁寧にしたつもりです。

「やさしい」と言われる本よりは詳しく、「難しい」と言われる本よりは具体的、
と言う感じでしょうか。けれども、本は相性もありますから、やはりご自分で
お手に取ってご確認いただくのが一番だと思います。もっとも、発行部数が少ない
ので、そうそう書店に置いていないのでそれが難しいのですが…。


No.12133

Re:どうもありがとうございます
投稿者---BBM(2004/01/25 21:14:42)


>「やさしい」と言われる本よりは詳しく、「難しい」と言われる本よりは具体的、
>と言う感じでしょうか。けれども、本は相性もありますから、やはりご自分で
>お手に取ってご確認いただくのが一番だと思います。もっとも、発行部数が少ない
>ので、そうそう書店に置いていないのでそれが難しいのですが…。

そのとおりなんですよねぇ・・・
紀伊国屋に行ってみましたが、なかったです
手にとって中身を見ないことには何とも決めかねます(汗
ポインタだけが分からないってことはないので
どちらかというと、ポインタ以外も載ってる参考書が欲しいのですよw
とりあえず、また、紀伊国屋などに行って、C言語の本を見て
気に入るのがなかったら、「ドリル&ゼミナールC言語」を
買ってみようと思います!!質問もできますしw