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

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

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

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

3回答

350閲覧

ポインタのポインタについて

alastashim

総合スコア16

C

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2018/05/19 14:30

質問概要

課題にて『ポインタのポインタを利用し、文字列の長さをカウントしその文字数を表示しなさい』というものが出ました。
ライブラリ関数<string.h>を利用したらできたのですが、ポインタのポインタを利用していなかったので一から書き直しました。しかしながら、予想した結果とは違う結果が出てしまいました。
今までポインタのポインタを習ったことがなかったため、使い方があっているのかがよくわかりません。
結果が

red 3 blue 4 yellow 6 green 5 black 5 white 5

となるためにはどうすればよいのでしょうか?
拙い説明ですがよろしくお願いします。

ソースコード

C

1#include <stdio.h> 2 3int main(void){ 4 char str[6][10]={"red", "blue", "yellow", "green", "black", "white"}; 5 char (*ptr)[10]; 6 char (**pp)[10]; 7 int i, j, num[6]={0}; 8 9 //strのポインタを代入 10 ptr = str; 11 12 //ポインタptrのポインタppに代入 13 pp = &ptr; 14 15 //指定した文字の文字数をカウント 16 for(i=0; i<6; i++){ 17 printf("%s\n", (*pp)[i]); 18 for(j=0; (*pp)[i][j] != '\0'; j++){ 19 num[j]++; 20 } 21 } 22 23 //各文字の文字数を表示 24 for(i=0; i<6; i++){ 25 printf("%d\n",num[i]); 26 } 27 28 return 0; 29} 30

実行結果

red 6 blue 6 yellow 6 green 5 black 4 white 1

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

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

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

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

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

guest

回答3

0

既にベストアンサーついてますが、ポインタのポインタを利用する、という点が明確になっていないようなので私の解釈を示します。

C

1 char str[6][10]={"red", "blue", "yellow", "green", "black", "white"};

という二次元の文字配列は、私なら文字列ポインタの一次元配列にします。

C

1 char *str[6] = { 2 "red", "blue", "yellow", "green", "black", "white" 3 };

普通は配列をアクセスする添え字 i を使って、こんな風に回すでしょう。

C

1 for (i = 0; i < 6; i++) { 2 printf("%s\n", str[i]); 3 printf("%d\n", strlen(str[i])); 4 }

ここにポインタのポインタが使えます。
str[0] は "red" という文字列を指すポインタですね。その** str[0] を指すポインタ pp を設けると、pp はポインタへのポインタ**です。
そのポインタを順に str[0]、str[1]、str[2]... と、指す位置をずらしていくことで、ポインタ配列 str[] を順に処理していくことができます。こんな風に。

C

1 char **pp; 2 3 pp = str; // pp = &str[0]; と同じ。最初は配列の先頭を指す 4 for (i = 0; i < 6; i++) { // テーブルを順に処理する 5 printf("%s\n", *pp); 6 printf("%d\n", strlen(*pp)); 7 pp++;       // 次の str[i + 1] を指す 8 }

以上、2つのfor文を比較しやすいようにしましたが、ポインタのポインタを使うなら、テーブルの最後にNULLポインタを置くのはよく使う手です。pp が NULL ポインタを指した時点でループを終了できるので、添え字変数 i を無くせます。

投稿2018/05/20 06:13

rubato6809

総合スコア1380

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

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

alastashim

2018/05/21 01:07

拙い説明の中で回答ありがとうございます。 今回の場合だと二次元配列をポインタの一次元配列にして、その先頭のアドレスを指すポインタがポインタのポインタなのですね。 わかりやすい説明ありがとうございます!
guest

0

ベストアンサー

num[j]++;
じゃなく
num[i]++;
じゃない?

投稿2018/05/19 21:09

PingHermit

総合スコア478

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

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

PingHermit

2018/05/19 22:34 編集

題意からすると、 #include <stdio.h> int main(void) { char str[6][10] = { "red", "blue", "yellow", "green", "black", "white" }; char *pp[6]; int i, j, num[6] = { 0 }; //ポインタをポインタ配列に代入 for (i = 0; i < 6; i++) { pp[i] = str[i]; } //指定した文字の文字数をカウント for (i = 0; i < 6; i++) { printf("%s\n", pp[i]); for (j = 0; pp[i][j] != '\0'; j++) { num[i]++; } } //各文字の文字数を表示 for (i = 0; i < 6; i++) { printf("%d\n", num[i]); } return 0; } じゃないかな・・・ char (*ptr)[10]; 使ってもいい気はするんだけど・・・ 文面からすると、それを却下されたような書きっぷりに見れたので。 char (**pp)[10]; はやりすぎ。 ポインタのポインタのポインタになっている。
alastashim

2018/05/20 00:47

拙い説明の中で回答ありがとうございます。 回答を見て、自分の考えが非常に硬いことに気づきました。 アドバイスありがとうございます!
guest

0

strのポインタを代入
ポインタptrのポインタppに代入

言っていることとやっていることが違います。あえて詳細な説明を省きますが、配列は3つの例外を除いて常にポインタに読み替えられることを念頭によく読み返してください。

投稿2018/05/19 14:48

yumetodo

総合スコア5850

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

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

alastashim

2018/05/20 00:47

拙い説明の中で回答ありがとうございます。 アドバイスありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問