6

変更した printf 実装を作成していますが、これらの質問に対する答えがわかりません。

  1. ゼロはヌル文字列として機能しますか? (printf("%s", 0)許される?)

    0 はint. しかし、これはこの質問を促します:

  2. NULLnull 文字列として機能しますか? (printf("%s", NULL)許される?)

    NULL論理的には、ポインターを意味するため、はいにする必要があると思います。しかし、多くの実装には があるように見える#define NULL 0ので、実際にはそうではないかもしれません。どちらが正しい?

  3. ポインタ型を指す必要がありcharますか? (printf("%s", (void const *)"")許される?)

    タイプは問題ではないと思いますが、よくわかりません。

4

3 に答える 3

8

intケース 1 は、引数の型 ( ) が書式指定子 ( ) で必要な型と一致しないため、未定義の動作ですchar *

ケース 2 は、同じ理由で未定義の動作です。NULLは、値が 0 の任意の整数定数式、または にキャストされたそのような式として定義できます(void *)。これらのタイプはいずれもchar *ではないため、動作は未定義です。

ケース 3 は、同じ理由で未定義の動作です。""null で終わる文字配列 (文字列) への有効なポインターを生成しますが、それを にキャストするとconst void *、書式文字列に一致する適切な型がなくなります。したがって、動作は未定義です。

于 2012-08-31T21:18:25.907 に答える
0

問題なくコンパイルできると思いますが、動作は未定義です。

printfどのように機能し、なぜ安全でないと見なされるのか についての何か。printf1 つ (最初の 1 つ) だけが必要な場合は、指定した数の引数を取ります。すべての引数 (最初のパターンを除く) は、バイトの配列として扱われます。タイプなどはチェックしません。単純に印刷します。

0 byte文字列の出力は、 ('\0')が見つかるまで続くため、より複雑です。明確にするために、整数でテストしてみてください。ご存じのとおり、shortは 2 バイトの長さで、long4 であり、long long8 です。printf に印刷するように指示してlong2 shorts を渡すと、それらは 1 つとして扱われますlong。または、渡しlong longて print を指示した場合long、最初の 4 バイトが必要で、それらを印刷に使用します。

私のこれらの特定のケースでは、おそらく(テストしなかった)何も出力されませんが、未定義の動作と見なされます。'\0'これらの値が 0 でない場合、先頭にいくつかの非 sがある特定の値を渡すと、いくつかの文字が出力されることがあります。

それが役立つかどうかはよくわかりませんが、そう願っています。

于 2012-08-31T21:21:07.043 に答える
0

オンラインC11 ドラフトから:

7.21.6.1 fprintf 関数

...長さ修飾子が存在しない場合、引数は文字型の配列の最初の要素へのポインタになります
s280) 配列の文字は、終端のヌル文字まで (ただし、ヌル文字は含みません) 書き込まれます。精度が指定されている場合、そのバイト数を超えて書き込まれることはありません。精度が指定されていないか、配列のサイズより大きい場合、配列にはヌル文字が含まれます。 l
280) マルチバイト文字に対する特別な規定はありません。

char少なくとも 1 文字 (0 ターミネータ) を含む 配列の最初の要素へのポインタ以外のものは、未定義の動作を引き起こします。

独自の実装を構築している場合は、0 または NULL に対する独自の動作を確実に定義できます。

ああ、そして NULL の定義に関する限り:

6.3.2.3 ポインタ

...
3 値が 0 の整数定数式、または型 void * にキャストされたそのような式は、NULL ポインター定数と呼ばれます。66) null ポインター定数がポインター型に変換される場合、null ポインターと呼ばれる結果のポインターは、任意のオブジェクトまたは関数へのポインターと等しくないことが保証されます。
66) マクロ NULL は <stddef.h> (およびその他のヘッダー) で null ポインター定数として定義されます。7.19 を参照

基本的に、ポインター コンテキスト内の値が 0 の整数式はすべて NULL ポインターと見なされます。

于 2012-09-01T14:53:10.217 に答える