16進数の先頭に0xが付いているのはなぜですか?


414

16進数の前に何が付いているの0xですか?接頭辞の使用法は理解していますが、なぜ0x選択されたのかという意味がわかりません。


9
タイトルとテキストが2つのまったく異なる質問をすることに気づきました。ほとんどの返信は、タイトルの質問に焦点を当てています。本文中の質問に対する答えは単に「それは何も意味しない-それは単に整数が16進数で書かれていることをコンパイラーに告げるプレフィックスです」です。
Andreas Rejbrand 2010

30
わかりやすくするために、タイトルの質問を2つの異なる方法で解釈することもできます。1)「16進数のプレフィックスが0xであるのに、他のプレフィックスやインジケータとは対照的ではないのですか。2)「16進数を入力するときに接頭辞を使用する必要があるのはなぜですか。コンパイラは、接頭辞がなくても58Aを16進数として認識しますか?」質問の2番目の解釈に対する答えは簡単です。「123」も16進数です。
Andreas Rejbrand 2010

回答:


440

ショートストーリー:0それは定数(およびない識別子/予約語)を扱っていますパーサに指示します。数値の基数を指定するには、まだ何かが必要です。これxは任意の選択です。

長い話: 60年代、普及しているプログラミング番号システムは10進数と8進数でした—メインフレームは1バイトあたり12、24、または36ビットでした。これは3 = log2(8)で割り切れます。

BCPL言語8 1234は8進数の構文を使用しました。ケントンプソンがBCPLからBを作成したとき、0代わりにプレフィックスを使用しました。これは素晴らしいです

  1. 整数定数は常に単一のトークンで構成され、
  2. パーサーはまだ定数があることをすぐに知ることができます。
  3. パーサーはすぐにベースを知ることができます(0両方のベースで同じです)、
  4. 数学的に正気(00005 == 05)であり、
  5. 貴重な特殊文字は必要ありません(など#123)。

CがBから作成されたとき、16進数の必要性が生じ(PDP-11には16ビットのワードがありました)、上記のすべての点が依然として有効でした。他のマシンで0xは依然として8進数が必要だったため、任意に選択しました(00おそらく扱いにくいと判断されました)。

C#はCの子孫であるため、構文を継承します。


112
私は考えていない0xオーバー00好み/不器用でした。00既存のコードを壊します。0010進があるように8しながら、001016進数は次のようになりよう16。彼らは、2番目の数字のインジケーターとして数字を使用できなかったため(8またはを除き9、16 進数に関連する重要性も持ちません)、文字は必須です。そして、その葉のいずれか0hまたは0xH E X idecimal)。この時点から、本当に好みに戻ったようです。
GManNickG 2013年


23
08進数に接頭辞を使用すると、長年にわたって非常に多くの問題が発生しています。特に、電話番号がで始まる英国などの国では0。JavaScriptや他の多くの言語では、これらを8進数として解析し、保存する前に数値を変換します。おもしろいことに、人気のあるデータベース製品の1つは、数値にまたはが含まれている場合、黙って10進解析に切り替えます。89
基本

1
12、24、36も4で割り切れるので、なぜ16進数を考えなかったのでしょうか。
phuclv 2017年

4
@LưuVĩnhPhúc16進数があまり関連していないためでしょう。当時のほとんどのハードウェア、ソフトウェア、およびドキュメントは、8進数の方がはるかに適しています。BCPLは最初、36ビットのIBM 7094に実装され、命令フォーマットが2つの3ビット部分と2つの15ビット部分に分割されました。6ビット文字。8進数のドキュメント。Bの初期の実装は、PDP-7(18ビット)とHoneywell GE-945(36ビットですが、18ビットアドレス指定で、6ビットと9ビットバイトをサポート)でした。16ビットPDP-11はBの後にリリースされたので、Bの設計にはあまり影響しなかったでしょう。
8ビットツリー

97

注:正解はわかりませんが、以下は個人的な推測です。

すでに述べたように、数値の前の0は、それが8進数であることを意味します。

04524 // octal, leading 0

16進数を表示するシステムを考え出す必要があると想像してください。また、Cスタイルの環境で作業していることに注意してください。アセンブリのようにhで終わるのはどうですか?残念ながらできません。有効な識別子であるトークンを作成することができます(たとえば、変数に同じ名前を付けることができます)。

8000h // hex
FF00h // oops - valid identifier!  Hex or a variable or type named FF00h?

同じ理由でキャラクターをリードすることはできません。

xFF00 // also valid identifier

ハッシュの使用は、プリプロセッサと競合するため、おそらくスローされました。

#define ...
#FF00 // invalid preprocessor token?

結局、何らかの理由で、16進数を表すために先頭の0の後にxを置くことにしました。それはまだ数字で始まっているので一義的ではなく、有効な識別子にすることはできず、おそらく先頭の0の8進法に基づいています。

0xFF00 // definitely not an identifier!

3
面白い。16進数を表すために、先頭の0と末尾のhを使用できたと思います。末尾のhは、タイプ指定子のサフィックスと混同されている可能性があります。たとえば、0xFF00lと0FF00hl
zdan

2
この引数は、8進数を表すために先行ゼロを使用すると、16進数の「0x」接頭辞が使用される前に使用されることを意味します。これは本当ですか?
Andreas Rejbrand 2010

1
両方が同時に発明されたのではないでしょうか?なぜ一方が存在し、もう一方が存在しないのですか?
AshleysBrain、2010

AshleysBrainは、同時に8進数が存在し、16進数が存在しない理由について、@Řrřolaの回答を参照してください。
jv42 2012年

2
@zdan彼らはずっと前にそれを使用しました。x86 Intelアセンブリでは、16進リテラルの先頭が文字の場合、先頭に0を付ける必要があります。たとえば、次の0xFFAB1234ように記述する必要があります0FFAB1234h。私が若かったとき、私はパスカルのインラインアセンブラからそれを覚えてstackoverflow.com/q/11733731/995714
phuclv

27

これは、数値が他のベースではなく16進数であることを示す接頭辞です。Cプログラミング言語はこれを使用してコンパイラーに指示します。

例:

0x6400変換 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. コンパイラは読み取ると0x6400、それは、数はの助けを借りて、進で理解し0xの 用語。通常、(6400)16または(6400)8などで理解できます。

以下のためのバイナリそれは次のようになります。

0b00000001

私が何らかの形で助けてくれたことを願っています。

良い一日!


2
バイナリリテラルは、C ++ 14以降のC ++でのみサポートされており、Cではまったくサポートされていません。
ルスラン

1
これは理由を説明していません。特に、最初の例を次のように記述できないのはなぜx6400ですか。xまだ進数を推測するために使用することができます。
アーロンフランケ

12

先行する0は、基数2、8、または16の数値を示すために使用されます。

私の意見では、「x」は16進数のように聞こえるため、0xは16進数を示すために選択されました。

私の意見だけですが、それは理にかなっていると思います。

良い一日!


2
答えてくれてありがとう!StackOverflowに関する最初の投稿であることを理解しています。意見が事実から分離されている場合、答えはより役に立ちました。
vivek_ganesan 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.