接上题目:
unsigned replace_byte(unsigned x, int i, unsigned char b);
以下示例,说明了这个函数该如何工作:
replace_byte(unsigned x, int i, unsigned char b);
replace_byte(0x12345678, 2, 0xAB)-->0x12AB5678;
replace_byte(0x12345678, 0, 0xAB)-- > 0x123456AB;
开始作答:
/** generate-a-word.c */
#include <stdio.h>
#include <assert.h>
//expression: ( (b & 0xFF) << 8 * i ) | ( x&(~ (0xFF << i * 8) ) )
unsigned replace_byte(unsigned x, int i, unsigned char b) {
unsigned int y = 0;
//8*i = i<<3 #*************#
y = (b & 0xFF) << 8 * i;
x = x&(~(0xFF << i * 8));
return x|y ;
}
int main() {
unsigned x = 0x12345678;
int i = 0;
unsigned char b = 0xAB;
printf("%#X\n",replace_byte(x,i,b));
return 0;
}
官方答案:
#include <stdio.h>
#include <assert.h>
unsigned replace_byte(unsigned x, int i, unsigned char b) {
if (i < 0) {
printf("error: i is negetive\n");
return x;
}
if (i > sizeof(unsigned)-1) {
printf("error: too big i");
return x;
}
// 1 byte has 8 bits, << 3 means * 8
unsigned mask = ((unsigned) 0xFF) << (i << 3);
unsigned pos_byte = ((unsigned) b) << (i << 3);
return (x & ~mask) | pos_byte;
}
int main(int argc, char *argv[]) {
unsigned rep_0 = replace_byte(0x12345678, 0, 0xAB);
unsigned rep_3 = replace_byte(0x12345678, 3, 0xAB);
assert(rep_0 == 0x123456AB);
assert(rep_3 == 0xAB345678);
return 0;
}