C Language
フォーマットされた入力/出力
サーチ…
オブジェクトへのポインタの値の出力
関数ポインターではなくオブジェクトへのポインターの値を出力するには、 p
変換指定子を使用します。印刷するように定義されvoid
そうでないの値をプリントアウトするために、唯一の-pointersをvoid
、それがために明示的に変換する必要があります(「*キャスト」)-pointer void*
。
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
int main(void)
{
int i;
int * p = &i;
printf("The address of i is %p.\n", (void*) p);
return EXIT_SUCCESS;
}
<inttypes.h>
とuintptr_t
C99以降でポインタを印刷する別の方法は、 uintptr_t
型と<inttypes.h>
マクロを使用します。
#include <inttypes.h> /* for uintptr_t and PRIXPTR */
#include <stdio.h> /* for printf() */
int main(void)
{
int i;
int *p = &i;
printf("The address of i is 0x%" PRIXPTR ".\n", (uintptr_t)p);
return 0;
}
理論的には、整数に変換されたポインタを保持できる整数型は存在しない可能性があります( uintptr_t
型が存在しない可能性があります)。実際には、それは存在します。関数へのポインタは、 uintptr_t
型に変換可能である必要はありません。
場合はuintptr_t
タイプが存在し、そうintptr_t
タイプは。しかし、なぜアドレスを符号付き整数として扱いたいのかは明らかではありません。
プレスタンダード・ヒストリー:
K&R-C時代のC89以前は、 void*
型(ヘッダ<stdlib.h>
もプロトタイプもなくint main(void)
表記もありませんでした)なので、ポインタはlong unsigned int
にキャストされ、 lx
長さ修飾子/変換指定子。
以下の例は情報提供のためのものです。今日ではこれは無効なコードであり、悪名高い未定義の振る舞いを引き起こす可能性があります。
#include <stdio.h> /* optional in pre-standard C - for printf() */
int main()
{
int i;
int *p = &i;
printf("The address of i is 0x%lx.\n", (long unsigned) p);
return 0;
}
2つのポインタの値の差をオブジェクトに出力する
オブジェクトへの2つのポインタの値を減算すると、符号付き整数* 1が得られます。したがって、少なくとも d
変換指定子を使用して印刷されます。
C99 <stddef.h>
はptrdiff_t
型を定義しているので、このような "ポインタ差"を保持できるだけの型があることを確認する。 ptrdiff_t
を印刷するには、 t
length修飾子を使用します。
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
#include <stddef.h> /* for ptrdiff_t */
int main(void)
{
int a[2];
int * p1 = &a[0], * p2 = &a[1];
ptrdiff_t pd = p2 - p1;
printf("p1 = %p\n", (void*) p1);
printf("p2 = %p\n", (void*) p2);
printf("p2 - p1 = %td\n", pd);
return EXIT_SUCCESS;
}
結果は次のようになります。
p1 = 0x7fff6679f430
p2 = 0x7fff6679f434
p2 - p1 = 1
差の結果として得られる値は、ポインタを減算したポイントの型のサイズ、ここではint
でスケールされることに注意してください。この例のint
のサイズは4です。
* 1減算する2つのポインタが同じオブジェクトを指していない場合、その動作は未定義です。
印刷用の変換指定子
変換指定子 | 引数の種類 | 説明 |
---|---|---|
i 、 d | int | 10進数を出力する |
u | 符号なし整数 | 10進数を出力する |
o | 符号なし整数 | 8進数を出力する |
x | 符号なし整数 | 16進数、小文字を出力します。 |
X | 符号なし整数 | 16進数、大文字を出力します。 |
f | ダブル | 精度が指定されていない場合、デフォルトの精度6でfloatを出力します(特殊な数値nan とinf またはinfinity 小文字が使用されinfinity ) |
F | ダブル | 精度が指定されていない場合は、デフォルトの精度6でfloatを出力します(特殊な数値NAN とINF またはINFINITY 大文字が使用されます) |
e | ダブル | 仮数/指数を使用して科学的表記を使用して、精度が指定されていない場合はデフォルトの精度6でfloatを出力します。小文字の指数と特殊な数字 |
E | ダブル | 仮数/指数を使用して科学的表記を使用して、精度が指定されていない場合はデフォルトの精度6でfloatを出力します。大文字の指数と特殊な数字 |
g | ダブル | f またはe いずれかを使用します[以下を参照] |
G | ダブル | F またはE いずれかを使用します[以下を参照] |
a | ダブル | 16進数、小文字を出力します。 |
A | ダブル | 16進数、大文字を出力します。 |
c | チャー | 1文字を出力する |
s | char * | 文字列をNUL 終端文字まで出力するか、指定されている場合は精度で指定された長さに切り捨てる |
p | void * | void -pointerの値を出力しvoid 。非void -pointerは明示的にvoid* 変換(キャスト)する必要がありvoid* 。オブジェクトポインタへのポインタ、関数ポインタではないポインタ |
% | 該当なし | % 文字を出力する |
n | int * | 今までに出力されたバイト数をint 示されたint 書き込みます。 |
ISO / IEC 9899:2011§7.21.6.1¶7に従って、長さ修飾子を%n
適用できることに注意してください(例: %hhn
は、次のn
変換指定子がsigned char
引数へのポインタに適用されることを示します)。
浮動小数点数の変換は、デフォルトの宣言規則のためにfloat
型とdouble
型に適用されます。§6.5.2.2関数呼び出し、¶7 関数プロトタイプ宣言子の省略記号は、最後に宣言されたパラメータの後で引数型変換を停止させます。既定の引数のプロモーションは、末尾の引数に対して実行されます。 )したがって、参照される変数がfloat
型であっても、 printf()
などの関数はdouble
値しか渡されません。
g
とG
形式では、 e
とf
(またはE
とF
)表記法の選択は、C標準とprintf()
POSIX仕様で文書化されています。
浮動小数点数を表すdouble引数は、変換された値と精度に応じて、
f
またはe
形式(またはG
変換指定子の場合はF
またはE
形式)に変換されます。 0以外の場合は精度をP
、精度が省略されている場合は6、精度がゼロの場合は1をP
とします。次に、スタイルE
変換がX
指数を持つ場合、
- P> X> = -4の場合、変換はスタイル
f
(またはF
)および精度P - (X+1)
ます。- それ以外の場合、変換はスタイル
e
(またはE
)と精度P - 1
行わなければならない。
最後に、 '#'フラグが使用されていない限り、末尾のゼロは結果の小数部から削除され、小数部が残っていなければ小数点文字は削除されます。
printf()関数
<stdio.h>
を<stdio.h>
アクセスすると、関数printf()
は、Cのコンソールにテキストを出力するために使用される主なツールです。
printf("Hello world!");
// Hello world!
通常のフォーマットされていない文字配列は、かっこの間に直接配置することで、単独で印刷できます。
printf("%d is the answer to life, the universe, and everything.", 42);
// 42 is the answer to life, the universe, and everything.
int x = 3;
char y = 'Z';
char* z = "Example";
printf("Int: %d, Char: %c, String: %s", x, y, z);
// Int: 3, Char: Z, String: Example
あるいは、整数、浮動小数点数、文字などは、エスケープ文字%
を使用して、フォーマットを表す文字または一連の文字( フォーマット指定子)を使用して印刷できます 。
関数printf()
への追加引数はすべてコンマで区切られ、これらの引数は書式指定子と同じ順序でなければなりません。追加の引数は無視されますが、間違って型指定された引数または引数の欠如はエラーまたは未定義の動作を引き起こします。各引数は、リテラル値または変数のいずれかです。
正常に実行された後、印刷された文字数がint
型で返されます。それ以外の場合、失敗は負の値を返します。
長さ修飾子
C99とC11の標準では、 printf()
次の長さ修飾子を指定しています。その意味は次のとおりです。
モディファイア | 変更する | に適用されます |
---|---|---|
hh | d、i、o、u、x、またはX | char 、 signed char またはunsigned char |
h | d、i、o、u、x、またはX | short int またはunsigned short int |
l | d、i、o、u、x、またはX | long int またはunsigned long int |
l | a、A、e、E、f、F、g、またはG | double ( scanf() との互換性のため、C90では未定義) |
II | d、i、o、u、x、またはX | long long int またはunsigned long long int |
j | d、i、o、u、x、またはX | intmax_t またはuintmax_t |
z | d、i、o、u、x、またはX | size_t または対応する符号付き型(POSIXではssize_t ) |
t | d、i、o、u、x、またはX | ptrdiff_t または対応する符号なし整数型 |
L | a、A、e、E、f、F、g、またはG | long double |
length修飾子が上記の指定以外の変換指定子とともに表示される場合、その動作は未定義です。
Microsoftはいくつかの異なる長さ修飾子を指定し、明示的にhh
、 j
、 z
、またはt
サポートしていません。
モディファイア | 変更する | に適用されます |
---|---|---|
I32 | d、i、o、x、またはX | __int32 |
I32 | o、u、x、またはX | unsigned __int32 |
I64 | d、i、o、x、またはX | __int64 |
I64 | o、u、x、またはX | unsigned __int64 |
私 | d、i、o、x、またはX | ptrdiff_t (すなわち、 __int32 32ビットプラットフォーム上で、 __int64 64ビットプラットフォーム上で) |
私 | o、u、x、またはX | size_t (すなわち、 unsigned __int32 32ビットプラットフォーム上で、 unsigned __int64 64ビットプラットフォーム上で) |
lまたはL | a、A、e、E、f、g、またはG | long double (がビジュアルC ++では、 long double 特殊タイプであり、それは同じ内部表現有するdouble )。 |
lまたはw | cまたはC | printf 関数とwprintf 関数を持つワイド文字。 ( lc 、 lC 、 wc 又はwC 型指定子は、と同義であるC でprintf 関数とを用いてc でwprintf 機能)。 |
lまたはw | s、S、またはZ | printf 関数とwprintf 関数を持つワイド文字列。 ( ls 、 lS 、 ws またはwS タイプ指定子と同義であるS でprintf 関数とを用いてs でwprintf 機能)。 |
C
、 S
、 Z
変換指定子とI
、 I32
、 I64
、およびw
長さ修飾子は、Microsoftの拡張機能です。治療l
ための変性剤としてlong double
ではなくdouble
、あなたがない限り、違いを見つけるためにハード押されるでしょうが、標準と異なるlong double
異なる表現があるdouble
。
印刷フォーマットフラグ
Cの標準(C11とC99も)では、 printf()
次のフラグを定義しています。
旗 | コンバージョン | 意味 |
---|---|---|
- | すべて | 変換の結果は、フィールド内で左詰めにしなければならない。このフラグが指定されていない場合、変換は右詰めになります。 |
+ | 符号付き数値 | 符号付き変換の結果は、常に符号( '+'または ' - ')で始まります。このフラグが指定されていない場合は、負の値が変換されたときにのみ変換が開始されます。 |
<space> | 符号付き数値 | 符号付き変換の最初の文字が符号でない場合、または符号付き変換の結果が文字でない場合は、 <space> が結果の前に付加されます。つまり、 <space> フラグと「 + 」フラグの両方が表示された場合、 <space> フラグは無視されます。 |
# | すべて | 値を代替フォームに変換することを指定します。 o 変換の場合、必要に応じて、結果の最初の桁を強制的にゼロにする(値と精度が両方とも0で、1つの0が出力される場合)。 x またはX 変換指定子の場合、0でない結果には0x (または0X )が前置されます。以下のために、 a A 、 e 、 E 、 f 、 F 、 g 、およびG 変換指定子、結果は常に何の数字は基数文字に従わない場合でも、基数文字を含まなければなりません。このフラグがなければ、数字が続く場合にのみ、これらの変換結果に基数文字が表示されます。 g とG 変換指定子の場合、末尾のゼロは通常のように結果から削除してはならない。他の変換指定子の場合、動作は未定義です。 |
0 | 数値 | d、i、o、u、x、X、a、A、e、E、f、F、g、Gの変換指定子の場合、(記号または基数の表示に続く)先行ゼロを使用して、無限大またはNaNを変換する場合を除き、スペースパディングを実行するのではなく、幅を指定します。 '0'と ' - 'フラグが両方とも表示された場合、 '0'フラグは無視されます。 d、i、o、u、x、およびX変換指定子の場合、精度が指定されている場合、 '0'フラグは無視されます。 '「0」と「 <apostrophe> 」の両方のフラグが表示された場合、グループ化文字はゼロ埋めの前に挿入されます。他のコンバージョンの場合、動作は未定義です。 ⌫ |
これらのフラグは、 Microsoftでも同じ意味でサポートされています 。
printf()
のPOSIX仕様には次のものが追加されています。
旗 | コンバージョン | 意味 |
---|---|---|
' | i、d、u、f、F、g、G | 小数変換の結果の整数部分は、千単位のグループ化文字でフォーマットされなければならない。他のコンバージョンの場合、動作は未定義です。非金銭的グループ化文字が使用されます。 |