ページ 11

ポインタとprintf関数についての初歩的な質問

Posted: 2013年1月07日(月) 16:00
by エレジー
以前この掲示板でゲームプログラミングについて質問させていただいていた者ですが、長い間挫折していました。
何が原因かと考えたところ、ゲームプログラミング以前にC/C++に関しての知識がしっかりしていないということが分かったので、勉強しなおしています。
これから当面はC/C++に関する超初歩的な質問をさせていただきたいと思いますのでよろしくお願いいたします。

件名と関係のない内容が長くなってしまい申し訳ないです。
ここから質問です。
printf関数の引数に*がつくときとつかないときの違いがよく分かりません。

コード:

	int num = 10;
	int* p = #

	printf( "%d\n", *p );
のようなときには引数に*をつけるのに

コード:

	char *str = "abc";

	printf( "%s\n", str );

	return 0;
のようなときは引数に*をつけません。
上のソースコードで*をつけなければ002DF7F8のようなポインタ自体の値が出力されてしまいます。
下のソースコードのprintf関数の引数のstrは文字列"abc"の先頭のアドレスを指し示すポインタとして扱われるはずなので、どちらのprintf関数の引数もポインタ変数であることは同じなのにつけるつけないの違いがある理由が分かりません。
ポインタについて理解しきれていないのかもしれません。

なんとなくで文字列のときにつけないんだなぁとは分かるのですが、理由を知りたいのでよろしくお願いします。

Re: ポインタとprintf関数についての初歩的な質問

Posted: 2013年1月07日(月) 16:19
by beatle
%dは対応する引数をint値だと思って出力する書式指定子です
%sは対応する引数を文字列へのアドレスだと思って出力する書式指定子です

関数の引数にint値はそのまま渡せますが、文字列自体をそのまま渡すことはできませんので、仕方なく文字列の先頭がある場所を数値化して渡します。

もし、%dが「対応する引数をint値へのアドレスだと思って出力する書式指定子」だったら、
printf( "%d\n", p );
と、アスタリスクを付けないで渡せば、お望みの整数値「10」を表示することができます。
しかしprintfの仕様はそうではなく、%dは対応する引数をint値そのものだと思って出力する書式指定子ですから、アスタリスクを付けない場合はアドレス値(の整数表現)が表示されます。

Re: ポインタとprintf関数についての初歩的な質問

Posted: 2013年1月07日(月) 16:22
by softya(ソフト屋)
C言語において文字列は、char型ポインタで扱うという規格がまずあります。
あとコンパイラとしての現実的な問題として、数値はCPUレジスタに収まるが不定長である文字列はCPUレジスタに収めることが出来ないと言う問題から関数間の受け渡しにはポインタ以外は考えられないと側面があります。
なので、printfの仕様として%s書式は文字列(char型ポインタ)で、それ以外は数値として引数で受け渡しという仕組みになっています。

Re: ポインタとprintf関数についての初歩的な質問

Posted: 2013年1月07日(月) 16:47
by エレジー
%dと%sでそもそも引数にするべきものが違うんですね。

ありがとうございました。
理解できました。