![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
お世話になります、フジと申します。今回皆様にお聞きしたいことは、かなり基本的な部分なのですがどうしても理解できず質問させて頂きます。
まず以下のようなプログラムを作成しました。
char *data[10];
void func(char* d)
{
static int i=0;
data[i] = d;
i++;
}
int main(void)
{
int i = 0;
char a[10];
while(1){
if(i>2)break;
if(i==0) strcpy(a,"Hello");
if(i==1) strcpy(a,"Morning");
if(i==2) strcpy(a,"Night");
func(a);
i++;
}
i = 0;
while(1){
if(i>2)break;
printf("data is %s\n",data[i]);
i++;
}
return 0;
}
すると出力されるdata[]の値は全て"Night"になります。これはポインタを使っているから当たり前だと思います。
これをどうにしかして上のようにポインタを用いて,
data is Hello
data is Morning
data is Evening
と出力させることが出来ないでしょうか?
大変基本的な部分とは思いますが、宜しくお願い致します。
No.1ベストアンサー
- 回答日時:
結局、data[0]もdata[1]もdata[2]も、aのポインタを指しているので、aに最後に入ってた文字列「Night」が表示される。
data配列が指す文字列を書き換えないなら、
char *data[10];
void func(char* d)
{
static int i=0;
data[i] = d;
i++;
}
int main(void)
{
int i = 0;
char *p;
while(1){
if(i>2)break;
if(i==0) p="Hello";
if(i==1) p="Morning";
if(i==2) p="Night";
func(p);
i++;
}
i = 0;
while(1){
if(i>2)break;
printf("data is %s\n",data[i]);
i++;
}
return 0;
}
data配列が指す文字列を書き換える可能性があるなら、
char data[10][10];
void func(char* d)
{
static int i=0;
strcpy(data[i],d);
i++;
}
int main(void)
{
int i = 0;
char *p;
while(1){
if(i>2)break;
if(i==0) p="Hello";
if(i==1) p="Morning";
if(i==2) p="Night";
func(p);
i++;
}
i = 0;
while(1){
if(i>2)break;
printf("data is %s\n",data[i]);
i++;
}
return 0;
}
となる。
ここで注意しないとならないのは「charポインタの配列と、charの2次元配列は、まったくの別物」って事。
これは「charポインタと、charの配列は、まったくの別物」ってのと同じ。
「charポインタは文字列はどっか別のトコにあるが、charの配列には文字列が入ってる」と言う違いがあるのは判ると思う。
同様に「charポインタの配列は文字列はどっか別のトコにあるが、charの2次元配列には文字列が入ってる」と言う違いがある。
「charポインタの配列」で、つまり「char *data[10]」って書きたいなら「文字列は、すべて、別々の場所に格納されてるのを、それぞれ用意しないとならない」って事。
質問者さんのプログラムは「別々の文字列を、毎回、a配列に格納し、data[0]もdata[1]もdata[2]も、a配列を指すようにしている」ので、結局は
char *data[10];
int main(void)
{
int i = 0;
char a[10];
strcpy(a,"Hello");
data[0]=a;
strcpy(a,"Morning");
data[1]=a;
strcpy(a,"Night");
data[2]=a;
printf("data is %s\n",data[0]);
printf("data is %s\n",data[1]);
printf("data is %s\n",data[2]);
return 0;
}
というプログラムと等しい。
strcpy処理と、data配列にaを代入する処理には、依存関係は無いから、順序を入れ替えても同じ。つまり
char *data[10];
int main(void)
{
int i = 0;
char a[10];
strcpy(a,"Hello");
strcpy(a,"Morning");
strcpy(a,"Night");
data[0]=a;
data[1]=a;
data[2]=a;
printf("data is %s\n",data[0]);
printf("data is %s\n",data[1]);
printf("data is %s\n",data[2]);
return 0;
}
と同じ。この時、
strcpy(a,"Hello");
strcpy(a,"Morning");
は
strcpy(a,"Night");
で上書きされるので無いのと等しい。最終的には
char *data[10];
int main(void)
{
int i = 0;
char a[10];
strcpy(a,"Night");
data[0]=a;
data[1]=a;
data[2]=a;
printf("data is %s\n",data[0]);
printf("data is %s\n",data[1]);
printf("data is %s\n",data[2]);
return 0;
}
と同じになる。
これじゃ「Nightが3回表示されて当然」でしょう。
とても分かりやすい説明ありがとうございます。
私は完璧にcharポインタの配列は二次元の文字列配列の別の表現の方法だと勘違いしていました。
確かに、ポインタを外部関数の引数にした場合に、返り値なしで、値の変化が反映されるという考えから考えても、何か違うんじゃないかと思っていました。
今回の件で、配列とポインタの違いをさらに認識できました。本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
別ファイルの構造体の値を読み...
-
ヒアドキュメントの中のfor文
-
undefined offset というエラー...
-
PHP5でCSVの指定行データだけを...
-
クッキーがよくわかりません
-
rubyで複数列のデータを一行に...
-
PHPで、CSVファイルを、指定し...
-
二次元配列の削除
-
文字列の文字一文字ずつを解析...
-
指定文字を含むファイル名の取得
-
preg_splitがうまくいかないの...
-
携帯絵文字変換スクリプトで20...
-
Resource id #3 と表示されま...
-
二次元文字列をポインタで操作...
-
プルダウンメニューにDBの内容...
-
配列をループでたくさん宣言し...
-
PHP 多次元配列変数のデータ受...
-
file_existsでファイル名の部分...
-
fgetc関数について
-
PHPについて教えて下さい。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
別ファイルの構造体の値を読み...
-
複数行のデータのPOST処理に関して
-
エラーメッセージ(無効な間接...
-
Resource id #3 と表示されま...
-
ヒアドキュメントの中のfor文
-
自動で番号を振りたい
-
C言語でCSVファイルの行数を読...
-
配列同士の足し算のループ処理
-
stdClass Objectを連想配列のよ...
-
PHPでCSVの一部の行を編集したい
-
phpを実行するとファイルダウン...
-
行数が30万件ほどあるCSVから、...
-
phpでCSVファイルの中身を多次...
-
php Undefined variableエラー
-
CSVデータの行数カウントをした...
-
csvの内容を行単位で削除したい
-
複数ファイルで、それぞれの行...
-
テキストデータから指定行の削除
-
rubyで複数列のデータを一行に...
-
PHP5でCSVの指定行データだけを...
おすすめ情報