プロが教えるわが家の防犯対策術!

同じような質問ばっかりたて続けにしてしまってすみません・・
あの,以下のような例の時↓
------
{
char array[7];
char *ptr;

strcpy(array, "abcdef");

ptr = &(array[0]);

printf(" array = %s\n ptr = %s\n", array, ptr);
}
------
これを実行したら、
array = abcdef
ptr = abcdef
となりますが、ポインタとして宣言してるptrから文字列を得たい時は
*ptr と書くんではないのでしょうか?
%s のように出力形式のところを指定をするだけで
文字列で表示してくれるのはなぜですか?
上の例のように書くのが正しいのでしょうか

A 回答 (6件)

*ptrで宣言した場合は、文字列表示する場合はptrと書くのが正しいのです。


ptrが文字列の先頭ポインタをさします。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2001/03/02 11:25

 %s は、指定された変数をポインタとして見るからです。

    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2001/03/02 11:26

失礼ですが、もう一度C言語の教科書を


読み直しましょう。
まず、ポインタの前に文字型以外の配列の勉強を
して正しい理解をしてください。
(「文字列」はちょっと特殊なので、、、)

「*ptr」の「*」は「ptr」が参照する先のアドレス
の中身(特定の1バイト)を参照するための演算子です。
ですから、*(ptr+1)とすれば「b」を指します。

printf(" array = %s\n ptr = %s\n", array+1, ptr+1);
とすれば、
array = bcdef
ptr = bcdef
と表示されます。
array自身はアドレスを指していますので
「array+1」で「array」から「sizeof(char)*1」分
だけアドレスがインクリメントされるため
「*(array+1)」は「array[1]」と等価となり、「array+1」は「&array[1]」と等価となります。

「%s」書式指定子には参照先のアドレスを指定します。
「%s」書式指定子は指示されたアドレスから開始
され、「\0(null文字)」までのバイト列を単純に
表示するだけの機能です。
「ptr+1」も同様で「ptr」の参照先は「&array[0]」
なので「ptr+1」で「&array[1]」と等価となります。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2001/03/02 11:26

C言語を勉強している人が陥りやすいワナにかかりましたね


C言語というものはシンプルですからもっと客観的に考える必要があります
それぞれの変数にどんな値が入っているかを良く考えながらもう一度トレース
してみてはいかがでしょうか
ちなみにこのプログラムでは

ptr = &(array[0]);

の処理の結果 ptr == array となります
( ただし array は変数ではないですが
代入できない char * 変数と考えればOKです )
ですからこの行の処理は

ptr = array;

とやっていることはまったく同じです
この行に置き換えてこのプログラムを見直してみてください
・・・いかがでしょう、少しはわかりやすくなったのでは・・・?
    • good
    • 0
この回答へのお礼

ありがとうございます。色々試してみます。

お礼日時:2001/03/02 11:28

printf(" array = %s\n ptr = %s\n", array, ptr);


を良く見て下さい。
array は何と等価でしょうか?

配列を配列名だけで書いたときは、その値は配列の先頭アドレスをさします。
つまり、arrey は &arrey[0] とは同じアドレス(つまり同じ値です)を差し
ています。

また printf のフォーマット部分で %s は他の方も書かれているように、
「ポインタの指し示すアドレスから\0 が見つかるまでを文字列として表示する。」
というprintf への指示です。

そのため、yuki7505 さんの書いたプログラムは、yuki7505 さんの書かれたような
結果が返ってきたのです。

また、*ptr とした場合は arrey 配列の先頭の文字 "a" の値が得られます。

これは、char *型の変数は はコンパイラから見てchar 配列のポインタなのか
char 変数のポインタなのかはまったく区別つかないし、区別してはいけない
ものだからです。そうしないと、配列用のポインタ、1文字変数用のポインタ・・・
ととんでもない数の型を言語仕様で作らなければならなくなります。

それで、*ptr と書いた場合は char 型の値が帰ってくるのです。では
*ptr が差すものが、配列だったらどうするの?と言われると、
「それはプログラマがそれを配列として扱い処理する。」
と言うことになります。

ということでたぶん、yuki7505 さんは、
printf("arrey = %s\n ptr = %08x\n",arrey,ptr);

として、文字列とそのアドレスを表示されることを期待していたのではと思い
ますがどうでしょうか?
    • good
    • 0
この回答へのお礼

そう期待してたんですが違うんですね。もっともっと勉強します。ありがとうございました。

お礼日時:2001/03/02 11:30

%dや%xは、引数の値を表示する機能です。


%sは引数の値をアドレスとみなして、その先にあるメモリーを
0x00が現れるまで文字列として表示する機能です。

char *ptr;という定義があって、実行文中で*ptrと書くと
「ptrのさすメモリー」の中にあるデーターの値を意味します。
このとき、型定義にしたがって最終的な値はcharとして扱われます。
ただ単にptrと書くと、変数の型定義にしたがってchar *の意味、
つまり「「charの入っているメモリー」のアドレス」の意味になります。

printf("%s",*ptr);の意味は、
printf("引数をアドレスとみなしその先のメモリーを表示する",
  「ptrのさすメモリーの中のデーター」をアドレスとして使う);

printf("%s",ptr);の意味は
printf("引数をアドレスとみなしその先のメモリーを表示する",
  ptrそのもの(←つまり"abcdef"の入っているメモリーのアドレス) );

ちょっと難しいですが、仕様にたちかえって説明してみました。
最初はこんがらがりますが、がんばってください。
    • good
    • 0
この回答へのお礼

すごく頭がこんがらまってます。はあ。。むずかしいですね・・。もっと勉強します。

お礼日時:2001/03/02 11:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!