0

ここで問題が発生しました。整数を入力し、整数ポインターをキャストして、ポインターと出力するバイト数print_bytesを受け入れる関数に送信しました。char*各バイトのアドレスと数値を 16 進数で出力してみました。ただし、250 の場合、o/p は最初のバイトが fa で、次の 3 バイトがゼロである必要がありましたが、代わりに最初のバイトが fffffffa と出力されます。

#include<stdio.h>
using namespace std;
void print_bytes(char* ptr,int len)
{
      for(int i=0;i<len;i++)
      {
             printf("%p  %x\n",ptr+i,*(ptr+i));         
      }     
}
int main()
{
      int a=250;
      print_bytes((char*)&a,4);
      return 0;
}

しかし、ポインターの型を変更するunsigned char*と、正しい出力が得られます。つまり、MSB が 1 でchar*あると、出力がうまくいかないということです。または、何か不足していますか?

4

3 に答える 3

0
printf("%p  %02x\n",ptr+i,(unsigned char)*(ptr+i));         
于 2013-06-27T09:24:48.780 に答える
0

printf 関数に渡されると、型が signed int に昇格されます。署名された型が昇格すると、「符号拡張」されます。

8 ビットの符号付きchar では、値 250 は -6 (2 の補数) に相当し、符号付きであるため、-6 は「真の」値と見なされます。これが符号付き整数 (4 バイト) に拡張されると、ここで起こっているように、値 250 ではなく値 -6 が (符号拡張によって) 保持されます。ただし、4 バイト値の -6 は fffffffa ですが、 1 バイトの fa にすぎません。

MSB は符号のフラグとして機能するため、設定されている場合は、観察した動作が得られます。

printf 呼び出しでキャストする(unsigned char)と、代わりに値が「ゼロ拡張」されます。これにより、値 -6 ではなく値 250 が保持され、必要な動作が得られます。

可変引数関数 (vararg) である printf (標準で設定されている) の要件は、int よりも狭い引数が渡される前に int に昇格されるため、そもそも符号拡張です。( float を double に昇格する必要もあります)。

于 2013-06-27T09:38:04.093 に答える