押しかけレビュー

Windows より Mac より Linux がいい
第3回資料

資料押しかけレビュー
第3回目

7ページ目

このままではprintfのところで警告が出るはず。warning freeにするためには以下のようにサイズを指定する。

printf(“%hhu\n”, *c++);

10ページ目

XORを使うと同じオブジェクトを渡したときに、値が失われてしまいます。素直に一時変数を使うが吉。豆知識としてはよいが、doubleに無理矢理適用しても、余り実用性がありません。まぁ型を偽ることの紹介という意味合いでしょうか。それならば以下のようなマクロはどうでしょう?何をしているかわかりますか?(プリプロセッサがテーマになる回があるようなので、そちら向きかもしれませんね。)
このマクロでは、オブジェクトなら何でもswapできます。配列ですら入れ替え可能なのが強みです。

#include <stdio.h>
#include <stdlib.h>

#define SWAP(a, b)	do{ \
	struct TTmp { \
		char buf[sizeof(*(&(a)))]; \
	} tmp; \
	tmp = *((struct TTmp *)&(a)); \
	*((struct TTmp *)&(a)) = *((struct TTmp *)&(b)); \
	*((struct TTmp *)&(b)) = tmp; \
}while(0)

typedef struct THoge {
	char a;
	char b;
	char c;
	char d;
} THoge;

void  swap(int *a,  int *b)  {
	*a  =  *a  ^  *b;
	*b  =  *b  ^  *a;
	*a  =  *a  ^  *b;
}

/* 使い方サンプルドライバ */
int main(void)
{
	int iA = 0x00000000, iB = 0x12345678;
	double dA = 0.0, dB = 3.14;
	THoge tA = {1, 2, 3, 4}, tB = {9, 8, 7, 6};
	char strA[] = "123", strB[] = "abc";

	/* intの入れ替え */
	printf("before: %08x, %08x\n", iA, iB);
	SWAP(iA, iB);
	printf("after:  %08x, %08x\n", iA, iB);

	/* doubleの入れ替え */
	printf("before: %5.2f, %5.2f\n", dA, dB);
	SWAP(dA, dB);
	printf("before: %5.2f, %5.2f\n", dA, dB);

	/* 構造体の入れ替え */
	printf("before: %08x, %08x\n", *((int *)&tA), *((int *)&tB));
	SWAP(tA, tB);
	printf("after:  %08x, %08x\n", *((int *)&tA), *((int *)&tB));

	/* 配列の入れ替え */
	printf("before: %08x, %08x\n", *((int *)strA), *((int *)strB));
	SWAP(strA, strB);
	printf("after:  %08x, %08x\n", *((int *)strA), *((int *)strB));

	/* intの入れ替え同じオブジェクト */
	printf("before: %08x, %08x\n", iA, iA);
	SWAP(iA, iA);
	printf("after:  %08x, %08x\n", iA, iA);
	
	/* intの入れ替え同じオブジェクトXOR版 */
	printf("before: %08x, %08x\n", iA, iA);
	swap(&iA, &iA);	/* 同じオブジェクトを渡すと値が失われる。 */
	printf("after:  %08x, %08x\n", iA, iA);
	
	return	0;
}

14ページ

「void *型は、値が分からないときに使います」これは型がわからないときに使用します」がよいでしょうね。
ポインタの説明の時に、「アドレスと型情報を持ったデータ型」と説明していましたが、この型情報が無い物です。よって、逆参照することができません。