3

C で次の文字定数を記述したとします。

  '\xFFFFAA'  

その数値は?

標準C99は次のように述べています。

  • 文字定数の型はintです。
  • 16 進文字定数は、 として表すことができますunsigned char
  • 基本文字定数の値は負ではありません。
  • 文字定数の値は の範囲に収まりますchar

その上:

  • の値の範囲は の値のsigned char範囲に含まれていますint
  • 、 、 のサイズ (ビット単位) は同じでchar、1 バイトです。 unsigned charsigned char
  • バイトのサイズは で与えられCHAR_BIT、その値は少なくとも 8 です。

の典型的な状況があるとしましょうCHAR_BIT == 8
また、それが私たちのためだとcharしましょsigned charう。

規則に従う: 定数 '\xFFFFAA' の型intは ですが、その値はで表すことができますがunsigned char実際の値は に収まりますchar
これらの規則から、'\xFF' の例は次のようになります。

  (int)(char)(unsigned char)'\xFF' == -1

最初のキャストunsigned charは、「unsigned char として表現できる」という要件から来ています。
2 番目のキャストcharは、「値が 1 文字に収まる」という要件から来ています。
3 番目のキャストint は、「int 型を持つ」という要件から来ています。

ただし、定数'\xFFFFAA'が大きすぎて、 として「表現」できませんunsigned int
その価値はどれですか?

(char)(0xFFFFAA % 256)この値は、標準が多かれ少なかれ次のように述べているため、次の結果であると思います。

  • 符号なし整数型の場合、値がその型で表現できる最大Mよりも大きい場合、値はMを法とする剰余を取った後に取得されます。

私はこの結論で正しいですか?

編集私は@KeithThompsonによって確信しました:彼は、標準によれば、大きな16進文字定数は制約違反であると言います。
だから、私はその答えを受け入れます。

ただし、たとえば、GCC 4.8、MinGW では、コンパイラは警告メッセージをトリガーし、プログラムは説明した動作に従ってコンパイルされます。したがって、'\x100020' のような有効な定数と見なされ、その値は 0x20 でした。

4

2 に答える 2

4

C 標準では、セクション 6.4.4.4 で構文とセマンティクスが定義されています。C11 規格のN1570ドラフトを引用します。

パラグラフ 6:

16 進エスケープ シーケンスでバックスラッシュと文字xに続く 16 進数字は、整数文字定数の場合は 1 文字、ワイド文字定数の場合は 1 ワイド文字の構成の一部と見なされます。このように形成された 16 進整数の数値は、目的の文字またはワイド文字の値を指定します。

パラグラフ 9:

制約

8 進数または 16 進数のエスケープ シーケンスの値は、対応する型の表現可能な値の範囲内でなければなりません。

接頭辞がない場合、「対応するタイプ」はunsigned char.

0xFFFFAAしたがって、それが type の表現可能な範囲外であると仮定するとunsigned char、文字定数'\xFFFFAA'は制約違反であり、コンパイル時の診断が必要になります。コンパイラは、ソース ファイルを完全に拒否することができます。

コンパイラが少なくともこれについて警告しない場合は、C 標準に準拠していません。

はい、標準では、符号なしの型にはモジュラー (ラップアラウンド) セマンティクスがあると書かれていますが、それは算術式と一部の変換にのみ適用され、定数の意味には適用されません。

(CHAR_BIT >= 24あなたのシステムでは完全に有効ですが、それはまれです; 通常はCHAR_BIT == 8.)

コンパイラが単なる警告を発行し、ソースのコンパイルを続行することを選択した場合、動作は未定義です (単に標準が動作を定義していないため)。

一方、実際に を意味していた場合、それは'xFFFFAA'16 進数として解釈されません。(単なるタイプミスであり、質問を編集して修正しましたが、とにかくここに残しておきます。) パラグラフ 10 で説明されているように、その値は実装によって定義されます。

複数の文字 (例: 'ab' )を含む整数文字定数の値は、 実装定義です。

複数の文字を含む文字定数は、ほとんど役に立たない言語機能であり、意図的に使用されるよりも偶然に使用されることが多いです。

于 2013-09-08T00:59:58.113 に答える
1

はい、 の値は\xFFFFAAで表現できるはずunsigned charです。

6.4.4.4 9 制約

8 進数または 16 進数のエスケープ シーケンスの値は、整数文字定数の unsigned char 型の表現可能な値の範囲内でなければなりません。

しかし、C99 は次のようにも述べています。

6.4.4.4 10 セマンティクス

複数の文字 ('ab' など) を含む整数文字定数の値、またはシングルバイト実行文字にマップされない文字またはエスケープ シーケンスを含む整数文字定数の値は、処理系定義です。

したがって、結果の値は unsigned char([0, 255]、CHAR_BIT == 8 の場合) の範囲内にある必要があります。ただし、どちらかについては、コンパイラ、アーキテクチャなどによって異なります。

于 2013-09-08T01:01:06.690 に答える