9

文字は 1 バイト、整数は 4 バイトです。char[4] からバイト単位で整数にコピーしたい。さまざまな方法を考えましたが、さまざまな答えが得られました。

char str[4]="abc";
unsigned int a = *(unsigned int*)str;
unsigned int b = str[0]<<24 | str[1]<<16 | str[2]<<8 | str[3];
unsigned int c;
memcpy(&c, str, 4);
printf("%u %u %u\n", a, b, c);

出力は 6513249 1633837824 6513249 です

どちらが正しいですか?何がうまくいかないのですか?

4

6 に答える 6

6

最初の 2 つのどちらも正しくありません。

1 つ目はエイリアシング ルールに違反し、 のアドレスがstrに対して適切にアラインされていないため、失敗する可能性がありますunsigned int。文字列のバイトをホスト システムのバイト順で再解釈するには、unsigned int次のようにコピーしますmemcpy

unsigned int a; memcpy(&a, &str, sizeof a);

( an のサイズunsigned intと のサイズstrが同じであると仮定します。)

str[0]2 番目の例は、が に昇格したため、整数オーバーフローで失敗する可能性がありますint。そのため、str[0]<<24typeintがありますが、シフトに必要な値は、 で表現できるよりも大きい可能性がありますint。これを修正するには、次を使用します。

unsigned int b = (unsigned int) str[0] << 24 | …;

この 2 番目の方法は、ホスト システム内strのバイトの順序に関係なく、バイトをビッグ エンディアンの順序で解釈します。unsigned int

于 2013-10-11T17:30:48.293 に答える