大学生

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ポインタと配列

大学生

#1

投稿記事 by ポインタと配列 » 8年前

Cで以下のプログラムを実行しようとしたのですが (1)の所がSegmentation fault: 11 と表示されてしまい、うまく値を表示してくれません。str = a = *b というのは理解できたのですが、 str[2] = a[2] = *b[2] というのはやはり間違いなのでしょうか??
ポインタのポインタが理解できていないのでおそらくこのようなことになっていると思うのですが、いまいち調べても理解できません。解決して下さる方がいましたら、教えてください。よろしくお願いしますm(_ _)m

コード:

int main(){
    
    char str[]="kitty on your lap";
    char *a;
    char **b;
    
    a = str;
    b = &a;
    
    printf("%s\n", str);
    printf("%s\n", a);
    printf("%s\n", *b);
    
    putchar('\n');
    
    putchar(str[2]);  putchar('\n');  //tを表示
    putchar(a[2]);  putchar('\n');    //tを表示
    putchar(*b[2]);                        //. . .(1)
    putchar('\n');
    
    return 0;
}
実行結果は以下のようになります。
kitty on your lap
kitty on your lap
kitty on your lap

t
t
Segmentation fault: 11 //. . .(1)

アバター
amehirune
記事: 181
登録日時: 10年前
住所: どっか
連絡を取る:

Re: 大学生

#2

投稿記事 by amehirune » 8年前

ポインタのポインタについてはよくわかりませんが、
プログラムを以下のように変更すると期待通りの結果が得られました。

コード:

int main(){
    
    char str[]="kitty on your lap";
    char *a;
    char **b;
    
    a = str;
    b = &a;
    
    printf("%s\n", str);
    printf("%s\n", a);
    printf("%s\n", *b);
    
    putchar('\n');
    
    putchar(str[2]);  putchar('\n');  //tを表示
    putchar(a[2]);  putchar('\n');    //tを表示
    putchar(b[0][2]);                     //ココ!
    putchar('\n');
    
    return 0;
}
*(*b+2) や *(b[0]+2) でもOKなようです。
オフトピック
名前とトピック名が逆になっています!
最後に編集したユーザー amehirune on 2015年8月03日(月) 15:11 [ 編集 1 回目 ]
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

アバター
usao
記事: 1887
登録日時: 11年前

Re: 大学生

#3

投稿記事 by usao » 8年前

> *b[2]

というのをあなたが
(*b)[2] だと考えているのか,それとも
*( b[2] ) だと考えているのか…

#両者が異なるのはわかりますよね.

大学生

Re: ポインタと配列

#4

投稿記事 by 大学生 » 8年前

>amehiruneさん
またまたご回答ありがとうございます(^^)
期待した結果を得ることができました!
あと名前とタイトル間違えてました(恥) ご指摘ありがとうございます。

>usaoさん
私は、*(b[2])と考えておりました。でも、*(b)[2]でコンパイルすると期待した結果が得られました(^^)
また*(b)[2]で考えると理解できました!ありがとうございます。

Rittai_3D
記事: 525
登録日時: 11年前

Re: 大学生

#5

投稿記事 by Rittai_3D » 8年前

解決後ですが、説明を書いてみました。
わたしもポインタ関連は苦手なので、間違えている部分もあるかもしれません。

► スポイラーを表示
[/s]
実行結果です。

# 追記(20:07)
すいません、このコードに間違いが見つかったので修正したものを投稿しました。
大学生 さんが書きました:私は、*(b[2])と考えておりました。でも、*(b)[2]でコンパイルすると期待した結果が得られました(^^)
また*(b)[2]で考えると理解できました!ありがとうございます。
本当に期待した結果が得られたのでしょうか。
実験したところコンパイルは通りましたが何も表示されませんでした。
期待した結果が得られたコードを見せてください。
最後に編集したユーザー Rittai_3D on 2015年8月03日(月) 20:07 [ 編集 1 回目 ]
初心者です

アバター
usao
記事: 1887
登録日時: 11年前

Re: 大学生

#6

投稿記事 by usao » 8年前

3Dさんのコードの12行目時点で,こんな感じになってると思います.
(矢印で ポインタが指し示す場所 を表しているつもり)
mem_img.png
mem_img.png (7.69 KiB) 閲覧数: 3598 回
ここで 16行目 の
*b = a;
を行うと,
図内 赤枠? の所の値を 'k' を指すように書き換えてしまうと思いますが,
それはまずいのではないでしょうか.

大学生

Re: ポインタと配列

#7

投稿記事 by 大学生 » 8年前

>3Dさん
すみません、*(b)[2] と (*b)[2] を打ち間違えしておりました(^^;)
コンパイルできたのはuseoさんにご指摘して頂いた (*b)[2] の考え方です。ご迷惑おかけしました。
しかし、3Dさんのコメント付きでの解説すごく分かりやすかったです。今後ポインタをやる上での理解もますます深まりました。ありがとうございました(^^)

>usaoさん
先ほどはありがとうございました。*(b)[2] と (*b)[2] を打ち間違えしておりました(^^;)
丁寧に図まで作って解説してくださりありがとうございます。とても分かりやすいです。ありがとうございました!

Rittai_3D
記事: 525
登録日時: 11年前

Re: 大学生

#8

投稿記事 by Rittai_3D » 8年前

>usaoさん

言われて気がつきましたが、書き変えてしまうのはまずいですね・・・。
先ほどのコードを以下のように修正します。
► スポイラーを表示
実行結果です。
初心者です

きゃりーわんわん
記事: 34
登録日時: 11年前

Re: 大学生

#9

投稿記事 by きゃりーわんわん » 8年前

解決済みですがコメントさせてください。
大学生 さんが書きました: >usaoさん
先ほどはありがとうございました。*(b)[2] と (*b)[2] を打ち間違えしておりました(^^;)
丁寧に図まで作って解説してくださりありがとうございます。とても分かりやすいです。ありがとうございました!
質問者さんも既に理解されていますが、
*b[2]と記載した場合、(*b)[2]ではなく*(b[2])と解釈されます。
# *(b[2]) ⇒ b[2][0]
# (*b)[2] ⇒ b[0][2]

これは演算子の優先順位によるものです。
書籍を確認するか、webで調べてください。

実際にコードを書く際に演算子の優先順位で迷ったら
()を使用するようにしてください。
# 適切な()は読みやすくなりますが、
# ()を多用すると読みにくくなります。
# 不具合が発生するよりはマシなので、
# コメントなりでカバーするようにしてください。

大学生

Re: ポインタと配列

#10

投稿記事 by 大学生 » 8年前

>きゃりーわんわんさん

ありがとうございます。演算子に優先があるから()を付けずに書くと思った結果と違うことになってしまうのですね。これからはポインタを使って書くときの優先順位に気をつけてプログラムを書こうと思いました。
分かりやすい解説ありがとうございました(^^)

閉鎖

“C言語何でも質問掲示板” へ戻る