2017-03-26 1 views
1

私はいくつかのCコードを別の言語に移植しようとしています。このセクションの内容を理解することを除いて、ほとんどのコードが動作しています。私が手渡したCコードはコンパイル可能な状態ではないので、実行時分析はできませんが、最後の手段としてそれを修正します。このCコードが値に割り当てるサイズのデータ​​/位置

バッファは、ファイルの生の内容を指すポインタです。私の予想はこれをしたコードを読むに基づいて

pos = 4132場合、このファイルの位置(pos << 8) + (pos + 1)から16ビットの符号なしの値を読み取るしようとしています。私はpos = 4132ため、この計算を行う際に

はしかし、私は、ファイルの終わりを超えた方法です1061925のファイル位置を、取得します。

unsigned short id; 

    struct file 
    { 
     char *buffer; 
    } 

id = (*(file_instance->buffer + pos)<<8) + *(file_instance->buffer+pos+1); 
+1

それの隣に。 'pos'のオクテットが' 0xAA'で、 'pos + 1''の' 0xBB'のオクテットの場合、 '0xAABB'が得られます。 '|'はこの文脈で '+'と同じことをします。 – PSkocik

+1

'*(file_instance-> buffer + pos)'は 'pos'だけでなく左シフトしていることに注意してください。 – aschepler

+1

最後のステートメントが配列の添え字で記述されていれば、より明確になるでしょう: 'id =(file_instance-> buffer [pos] << 8)+ file_instance-> buffer [pos + 1];' – dbush

答えて

2

あなたがアイデンティティに*(A+B) == A[B]、そしてX << 1 == X * 2使用して、それを変換することができ、読みのコードを容易にするために:このコードは、bufferunsigned char *た場合

id = (file_instance->buffer[0] * 256) + file_instance->buffer[1]; 

をだろう最初のオクテットが最も重要なものであるメモリから16ビットの整数を読み取るための共通の慣用法になります。たとえば、メモリが{ 0x01, 0x02 }だった場合、この方程式が整数値0x0102を生成することを確認できます。

ただし、あなたはバッファーがchar *だと言っています。 Cでは、charは、符号付きまたは符号なしのいずれかのタイプです。あなたが作業しているシステムで署名されていない場合は、すべて正常です。また、読んでいるデータに決してMSBのバイトが設定されていない場合は、すべて問題ありません。

charが署名されている場合、file_instance->buffer[0]の値が負の値(つまり、MSBセットを持つ)である場合、符号は負の数を左シフトするためにundefined behaviourとなります。また、2つの負の数を追加すると予期しない動作が発生する可能性があります。あなたは、コードを実行することができない場合

さまざまなハードウェアとコンパイラの最適化の詳細に翻弄されるので、既存の動作が何であったかうまくすることは困難です。

あなたは、ターゲットシステム上でコードを実行できるなら、あなたは試してみて、次のようなコードスニペットで何が起こるかを見ることができる:それはpos` `でオクテットを取り、` POS + 1でoctecを配置

#include <stdio.h> 

int main() 
{ 
    char buf[2] = { 0xAA, 0xBB };  // put sample data here 

    int r = buf[0] << 8 + buf[1]; 

    printf("%x\n", (unsigned)r); 
} 
+0

ありがとう、私はこの情報に基づいて動作しました。 –

関連する問題