質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • C

    3335questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C言語のポインタのポインタの動作がさっぱりわかりません。

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 258

ogura87

score 92

C言語では、変数に**を付けた、ポインタのポインタというものが可能であるという事を知ったのですが、実際に使ってみると、思ったような動作でなくて戸惑っています。

例えば、

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%s\n", *pt);

この場合、画面にはcdaと表示されます。
ポインタのポインタに格納されたアドレスなので、markの先頭アドレスから文字数分表示されるというのは理解できます。

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%s\n", *pt+1);

このようにすると、daと表示されます。
**ptがchar方なので、+1はchar1文字分進むというのは予想通りです。
これも理解できます。

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%c\n", **pt);

このようにすると、cと表示されます。
ポインタのポインタの値なので、cbaの先頭アドレスのcが表示されているという事は理解できます。

理解できないのは次です。

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%c\n", **pt+1);

+1しているので、てっきりcの次のbが表示されると思いきや、実際に実行数すると、配列2つめの2文字目であるdが表示されます。
先頭から5番目の文字、cの4バイト先の文字です。

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%c\n", **pt+2);

さらにこのように+2にすると、eが表示されます。
配列2つめの1文字目です。
先頭のcから数えて3バイト先です。
+1の時からひとつ戻った形になります。

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%c\n", **pt+3);

このように+3すると、今度はfが表示されます。

どうしてこのような動作になってしまうのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+6

+1しているので、てっきりcの次のbが表示されると思いきや、実際に実行数すると、配列2つめの2文字目であるdが表示されます。

これの一つ前の処理、

printf("%c\n", **pt);

**pt='c'ということは理解できているのですよね。
であれば**pt+1'c'+1に置き換えて考えられますね。
ということは文字cの次の文字dを表示しているということです。
配列の2つ目の要素から持ってきているわけではありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/26 23:41

    ttyp03様
    あぁ、なるほど。
    そういう事なんですねぇ?
    すっきりしました。
    一番わかりやすかったです!

    キャンセル

+3

**pt+3


**(pt+3)


ではなく

(**pt)+3


になっている。ということでは?

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };


    char *mark[5] = { "Cba","ed","ihgf","lkj","ponm" };


に変えて試してみましょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/26 02:25

    なお、
    **pt++
    はまた別です。

    キャンセル

  • 2018/01/26 23:44

    あぁ、なるほど。そういう事なんですねぇ。
    奥が深いです💦

    キャンセル

+1

    char *mark[5] = { "cba","ed","ihgf","lkj","ponm" };
    char **pt;
    pt = mark;
    printf("%c\n", **pt+1);

これでdと表示されるのは、二番目の配列のdではなく、
cの文字コード(99)に+1したのでdの文字(100)になったということです。

**ptは最初の配列のcの文字であるという認識は正しいのですが、
正確にはcの文字コード値である、99が入ります。
printf関数の%cは、数値を受けてそのキャラクターコード値である文字を出力するという処理をします。
つまり**ptならば99が入るのでc**pt+1ならば100が入るのでdが出力されます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/26 23:43

    なるほど、文字に1を足すという事ができてしまうんですね。
    Cの仕様という事ですね。。。

    キャンセル

  • 2018/01/29 09:48

    これはC言語の仕様ではなく、コンピュータの仕様で、
    コンピュータ内部には文字という概念はなく、すべて数値で管理しています。
    Cという文字は実際には99という数値なので、足し算をすることができるのです。

    キャンセル

+1

**ptの優先順位が高という意味で下記の様に書く事もできます

    printf("%c\n", **pt+1);
    printf("%c\n", (**pt)+1);

    printf("%c\n", **pt+2);
    printf("%c\n", (**pt)+2);

    printf("%c\n", **pt+3);
    printf("%c\n", (**pt)+3);


(**pt)は先頭のc文字を指していて文字に1,2,3と足したので、defと並んでいる文字コードが表示されています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/26 23:42

    A.Ichi様
    なるほど、そういう事なんですね?
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3335questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。