printfを使ってみようズ

C言語ではconsole画面(コマンドプロンプトとか)に計算結果を出力するために,printf関数を使います(printfunction 関数だと関数関数になってるよね)
printfを使うためには以下のようにします。

includeと一番簡単なつかいかた

printf関数はstdio.hというヘッダファイルに宣言してあります。
これらは、C言語の標準入出力関数をまとめたもので、様々な便利な関数がパックされたヘッダファイルです。
(本当は、ライブラリファイル(.obj)がリンクされているんだけど、その辺の仕組みはまたあとで)
それではサンプル。

#include <stdio.h>
/* stdio.hをインクルード */
 
/*
一番簡単なprintfを使ったソースコード
ちなみにC言語のコメント文はこの形式だけである。
//このような1行コメントは使える環境と使えない環境がある。
注意されたい。
*/
 
/* 引数がない時は引数リストに(void)と書くのはC++と違うので注意 */
int main(void) {
 
  /* 授業でやったprintf(文字列); の形式 */
  printf("Hello World\n");
  /* 文字列とは "で囲まれた文字列" の事だよ */
  /* '\n' (¥n)は改行 */
 
	return 0;
}

実行結果

Hello World⏎

C言語には文字列型が存在しません。(厳密にはC++にも存在しませんが。。。)
なので、昔習った文字型配列を使って文字列を表現します。(文字列参考)
文字は、char型(=アスキーコードの番号=整数値)なので、文字配列は以下のような形になります。

char str[5] = {'a', 'b', 'c', 'd', '\0'};

又は、以下のように初期化できます。

char str[5] = "abcd";

この文字配列(≒文字列)をprintfで表示するには以下のようにする。

char str[5] = "abcd";
 
printf("文字列は%sです\n", str);
/* %sで文字列表示を指示し、表示する文字列の先頭アドレスを指定する */

このように、printf関数では、引数の前半に“書式指定”、後半に書式指定で指定された書式指定子で値を表示する変数リストを並べる。

printf(“書式指定”, var1, var2, var3…);

書式指定は、表示したい文字列と、書式指定子の組み合わせで書く。
書式指定子とは、どの変数の値をどんなフォーマットで表示するかを指定する文字列である。

Fig. 1: 書式制御文字列と書式制御指定子と変数の変換

よく使うやつ

書式指定子 対応の型 内容
%d int 整数値を10進表示で出力
%f float 実数値を固定小数点表示で出力
%lf double 倍精度実数値を固定小数点表示で出力
%s char *, char [] 文字配列を文字列として出力
%c char ASCIIコード値を対応する1文字で表示

あまり使わないけど、試験に出る奴

書式指定子 対応の型 内容
%u unsigned int 符号なし10進数表記で表示
%o int, unsigned int 整数を8進数表記で表示
%x int, unsigned int 整数を16進数表記で表示
%e float 実数を仮数+指数表記で表示
%g float %fか%eの適切そうな方で表示
%ld long longを10進数表記で表示(long decimalの略)
%lu unsigned long unsigned longを10進数表記で表示(long unsigned)
%lo long, unsigned long longを8進数表記で表示
%lx long, unsigned long longを16進数表記で表示

フォーマット指定サンプル

それでは、printf+フォーマット指定の超基本的なサンプルを見ていきましょう

ソースコード
#include <stdio.h>
 
int main(void) {
    int n = 10;
 
    printf("nの値は %d です\n", n);
 
    return 0;
}

出力
nの値は 10 です⏎

書式制御文字列には複数の制御指定子を混在、存在させることができる。
その場合、書式指定子の数と、変換する変数、値の数は同じでなければならない。
また、指定した書式指定子に適切な型(値)を持った変数を指定しなければならない。

Fig. 2: 複数の制御指定子と同数の表示用変数
ソースコード
char c = 'a';
int int_c = (int)c; /* 'a'をcharからintに変換 */
print("%cのASCII CODEは10進数では%d,16進数では%xである\n",  c, int_c, int_c);
printf("%c%c%c%c",c,c,c,c);
ソースコード
/* ここからはいらんところは省略 */
int n = 4029;
 
printf("nの値は\n 10進数で%d\n  8進数で%o\n 16進数で%x\nです\n", n, n, n);

出力
nの値は⏎
 10進数で4029⏎
  8進数で7675⏎
 16進数でfbd⏎
です⏎

ちなみに%xは大文字バージョン%Xもある。xを大文字にすると16進表記の時にアルファベットが大文字で表示される。

ソースコード
int n = 4029;
 
printf("nの値は\n 10進数で%d\n  8進数で%o\n 16進数で%X\nです\n", n, n, n);

出力
nの値は⏎
 10進数で4029⏎
  8進数で7675⏎
 16進数でFBD⏎
です⏎

%fは固定小数点表示、%eは浮動小数点表記になります。
小数点以下は、デフォルトでは6桁表示される仕様になっているようです。
この表示桁数を任意に変更できるのですが、試験では頻出事項です。
後で、まとめて解説します。

ソースコード
  float ex = 2.7182818284590452353602;
 
  printf("e = %f ( %e ) \n", ex, ex);

出力
e = 2.718282 ( 2.718282e+00 ) ⏎

%lfは固定小数点表示、%eは浮動小数点表記になります。
小数点以下は、デフォルトでは6桁表示される仕様になっているようです。
デフォルトで使う場合は元のデータが、floatだったか、doubleだったかで使い分けるだけです。
どっちにしろ、小数点以下が何桁あってもデフォルトだと%f, %lfとも6桁しか表示しないので同意です。
小数点以下の桁数を増やしたときに、どこまでのけたを表示できるでしょうというのがfloatとdoubleで異なってくるので、
その型に合わせたものを使いましょう。ということになってきます。

ソースコード
  double ex = 2.7182818284590452353602;
 
  printf("e = %lf ( %e ) \n", ex, ex);

出力
e = 2.718282 ( 2.718282e+00 ) ⏎

#include <stdio.h>
 
int main(void) {
  /* 0x41は 'A'のASCIIコード65の16進数表記 */
  char c0 = 0x41;
  char c1 = 'b'; /* 'b'の値は10進数で98, 16進数で0x62 */
  int c2 = 'c';
 
  printf("0x41:%c\n 'b':%c\n 'c':%c\n", c0, c1, c2);
 
  return 0;
}

出力
0x41:A⏎
 'b':b⏎
 'c':c⏎

文字列と文字配列の違いに注意して使ってください。

文字型
char型のこと、中身は整数値
整数で文字1文字分のアスキーコード(最大8bit)を格納する型
文字配列
char型の配列のこと。
char ca[4] = {'a', '+', 'b', '='};
文字列
““で囲まれた文字列リテラルのこと
“The Cachter in the Rye”
文字列型
そんなもんはない。
仕方ないから文字列を文字配列+終端文字('\0')で表現する

繰り返しますが、%cは1文字だけ表示することに注意してください。


  int i = 0;
  char ca1[] = {'j', 'c', '-', '2', '1'}; /* ただのchar型の配列 */
  char ca2[] = "jc-21";                   /* 文字列型 */
  /* 
   こう書くと文字配列+'\0'で文字列を表す配列が自動で生成される。
   中身は {'j', 'c', '-', '2', '1', '\0'};  
  */
  /* char配列の中身を1文字ずつ表示 */
  for(i = 0; i < 5; i++){
		printf("ca1[%d]:%c\n", i, ca1[i]);
  }

これは、配列のデータがきちんと文字列を表現する形(charの配列の終わりに終端文字'\0'が入っている)になっているときに限り、
%sにその配列の先頭アドレスを渡すことで、文字列としてその配列を表示することができる。

  char str[] = "jc-21";                   /* 文字列型(厳密には違うよ) */
  char cstr[] = {'j', 'c', '-', '2', '1', '\0'}; /* ただのchar型の配列+'\0'でも文字列 */
 
  /* 先頭アドレス(=配列の名前)で指定された配列の中身を文字列として表示 */
  printf("str = %s\n", str);
  printf("cstr = %s\n", cstr);

次は、scanfの使い方の基本を見てみよう。

  • game-engineer/classes/2021/game-programing-1/clang/clang-printf.txt
  • 最終更新: 4年前
  • by root