1

私は C コードを読んでいて、コードを正しく理解しているかどうかを知りたいと思っていました。

以下に示すように、ヘッダー ファイルで定義された構造体 BF_salt があります。

typedef
{
BF_WORD salt[4];
..
..
} BF_SALT;

メイン C コードでは、関数への呼び出しがあります。

function func1()
{
 static BF_SALT salt;
 func2(salt.salt,x,y);
....
}

func2(BF_WORD * dst,x,y)
{
 unsigned char * dptr= (unsigned char*)dst;
 int c1,c2;

 // c1 and c2 are initialized here.

 // in a loop, an operation similar to the below is performed.

 *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
}

上記のコードの私の理解は次のとおりです。

func1 では、salt は構造体 BF_SALT のデータ型で定義されています。

func2 を呼び出して、構造体のソルト フィールドを渡します。

salt フィールドは、それぞれがデータ型 BF_WORD (32 ビット ワードまたは 4 バイト) の 4 つの要素の配列です。

関数 2 で

dst は、タイプ BF_WORD の要素を指す配列の名前です。

ポインター dst で型キャストを実行しています。

現在、dst はデータ型 BF_WORD を指しています。char (1 バイト データ) を指すように型キャストされます。

これで、整数 c1 と c2 に対してビットシフト演算が実行され、dptr が指すメモリ アドレスに出力が書き込まれます。そのため、dst が最初に指していたデータ (salt 配列のバイト) を上書きしています。

c1 と c2 のデータ型は int で、4 バイトのスペースが必要です。

dptr はどのように配列の内容を上書きしますか? 毎回 *dptr++ を実行するので、ポインター dptr を 1 バイト進めます。これは、文字を指しているためです。

ただし、1 バイトより大きいサイズの値を割り当てています。データはどのようにメモリに書き込まれますか?

ありがとう。

4

3 に答える 3

2

結果の最下位バイトのみがメモリに書き込まれます。ポインターは char を指すため、int は切り捨てられ、左辺値の型に変換されるときに上位バイトが失われます。結果を単に char 変数に代入した場合と同じ規則です。詳細については、標準セクション 6.3.2.1 および 6.5.16.1 を参照してください。

于 2013-02-27T18:15:45.097 に答える
1

ここ

*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);

への暗黙的なキャストunsigned charが実行されるdptrためunsigned char **dptrは として扱われますunsigned char

于 2013-02-27T18:07:18.440 に答える
0

上記のコードについてのあなたの理解は、私のものと似ています。また、私自身の考えのいくつかを取り入れさせてください。

unsigned char * dptr= (unsigned char*)dst;

ここで、タイプBF_WORD(4バイト)のdstは、charタイプ(1バイト)にダウンキャストされます。また、ポインターのタイプはcharであり、一度に1バイトをナビゲートできますが、保持されます。 4バイトの連続したメモリ位置のアドレス。したがって、技術的には、一度に1バイトずつこれらの4バイトをナビゲートできる必要があります。

dptrはどのようにして配列の内容を上書きしますか?

dptrには、4つの数値、4バイトの配列saltの開始アドレスが含まれるようになりました。そのため、現在、salt[0]にアクセスしています。ここで、salt [0]のサイズは4バイトで、dptrは1バイトのポインターであるため、配列salt [0]の1つの要素をカバーするには、4(dptr ++)の増分が必要です。

今、他の質問

1バイトより大きいサイズの値を割り当てています。データはどのようにメモリに書き込まれますか?

*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);

ここで、c1とc2はどちらもint型であるため、ビット演算後の結果はint型になります。したがって、4バイトの結果はdptrが指すsalt[0]に書き込まれます。dptrの次の増分では、ポインターは前の4バイトの結果の2バイトを指すため、前の結果の最後の3バイトは次のビット単位の結果によってオーバーランされます。

于 2013-02-27T18:06:47.643 に答える