====== printf 実践編 ====== ===== 基本と整数編 ===== ==== 文字列のみ表示 ==== printfを使うには、stdio.hをインクルードする。 #include printfの基本形、print("文字列リテラル");の形\\ 補足:改行はバックスラッシュn ('\n')を使う。\\ 文字列"A string is printed"を表示したいときは、\\ printf("A string is printed"); となります。最後に改行を入れたいときは\\ printf("A string is printed\n"); です。\\ ==== 整数値のみ表示 ==== int val = 250; /* valの値を%dで表示して改行 */ printf("%d\n", val); valの値が表示されて、改行されます。\\ ==== 文字列中に整数の変数値を表示 ==== "valの値は○○です。"のように文章中のある部分を変数の値に変換して表示します。\\ 文章の途中に「変換指定子」%dを仕込むだけです。\\ int val = 250; /* 文章中のある部分を変数の値に変換して表示 */ printf("valの値は%dです\n", val); ==== %dの表示桁数を指定とゼロ埋め ==== __%[桁数]d__ で、何桁表示するかを指定できる。\\ __%0[桁数]d__ で、不足桁数を0で埋められます。 int val = 250; printf("%6d\n", val); // " 250⏎" printf("%06d\n", val); // "000250⏎" ==== %dの表示桁数をまさかの左詰め ==== __%-[桁数]d__ で、%dの桁数指定をしたときに、左詰めで表示します。\\ int val = 250; printf("%6d\n", val); //デフォルトは右寄せ " 250⏎" printf("%-6d\n", val); //    左寄せ指定 "250 ⏎" ==== 10進数表示%dに明示的に符号を表示させる ==== __%+[桁数]d__ で、%dの桁数指定をしたときに、符号付で表示します。\\ 右寄せや桁数表示、符号付き指定などは、ほかの表示形式でも使えるものが多いです。(一部不可)\\ __桁数指定では、符号も1文字として数えられるので注意されたし!__\\ 自分でいろいろ試して確認してみましょう!\\ int val = 250; printf("%6d\n", val); //" 250⏎" printf("%+6d\n", val); //" +250⏎" printf("%+6d\n", -val); //" -250⏎" ==== 整数の値を、8進数,16進数で表示 ==== __%[桁数]o__ で、指定した値や変数を8進数で表示できます。残念ながら2進数は有りません。\\ __%[桁数]x__ で、指定した値や変数を16進数で表示できます。\\ __%#[桁数]o__ で、指定した値や変数を8進プレフィクス付きで8進数で表示 例:053\\ __%#[桁数]x__ で、指定した値や変数を16進プレフィクス付きで16進数で表示 例:0xff\\ __%#[桁数]X__ xを大文字にすると、A~Fが大文字で表示される 例:0xFF\\ ただし、8進、16進表記では、\\ __桁数指定では、プレフィックスも表示文字数として数えられるので注意されたし!__\\ int val = 250; printf("%6o\n", val); //" 372⏎" printf("%6x\n", val); //" fa⏎" printf("%6X\n", val); //" FA⏎" printf("%#6o\n", val); //" 0372⏎" printf("%#6x\n", val); //" 0xfa⏎" printf("%#6X\n", val); //" 0xFA⏎" printf("%#06o\n", val); //"000372⏎" printf("%#06x\n", val); //"0x00fa⏎" printf("%#06X\n", val); //"0x00FA⏎" ---- ===== 実数編 ===== 実数(本来は実数ではなく浮動小数点数)は単精度(float)と(double)倍精度が存在する。\\ ==== floatとdouleの表示の基本 ==== floatの変数や値を表示したいときは変換指定子として %f を指定する。\\ doubleの変数や値を表示したいときは変換指定子として%lf を指定する。\\ (fはfloat, lfはlong floatの略っぽい。)\\ __デフォルトではどちらも、小数点以下6桁表示のみ指定されている。__\\ float val1 = 3.14159265359; //医師異国に向こう //医師異国に、婿さん号泣 double val2 = 3141.59265359; printf("val1 : %f \n", val1); printf("val2 : %lf \n", val2); ==== floatとdouleの表示(桁数とか符号とか) ==== 整数の時と同様に、桁数指定もできます。\\ 小数点表示の場合はデフォルトでは小数点以下6桁表示のみ指定されています。\\ 小数点以下の表示桁数を変更するには、以下のように指定します。\\ __%.[小数点以下の桁数]f__ \\ 例:%.2f %.6lf など\\ ただし、__桁数指定では、符号も1文字、小数点も1文字として数えられるので注意されたし!__\\ 指定桁数よりも、変数の値の桁が少ない時は(%.5fを指定したのに、変換値が3.1だった時)などは正しい値が表示されないことがある。\\ 指定桁数よりも、変数の桁の方が 多い時は(%.2fを指定したのに、変換値が3.141592などの時)は小数点以下3桁目を四捨五入した値で小数点以下2桁まで表示)\\ float val1 = 3.14159265359; double val2 = 3141.59265359; printf("val1->%.2f\n", val1); // val1->3.14 printf("val2->%.2lf\n", val2); // val2->3141.59 === 全体の文字数の設定 === 桁数指定するときに、数値全体の表示幅も指定できます。\\ __%[全体の表示幅].[小数点以下の桁数]f__ \\ 例:%3.2f %11.6lf など\\ ただし、__桁数指定では、符号も1文字、小数点も1文字として数えられるので注意されたし!__\\ == %4.2fの場合 == %4.2fなので、全体幅4のうち小数点以下2桁で表示、と読める。\\ 全体の表示幅4 |〇〇〇〇|\\ 全体4のうち .2 なので 小数点以下2桁分 ✕部分 |〇〇✕✕|\\ 全体4のうち       小数点表示1桁分 .部分 |〇.✕✕|\\ 全体4のうち      整数部が残り1桁分 〇部分 |〇.✕✕|\\ == %11.6fの場合== %11.6fなので、全体幅11のうち小数点以下6桁で表示、と読める。\\ 全体の表示幅11 |〇〇〇〇〇〇〇〇〇〇〇|\\ 全体4のうち .6 なので 小数点以下6桁分  ×部分 |〇〇〇〇〇✕✕✕✕✕✕|\\ 全体4のうち       小数点表示1桁分 .部分 |〇〇〇〇.✕✕✕✕✕✕|\\ 全体4のうち      整数部が残り4桁分 〇部分 |〇〇〇〇.✕✕✕✕✕✕|\\ float val1 = 3.14159265359; double val2 = 3141.59265359; printf("val1->%4.2f\n", val1); // val1->3.14 printf("val2->%11.6f\n", val2); // val2->3141.592654 さらに、__符号表記も必要な場合は、符号も表示文字数に含まれる__のでさらに注意が必要である。\\ == %+5.1fの場合 == %5.1fなので、全体幅5のうち小数点以下1桁で符号付き表示、と読める。\\ 全体の表示幅4 |〇〇〇〇〇|\\ 全体5のうち .1 なので 小数点以下1桁分 ✕部分 |〇〇〇〇✕|\\ 全体5のうち       小数点表示1桁分 .部分 |〇〇〇.✕|\\ 全体5のうち      整数部が残り3桁分 〇部分 |〇〇〇.✕|\\ 整数部分が、3桁より少ない場合は右詰めで表示される。そのうち1桁が符号として使われる。\\ 例)\\ printf("%5.1f\n", 3.14); // +3.1⏎ == %+12.3fの場合== %12.3fなので、全体幅12のうち小数点以下3桁で符号付きで表示、と読める。\\ 全体の表示幅12 |〇〇〇〇〇〇〇〇〇〇〇〇|\\ 全体12のうち .3 なので 小数点以下3桁分 ✕部分 |〇〇〇〇〇〇〇〇〇✕✕✕|\\ 全体12のうち       小数点表示1桁分 .部分 |〇〇〇〇〇〇〇〇.✕✕✕|\\ 全体12のうち      整数部が残り8桁分 〇部分 |〇〇〇〇〇〇〇〇.✕✕✕|\\ 整数部分が、8桁より少ない場合は右詰めで表示される。そのうち1桁が符号として使われる。\\ 例)\\ printf("%12.3f\n", 3141.5926535); // +3141.593⏎ ==== 指数形(科学的記数法)表示 ==== 数値を仮数と指数で表現する方法で表示する。\\ 指数は$10^n$が使われるが、10進数の数字と区別がつかなくなるので、\\ 表示上わかりやすいように$e+n$や$e-n$が使われる。eが10の何乗を表している。\\ 仮数部は、%fと同じように、整数部と小数部の桁数指定や符号の指定ができる。\\ (デフォルトは同様に小数点以下6桁)\\ printf("%e\n", 3.14); //3.140000e+00 printf("%e\n", 3141.592659); //3.141593e+03 ==== 文字と文字列(ラスボス) ==== C言語における、文字と、文字列については[[game-engineer:classes:2021:game-programing-1:clang:clang-riteral|文字と文字列]]を参照してください。\\ ('a'は文字、"string"は文字列だよね?)\\ ==== 文字(char型)の表示 ==== 文字を1文字表示するには,変換指定子として __%c__を使う。\\ 1文字を、1文字で表示するので特にオプションなどはない。\\ char c = 'b'; char c2 = '\''; //記号や制御文字(エスケープシーケンス(改行とかタブ))など、 //表示できなさそうな文字を表示するときはバックスラッシュを付ける char c3 = 'z'; printf("%c", c); //b printf("%c", c2); //' printf("%c", c3); //z //b'z が表示される printf("%c%c%c",c ,c2 ,c3); //でも同じ結果 === 文字の配列 === Cには文字列型がないので、char型の配列を使って文字列を表現する。\\ char *str1 = "monja"; //ポインタを使ってchar配列を宣言する方法 char str2[] = "yaki"; //配列形式で宣言  配列の要素数はいくつでしょう? これらは、内部で文字配列+終端文字'\0'に変換されるルールでしたね。\\ char *str1 = "monja"; // = { 'm', 'o', 'n', 'j', 'a', '\0'}; char str2[] = "yaki"; // = { 'y', 'a', 'k', 'i', '\0'}; これらを表示するためには、終端文字が現れるまで1文字ずつ文字を表示すればよいです。\\ int i = 0; while(1) //C言語はtrueが使えない。。。 { if(str1[i] != '\0'){ printf("%c", str1[i]); i++; } else break; } //monjaと表示される この方法の良いところは、'\0'が設定されていてもいなくても、文字の配列でしかないので配列サイズさえ分かっていれば、\\ 通常の数値の配列と扱いが変わらないのでいろいろ応用が利くところ\\ ==== 文字列用の変換指定子 ==== 文字列を表す文字配列(文字の配列+'\0')を、うまく表示するための変換指定子があります。\\ __%s__です。変換値として__文字列を表す配列の先頭アドレス__を指定します。\\ char *str1 = "monja"; // = { 'm', 'o', 'n', 'j', 'a', '\0'}; char str2[] = "yaki"; // = { 'y', 'a', 'k', 'i', '\0'}; printf("%s%s\n", str1, str2); //monjayaki と表示される。 ==== %sで表示幅指定する ==== 文字列に表示幅指定をしてみる。右寄せ左寄せもできる\\ __%[表示幅]s__  右寄せ表示幅指定\\ __%-[表示幅]s__ 左寄せ表示幅指定\\ char *str1 = "monja"; char str2[] = "yaki"; printf("%10s\n", str1); // monjaと表示される。 printf("%-10s\n", str1); //monja と表示される。 === ちょっと補足(文字列の途中から表示する) === %sの変換値としては変数の先頭アドレスを指定と書いたが、正確には__表示する先頭のアドレスである__。\\ char *str1 = "monja"; // = { 'm', 'o', 'n', 'j', 'a', '\0'}; char str2[] = "yaki"; // = { 'y', 'a', 'k', 'i', '\0'}; char str3[] = {'m', 'o', 'n', 'j', 'a', '\0', 'y', 'a', 'k', 'i', '\0'}; //1つの配列に文字列をいっぱい詰め込むこともできる printf("%s\n", str1+2); //ja と表示される。 printf("%s\n", str3); //monja printf("%s\n", str3+6); //yaki