Unsigned char値を2桁の16進値として出力しようとしていますが、結果は常に4桁の16進値として取得され、コードの何が問題になっているのかわかりません。
// unsigned char declaration
unsigned char status = 0x00;
// printing out the value
printf("status = (0x%02X)\n\r", (status |= 0xC0));
0xC0
として2桁の16進数の結果を期待していますが、常に0xC0FF
を取得します。
また、unsigned charと同じ変数(ステータス)を%bu
形式の識別子で出力しようとすると、出力は255
になりました。
2つの16進文字だけを出力として取得するにはどうすればよいですか?
私の知る限り、 Keil Cコンパイラ はC標準に完全には準拠していません。その場合、可変個引数関数にchar
値を渡すなどの標準のプロモーションルールに完全には準拠していない可能性があります。 8ビットCPUでは、8ビット値を16ビット以上に自動的に拡張しないというパフォーマンス上の利点があります。
回避策として、引数をprintf
に渡す前に、上位ビットを明示的に切り捨てることができます。これを試して:
#include <stdio.h>
int main(void) {
unsigned char status = 0x00;
status |= 0xC0;
printf("status = 0x%02X\n", (unsigned int)(status & 0xFF));
return 0;
}
0xFF
でビット単位の「and」を実行すると、下位8ビットを除くすべてがクリアされます。 unsigned int
へのキャストは必要ありませんが、引数が実際にprintf
で期待されるタイプであることを保証します。 "%02X"
形式で。
タイププロモーションとprintf
の非標準の動作については、実装のドキュメントも参照してください。
intを期待するフォーマット文字列にcharを送信しています。 printf関数は、スタックから別のバイトを取得して埋めます。試してみてください
printf("%02X",(int)(status|0xC0));
Unsigned charにキャストします:
printf("status = (0x%02X)\n\r", (unsigned char)(status |= 0xC0));
すべての答えを見ると、おそらくこれを行う別の方法が欠けていると思います。
const unsigned char chararr[]="abceXYZ";
for (int i=0; i< 7; ++i) {
printf("%#04X %d %c\n", chararr[i], chararr[i], chararr[i]);
}
0X61 97 a
0X62 98 b
0X63 99 c
0X65 101 e
0X58 88 X
0X59 89 Y
0X5A 90 Z
%#04x small xを使用すると、出力はb 0x smallxプレフィックスになります。 #ポンド記号は、0xを出力するように関数に指示します。 04は出力する桁数を指示し、入力が「0x0a」の場合はこれを出力し、04がない場合は「0xa」を出力します。
私のコンピュータであるDellワークステーションでは、出力は質問で期待どおりです。そうでなければ
unsigned char status = 0x00;
printf("status = (0x%02X)\n\r", (status |= 0xC0));
// output
//status = (0xC0)
// is exactly expected by the original question.
例でよりよく説明されています:
37 printf("status = (%#02x)\n", (status |= 0xC0));
38 printf("status = (%#04x)\n", (status |= 0xC0));
39 printf("status = (%#04x)\n", 0x0f);
40 printf("status = (%#02x)\n", 0x0f);
status = (0xc0)
status = (0xc0)
status = (0x0f)
status = (0xf)