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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

Q&A

解決済

4回答

994閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2018/01/25 17:02

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

例えば、

C

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

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

C

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

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

C

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

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

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

C

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

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

C

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

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

C

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

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

これの一つ前の処理、

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

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

投稿2018/01/25 23:50

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/01/26 14:41

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

0

C

1**pt+3

C

1**(pt+3)

ではなく

C

1(**pt)+3

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

C

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

C

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

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

投稿2018/01/25 17:20

okrt

総合スコア366

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

okrt

2018/01/25 17:25

なお、 **pt++ はまた別です。
退会済みユーザー

退会済みユーザー

2018/01/26 14:44

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

0

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

c

1 2 printf("%c\n", **pt+1); 3 printf("%c\n", (**pt)+1); 4 5 printf("%c\n", **pt+2); 6 printf("%c\n", (**pt)+2); 7 8 printf("%c\n", **pt+3); 9 printf("%c\n", (**pt)+3); 10

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

投稿2018/01/26 07:04

編集2018/01/26 08:09
A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/01/26 14:42

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

0

c

1 char *mark[5] = { "cba","ed","ihgf","lkj","ponm" }; 2 char **pt; 3 pt = mark; 4 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/25 23:30

編集2018/01/25 23:32
naga3

総合スコア1293

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/01/26 14:43

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

2018/01/29 00:48

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問