c-'0' を使用する K&R 関数の 1 つをテストしようとしていました。明確に理解するために、以下のように 2 行のコードを書きました。私の質問は、なぜ「1」を印刷しているのかということです。そして、この文脈で「数値」は実際には何を意味するのでしょうか。ありがとう!
char c = 'a';
printf("%c",c-'0');
c-'0' を使用する K&R 関数の 1 つをテストしようとしていました。明確に理解するために、以下のように 2 行のコードを書きました。私の質問は、なぜ「1」を印刷しているのかということです。そして、この文脈で「数値」は実際には何を意味するのでしょうか。ありがとう!
char c = 'a';
printf("%c",c-'0');
c - '0'cが数字(「0」、「1」、...、または「9」)の場合にのみ、明確な特定の値があります。
の場合、は、のc場合に等しいためです。これは、 C実装が使用することを選択した任意の文字セットの直後に続くためです。と他の数字についても同じです。値は。です。'0''0' - '0'0c'1''1' - '0'1'1''0''2''9' - '0'9
"%c"また、フォーマット指定子を使用して値を出力するべきではありません。
数値は文字の ASCII 値です。
'a'は 97、'0'は 48 です。97-48=49。
49 は の値な'1'ので、それが出力されます。
Cの文字は、単なる整数値にすぎません。それらの値は、文字エンコードに従って定義されます。ASCIIエンコーディングは非常によく知られており、OPによって投稿された質問に適用されるものです。したがって、「0」は48に等しく、「a」は97に等しくなります。それらを減算することにより、ASCIIテーブル内のこれらの文字間の差を取得するだけです。
この例(あなたの例と同等)では:
printf("%c",'a'-'0');
1ASCII文字「1」に対応する97-48=49から取得します。
代わりに使用していた場合(「%c」ではなく「%d」に注意してください):
printf("%d",'a'-'0');
次に、これは違い(この場合は49)のみを出力し、違いに関連付けられたASCII文字は出力しません。
コードの動作は実装に依存します。文字のエンコーディングに依存しています。
私の Linux マシンでは、a文字はASCII (および UTF8) で 1 バイト97(10 進数)、つまり0x61. 同様に、文字はie0としてエンコードされます。違いは、たまたま文字のエンコーディングであるということです480x30'a' - '0'97 - 48491
一部の古いEBCDICマシン (たとえば、古い IBM メインフレーム、または何らかの互換モードまたはオペレーティング システムで実行されている新しいもの) では、エンコーディングが異なります。
UTF8 (現在非常に頻繁に使用されています)では、さらに多くの文字が存在し (たとえば、çフランス語のスペリングの C cedilla)、それらは通常 1 バイト以上でエンコードされます!
c-「0」は、cから「0」(48)の文字コードを減算します。cが数字を表す場合、これはcに対応する数値になります(たとえば、文字「3」の場合は3)。
それでもこの数値を取得するには、%cの代わりにprintfでフォーマット指定子%dを使用する必要があります。
「a」から「0」を引くことはあまり意味がありませんが、特定のタスクに何らかの用途があるかもしれません。
文字の代わりに整数を使用して、これをもう少し説明しましょう。
char c = 97;
printf("%d", c - 48);
これはもちろん 49 を出力しますが、これを ASCII テーブルで文字に変換すると 1 になります。
char c = 97;
printf("%c", c-48);
このコードは、出力時に char データ型を使用し、値 49 を同等の ASCII 数値 1 に変換するため、1 を出力します。
これを証明するために、次のようなことを試すことができます。
char a = 'a';
char b = 97;
if((a == b) && ((a-'0') == (b-48))) {
printf("%s", "true");
}
最初に a と b が同等かどうかを確認し、次に a-'0' が b-48 と同等かどうかを確認します。どちらも true であるため、true を出力します。