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

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

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

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

Q&A

解決済

4回答

1755閲覧

C言語でアドレスや値を参照する際の記述について

jiroway

総合スコア10

C

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

0グッド

0クリップ

投稿2016/04/22 09:13

プログラミング初心者です。
かなり基本的なことだと思いますが、調べてもどうしてもわからないので教えていただきたいです。

C言語でポインタ配列について勉強中です。
下記のようにコードを入力してポインタ配列のアドレスや格納されている値を確認するというものなのですが、
太字斜体にしている部分について質問があります。
なぜ"str+i"と"str[i]"という違った記述をしなければならないのかがわかりません。
どちらの記述も同じ意味ではないのでしょうか?
試しに両方とも"str+i"と記述するとエラーになりました。
(逆に両方"str[i]"にすると特に問題ありませんでした)

int main(void) {
char *str[] = {"dog", "cat", "rabbit"};
int i;
for(i = 0; i < 3; i++) {
printf("%p str[%d]: %s アドレス:%p\n", str+i, i, str[i], *(str+i));
}
return 0;
}

どうぞよろしくお願いします。

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

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

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

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

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

guest

回答4

0

こんにちは。

どちらの記述も同じ意味ではないのでしょうか?

意味は微妙に異なります。
str[i]char*型です。str+ichar**型です。

例えば、int foo[];int型の配列ですので、fooは通常int*型になります。
これと同じく、char* str[];char*型の配列ですので、strchar*型に*が付いた型char**となるのです。

そして、書式指定子%sはchar*型を期待しているので、そこにchar**型を与えると親切なコンパイラなら警告してくれます。

投稿2016/04/22 09:24

Chironian

総合スコア23272

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

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

0

なぜ"str+i"と"str[i]"という違った記述をしなければならないのかがわかりません。

どちらの記述も同じ意味ではないのでしょうか?

違います。同じ意味では決してありません
str[i]*(str+i)糖衣構文です。*が前に付いている分だけstr+iと違います。どれくらい違うかというと、p*pぐらい違います。

投稿2016/04/22 12:59

編集2016/04/22 13:01
raccy

総合スコア21735

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

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

0

Webで例えますと…
「リンク」と「リンク先」って両方とも同じようなものですが
実際には違いますよね。

C言語はポインターがあることにより便利な使い方ができますが、
ポインターを使う際の書式は紛らわしく理解しにくいものです。
慣れればそうでもないんですけどね。
これからもC言語を使おうと思うなら乗り越えなければならない
壁といったところでしょうか。

投稿2016/04/22 11:17

takasima20

総合スコア7458

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

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

0

ベストアンサー

Chironianさんがだいたい説明してくださっているので補足。

(逆に両方"str[i]"にすると特に問題ありませんでした)

for文の中身を少し分解してみます。(体裁は一部異なります)

C

1printf("%p", str+i); 2printf("str[%d]", i); 3printf("%s", str[i]); 4printf("アドレス:%p\n", *(str+i));

この1行目と3行目の書式指定子(printf関数の第1引数)を比較してみてください。
1行目は%p、「何か」のアドレスを追加の引数にします、という意味です。
3行目は%s、「文字列の先頭」のアドレスを追加の引数にします、という意味です。

この例では、str[i]というのが「文字列の先頭」のアドレスを意味します。
なので、printf("%p", str[i]);と書いても「アドレス」を渡しているので動作「は」します。(ただし、最初に書いたものとは別の意味になる)

一方で、str+iというのは、「文字列の先頭」のアドレスを意味しません。
これは、「「文字列の先頭」が入っているポインタ変数」のアドレスを意味します。
大事なことなのでもう一度言います、str+iは、「ポインタ変数」のアドレスを意味します。
なので、printf("%s", str+i);と書くとクラッシュするのです。

投稿2016/04/22 10:53

編集2016/04/22 10:56
majiponi

総合スコア1720

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問