37903


c言語で、ある特定の1バイトを指定した1バイトに変える関数を作成したいです。

[code]

    int okikae(0x12345678, 0xFF, 2) // 0x12FF5678 が戻り値
    int okikae(0x12345678, 0xFF, 0) // 0x123456FF が戻り値
    
[/code]

といった具合で、演算子を ~!|&^+>><<だけ使い、かつif文やwhile文、変数宣言などをせずに作りたいのですがどのようにすれば良いでしょうか？


CC BY-SA 3.0
2017-09-12T13:43:27.937
37899
2017-09-12T16:17:40.427
2017-09-12T16:15:20.053
19110
18535
question
c
cのビット演算で特定のビットを指定したビットに置き換える関数を作りたい


ビットマスクを使って実装してみました。 ([下のコードの
Wandbox](https://wandbox.org/permlink/mrkIaweCg6zLQrJE))

[code]

    #include <stdint.h>
    #include <stdio.h>
    
    uint32_t okikae(uint32_t data, uint8_t byte, uint8_t shift) {
      // ここで shift が3以下であることを確認したほうが良いでしょう
      uint32_t mask = ~((uint32_t)0xFF << (shift * 8));
      uint32_t answer = (data & mask) | ((uint32_t)byte << (shift * 8));
      printf("        data = 0x%08x\n", data);
      printf("        byte = 0x%08x\n", byte);
      printf("        mask = 0x%08x\n", mask);
      printf(" masked data = 0x%08x\n", data & mask);
      printf("shifted byte = 0x%08x\n", (uint32_t)byte << (shift * 8));
      printf("      return = 0x%08x\n\n", answer);
      return answer;
    }
    
    int main() {
      okikae(0x12345678, 0xFF, 0);
      okikae(0x12345678, 0xFF, 1);
      okikae(0x12345678, 0xFF, 2);
      okikae(0x12345678, 0xFF, 3);
      return 0;
    }
    
[/code]

[code]

            data = 0x12345678
            byte = 0x000000ff
            mask = 0xffffff00
     masked data = 0x12345600
    shifted byte = 0x000000ff
          return = 0x123456ff
    
            data = 0x12345678
            byte = 0x000000ff
            mask = 0xffff00ff
     masked data = 0x12340078
    shifted byte = 0x0000ff00
          return = 0x1234ff78
    
            data = 0x12345678
            byte = 0x000000ff
            mask = 0xff00ffff
     masked data = 0x12005678
    shifted byte = 0x00ff0000
          return = 0x12ff5678
    
            data = 0x12345678
            byte = 0x000000ff
            mask = 0x00ffffff
     masked data = 0x00345678
    shifted byte = 0xff000000
          return = 0xff345678
    
[/code]

変更されるべき部分をマスクで 0 にリセットし、その後指定した1バイトを bitwise-or で挿入しています。

※ 説明のために変数宣言をしていますが、1行にまとめることができます。


CC BY-SA 3.0
2017-09-12T16:06:17.617
37903
2017-09-12T16:17:40.427
2017-09-12T16:17:40.427
19110
19110
37899
answer