1
unsigned char xor4(unsigned char c1, unsigned char c2){
    int i = 0;
    while(i < 8){
        if((getBit(c1, i) ^ getBit(c2, i)))
             setBit(c1,i);
        else clearBit(c1, i);
        i+=2;
    }

    return c1;
}

上記のコードは、2 番目の文字の 1 つおきのビットを使用した xor の結果に基づいて、1 つの文字の 1 つおきのビットを設定する非常に単純な関数であると想定されています。何らかの理由で、これは単に機能しません。プログラムは、while ループを無視して元の関数を返すようです。

ああ、ここに私の getBit、setBit、および clearBit 関数があります。

unsigned char getBit(unsigned char c, int n){
  return (c & 1<<n) >> n;
}

unsigned char clearBit(unsigned char c, int n){
  c = c & (~(1<<n));
}

unsigned char setBit(unsigned char c, int n){
  `c = c | (1<<n);
}
4

2 に答える 2

3

と を呼び出しているときはsetBit、のコピーをこれらの関数にclearBit渡しています。したがって、inの値はまったく変更されません。c1c1xor4

交換

 if((getBit(c1,i)^getBit(c2,i))) setBit(c1,i);
 else clearBit(c1,i);

直接セットまたはクリア操作で、

 if((getBit(c1,i)^getBit(c2,i))) c1 |= (1 << i);
 else c1 &= ~(1 << i);

(しかし、指摘されたように、関数を単純なものに置き換えるだけc1 ^ c2でより効率的になります。)

于 2012-10-06T00:40:12.403 に答える
1

setbit および clearbit 関数を投稿しませんでしたが、それらが何をしても、呼び出し元の関数で c1 を変更することはできません。c1 のアドレスを渡すか、c1 の新しい値を返す必要があります。または、C ビット単位の演算子を使用することもできます。そして、操作全体はc1 ^= c2(charが8ビットであると仮定して)とまったく同じです。

編集: 編集を考慮して、関数の戻り値を c1 に割り当てるだけです...そして setbit および clear bit 関数を修正します...それらは値を返しません。コンパイラで適切な警告設定を使用していた場合は、それを教えてください。私はいくつかのスタイル上の変更を加えました:

/* your getbit works but is needlessly complex */
unsigned char getBit(unsigned char c, int n){
    return (c >> n) & 1; 

unsigned char clearBit(unsigned char c, int n){
    return c & ~(1 << n);
}

unsigned char setBit(unsigned char c, int n){
    return c | (1 << n);
} 

unsigned char xor4(unsigned char c1, unsigned char c2){
    for( int i = 0; i < 8; i += 2 )
        c1 = ( getBit(c1, i) ^ getBit(c2, i)
               ? setBit(c1, i);
               : clearBit(c1, i) );

    return c1;
}

より速い解決策は次のとおりです。

unsigned char xor4(unsigned char c1, unsigned char c2){
    return (c1 & 0xAA) | ((c1 ^ c2) & 0x55);
}

さらに高速:

unsigned char xor4(unsigned char c1, unsigned char c2){
    return (c2 & 0x55) ^ c1;
}
于 2012-10-06T00:43:07.190 に答える