図 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分ぐらい時間をつぶした。
#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); }