サーチ…


オブジェクトへのポインタの値の出力

関数ポインターではなくオブジェクトへのポインターの値を出力するには、 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;
}
C99

<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 C89

プレスタンダード・ヒストリー:

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修飾子を使用します。

C99
#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つのポインタが同じオブジェクトを指していない場合、その動作は未定義です。

印刷用の変換指定子

変換指定子引数の種類説明
id int 10進数を出力する
u 符号なし整数 10進数を出力する
o 符号なし整数 8進数を出力する
x 符号なし整数 16進数、小文字を出力します。
X 符号なし整数 16進数、大文字を出力します。
f ダブル精度が指定されていない場合、デフォルトの精度6でfloatを出力します(特殊な数値naninfまたはinfinity小文字が使用されinfinity
F ダブル精度が指定されていない場合は、デフォルトの精度6でfloatを出力します(特殊な数値NANINFまたは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値しか渡されません。

gG形式では、 ef (またはEF )表記法の選択は、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 charsigned 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 doublescanf()との互換性のため、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はいくつかの異なる長さ修飾子を指定し、明示的にhhjz 、または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関数を持つワイド文字。 ( lclCwc又はwC型指定子は、と同義であるCprintf関数とを用いてcwprintf機能)。
lまたはw s、S、またはZ printf関数とwprintf関数を持つワイド文字列。 ( lslSwsまたはwSタイプ指定子と同義であるSprintf関数とを用いてswprintf機能)。

CSZ変換指定子とII32I64 、および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 AeEfFg 、およびG変換指定子、結果は常に何の数字は基数文字に従わない場合でも、基数文字を含まなければなりません。このフラグがなければ、数字が続く場合にのみ、これらの変換結果に基数文字が表示されます。 gG変換指定子の場合、末尾のゼロは通常のように結果から削除してはならない。他の変換指定子の場合、動作は未定義です。
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 小数変換の結果の整数部分は、千単位のグループ化文字でフォーマットされなければならない。他のコンバージョンの場合、動作は未定義です。非金銭的グループ化文字が使用されます。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow