ここから本文です

printfの処理について

nek********さん

2011/9/612:33:48

printfの処理について

整数型
int a=10;
printf("a=%d", a);

文字列型
char b="10";
print("b=%c", b);

printfの処理について。
整数型だとメモリのイメージができるのですが、文字列型だと複雑になりイメージができなくなりました。
strcpyのような処理がされて整数型のようになるとは、先ほどの回答を見る限り考えにくいです。

どう考えればいいのでしょうか。

補足すいません。
添付した画像が縮小されたみたいです。
http://bit.ly/qZiPYH です。

printf,char b,整数型,strcpy,int a,文字列,int2str

閲覧数:
375
回答数:
3
お礼:
500枚

違反報告

ベストアンサーに選ばれた回答

azu********さん

2011/9/614:20:34

別にむずかしいことはないと思いますが。

printf()は基本的に文字列を表示する関数です。文字列ならその表示開始アドレスが分かればいいのです。
そこでその開始アドレスを保持するポインタ変数が出発点になることを示す説明がなされています。


左の図は

整数型
int a=10; 。
printf("a=%c", a);

の説明ですね。ポインタ変数が入っているアドレスは100であり、変数の内容であるアドレスは200ですから、200を先頭アドレスとする文字列 "a=1"が表示されることになります。'='の後にある '1','0','\0'という文字は、int型変数 a に入っていた2進数を文字列に変換したものです。しかし、%sではなく、 %c でという指示にしたがって 先頭1文字だけが表示されます。


右の図は、上が char b="10";

下が print("b=%s", b); の説明ですね。

char b="10";
の場合、"10"は文字列ですから、その開始アドレスが200であり、その値を保持しているポインタ変数はアドレス100に入っているということを示しています。

printf()が表示する文字列の開始アドレスとして、アドレス400にあるポインタ変数にアドレス500が入ります。そこでアドレス500が指す'b'と'='を表示するわけですが、その次は %s ですから、それに対応するアドレスには文字ではなく、文字列を指すポインタ変数のアドレスが入っています。これは上で割り当てた"10"の開始位置を保持したポインタ変数のアドレス100です。アドレス100の内容は上でとった200です。そして、アドレス200からは上でとった文字列である"10"が入っています。そこで全体として、"b=10"が表示されることになります。

説明図では文字そのもののコードとアドレスが同じ1バイトというサイズになっており、それらの違いをどう判断しているのか不明ですが、あくまでイメージということでしょう。100という数は1バイトに入っている以上16進数ということはありえず10進数なのでしょう。ところが10進数の100は16進数では64であり、64という数字はJISコードの'd'を表すわけなので、文字なのかアドレス(あるいはあるアドレスからのオフセット)なのかの判断がつかないことになります。厳密に考える人にはおかしな説明をしていると取る人がいるかもしれません。

実際は表示についても、リストをたどってそのとき出くわした文字を順に表示するというのではなく、一旦出力用のバッファに入れてからまとめて表示しているはずです。

質問した人からのコメント

2011/9/7 14:38:38

理解を深めることができました。皆さん、ありがとうございました。

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

dak********さん

2011/9/614:53:47

printfが表示するのはあくまで文字列であって、文字列がそのまま整数型になっているわけではないです。

> print("b=%c", b);
%c は、引数を char型とみなして処理するというものですから、引数 bの値を、char型の数値として読み取り、内部で数値→文字列変換処理して出力しているだけです。

ところで、このとき引数bに格納されているものが何かといいますと、AsciiZ文字列"10"の格納アドレスを「charでキャストした値」が入っています。
>char b="10"
そもそも、こう表記した場合は通常はワーニングが出ますし。

そして文字列"10"の格納アドレスが、仮に 0x1234だったとしましょう。
インテル系でしたらデータは下位から若いアドレス順に並ぶので、bの値は 0x34になります。
結果、printf()は、キャラクターコード0x34である、'4'を一文字表示します。

スクリプト系などの型が(厳密では)ない言語でしたら、数値っぽい文字列は初めから数値として解釈してくれますので、あまり考えなくてもいいようになっているのですが、Cなどの場合は、データ型の指定は厳密に行う必要があります。
もっとも型を省略した場合は int型になり、char型は符号無しの8bit整数として扱われる、というのがK&R時代のお約束ではありますが。

久遠人さん

編集あり2011/9/619:17:25

printfの簡略化した実装。

整数型を数字文字列として表示する。

int2str(int i)
{
if(i == 0) return;
int2str(i / 10);
putchar(i % 10 + '0');
}
main()
{
int i = 123456;
if(i < 0) {
i *= -1;
putchar('-');
}
int2str(i);
}

文字列を表示する

main()
{
char *s = "123456";
for(;*s != '\0';s++) putchar(*s);
}

基本的にハードには文字列を一度に表示する機能は無い。
数字を直接表示する機能も無い。
数字は一つずつ文字に直して表示し、文字列も一文字ずつ表示するしかない。

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる