おぼえがき

過ちては則ち改むるにうんぬんかんぬん

printf関数と変換指定子について(C言語)

f:id:feci:20210810151051j:plain

C11

 

C11のprintf関数について。

#include <stdio.h>

void main() {
  printf("こんにちは。私の名前は%sです。 \n年齢は%d歳です。\n" , "山田たろう" , 45);
  printf("%f + %f = %f" , 1.5 , 3.5 , 1.5+3.5);
}

printf関数は、引数に指定された文字列や数値を出力する関数です。

 

 

上記のプログラムの出力結果は以下のようになっています。

 

出力結果

こんにちは。私の名前は山田たろうです。
年齢は45歳です。
1.500000+3.500000=5.000000

 

 

printf関数の定形は以下のようになっています。

 

データ型 main() {
    printf("第一引数" , 第二引数);
}

 

データ型の部分にはCのデータ型の種類が入ります。

なお、この部分は記入しなくてもprintf関数は正常に動作します。

 

main() はメイン関数の宣言です。

データ型を指定してメイン関数を宣言してから処理の内容をブレイス(波括弧)で囲むことで、ブレイス内の関数を実行することができます。

 

printf関数の第一引数には、文字列や数値や変換指定子やエスケープシーケンスを記入します。

この関数の第一引数はダブルクオーテーションで囲まないとprintf関数は正常に動作しません。

 

第二引数には第一引数で指定した変換指定子に対応した値を、1つずつカンマで区切りながら指定していきます。

printf関数の第二引数に記述する値はすべて、その値のデータ型に合わせたルールで記述しなければいけません。

これについては、下記の変換指定子の部分を参照してください。

 

なお、この際の引数を記述する順番は完全に固定です。

これはPythonでいうところの位置引数みたいな感じになっています。

 

なので変換指定子の順番と第二引数の記述の順番(位置)がまちがっていると、printf関数は正常に動作しません。

 

またprintf関数の第二引数は、文字列はダブルクオーテーションで囲う必要があります。

しかし数値や変数や計算式の場合は、値を記号で囲ってはいけません。

 

 

●変換指定子について。

 

printf関数の第位置引数内にある%sなどの表記は変換指定子と呼ばれます。

変換指定子には特定のデータ型があり、第二引数に指定した値と変換指定子の型がマッチしていなければ、printf関数は正常に動作しません。

 

 

変換指定子には以下のようなものがあります。

 

%c   文字(1文字)が入る(char型)
%s   文字列が入る(char型)

%hd   16bit(半分の精度)の10進数が入る(short int型)
%d   32bitの10進数が入る(int型)
%ld  64bit(倍精度)の10進数が入る(long int型)

%hu   16bitの符号なし10進数が入る(unsigned short int型)
%u   32bitの符号なし10進数が入る(unsigned int型)

%lu  64bitの符号なし10進数が入る(unsigned long int型)

%o   符号なし8進数が入る(int型)
%x   符号なし16進数(10~15は'a'~'f'表示)が入る(int型)
%X   符号なし16進数(10~15は'A'~'F'表示)が入る(int型)

%f    32bitの単精度浮動小数点(実数)が入る(float型)
%lf   64bitの倍精度浮動小数点が入る(double型)

 

 

上で少し触れたデータ型に合わせた値の記述ルールについて解説します。

 

char型(文字)の値はシングルクオーテーションで囲わなければいけません。

またchar型(文字列)の値は、ダブルクオーテーションで囲わなければいけません。

 

厳密にいえばCには文字列型というデータ型は存在しないらしいのですが、Cは文字列をchar型の配列として処理しているらしいです。

このときの配列の最後にはNULL文字(\0)が強制的に付与されているらしいので、表したい文字列の長さ+1の値がブラケット内に必要になります。

 

例:char x[10]で変数x内の0~9番目までの値を文字列として処理。10を指定しているので、x内の文字の数に関係なくこの場合の9番目の文字は\0で固定となる。

 

というわけなので、このブログでは今後も文字列のデータ型はchar[]型ということにして話を進めていきます。

 

 

閑話休題

 

ちなみにchar型でいうところの文字には、ひらがなやカタカナや漢字は該当しません。

半角大文字小文字の英数字のみが、ここでいう文字(char型)に該当します。

 

int型は小数点のない整数です。

float型は小数点付きの整数(有効桁数7桁の実数)です。

 

小数点付きの実数のお尻にfまたはFを記述すると、Cはその値をfloat型として認識します。

小数点付きの実数のお尻にfまたはFの記述がない場合は、おそらくCはその値をdouble型として認識してます。

 

整数の頭に0をつけると、Cはその値を8進数として認識します(int型)。

また整数の頭に0xをつけると、Cはその値を16進数として認識します(int型)。

 

16進数は10から15までの値をそれぞれ’a’、’b’、’c’、’d’、’e’、’f’と表示します。

変換指定子が%xなら小文字で表示されますし、%Xなら大文字で表示されます。

 

16進数の頭につくことのある0Xは、10進数と16進数を見分けるための記号です。

10は10進数の10ですし、0x10は16進数の16ということになります。

hも0xと同様の16進数を見分けるための表示です。

0xは16進数の頭に付けますが、hは16進数のお尻に付けます。

 

また、整数のお尻にuまたはUをつけると、Cはその値を符号なし整数として認識します(unsigned int型)。

整数のお尻にlまたはLをつけると、Cはその値をlong型の整数として認識します(long int型)。

 

ちなみにlong型整数の格納できる値は、通常の整数(32bit)の倍の64bitです。

逆にshort型整数の格納できる値は、通常の整数(32bit)の半分の16bitです。

 

 

閑話休題

各データ型に合わせた値の記述ルールの解説に戻ります。

 

int型やfloat型の値は、クオーテーション記号で囲ってはいけません。

またint型やfloat型の値と算術演算子を使った演算(計算)処理を記述する場合も、その値をクオーテーション記号で囲ってはいけません。

 

このデータ型に合わせた値の記述ルールは、printf関数の第二引数の記述ルールと完全に一致しています。

しかし第一引数については、このルールは適用されません。

 

printf関数の第一引数に記述する値は、すべてダブルクオーテーションで囲う必要があります。

 

 

以上です。