図 2.4 のコード
オブジェクトのバイト表現を表示するコード。
ポインタのキャストを活用している。
#include <stdio.h>
#include <string.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len){
size_t i;
for (i = 0; i < len; i++){
printf(" %.2x", start[i]);
}
printf("\n");
}
void show_int(int x){
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x){
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x){
show_bytes((byte_pointer)&x, sizeof(void *));
}
void show_strings(char *x){
show_bytes((byte_pointer) x, strlen(x));
}
void test_show_bytes(int val){
int ival = val;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}
int main(){
test_show_bytes(12345);
char *s = "abcdef";
show_strings(s);
return 0;
}
問題2.11
ポインタ演算によるin-placeスワップと、配列を逆順にするコード。
全くもって見事に「ARR01-C. 配列のサイズを求めるときに sizeof 演算子をポインタに適用しない」に違反したコードを書いていた。
sizeofで配列の長さを計算しているのに...というバグをつぶそうと30分ぐらい時間をつぶした。
www.jpcert.or.jp
#include <stdio.h>
void inplace_swap(int *x, int*y){
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
}
void reverse_array(int a[], int cnt){
int first, last;
for (first = 0, last = cnt-1; first < last; first++, last--){
inplace_swap(&a[first], &a[last]);
}
}
void print_array(int a[], size_t len){
int i;
for (i=0; i < len; i++){
printf("%d", a[i]);
}
printf("\n");
}
int main(){
int b[5] = {1, 2, 3, 4, 5};
print_array(b, sizeof(b) / sizeof(int));
reverse_array(b, sizeof(b) / sizeof(int));
print_array(b, sizeof(b) / sizeof(int));
return 0;
}
問題2.13
VAXコンピュータには ANDとORの代わりにbisとbicという演算子があり…という件から始まる。
#include <stdio.h>
int bis(int x, int m){
return x | m;
}
int bic(int x, int m){
return x & (~m);
}
int bool_or(int x, int y){
int result = bis(x, y);
return result;
}
int bool_xor(int x, int y){
int result = bis(bic(x, y), bic(y, x));
}
int main(){
int x = 0x69;
int y = 0x55;
printf("%x | %x = %x\n", x, y, bool_or(x, y));
printf("%x ^ %x = %x\n", x, y, bool_xor(x, y));
return 0;
}
問題2.14
ビット演算と論理演算は別物ですよ、という問題
#include <stdio.h>
int main(){
int x = 0x66;
int y = 0x39;
printf("%x & %x = %x\n", x, y, x & y);
printf("%x | %x = %x\n", x, y, x | y);
printf("~%x | ~%x = %x\n", x, y, ~x | ~y);
printf("%x & !%x = %x\n", x, y, x & !y);
printf("\n");
printf("%x && %x = %x\n", x, y, x && y);
printf("%x || %x = %x\n", x, y, x || y);
printf("~%x || ~%x = %x\n", x, y, ~x || ~y);
printf("%x && !%x = %x\n", x, y, x && !y);
}