1.编写一个将二进制字符串转化为数字值的函数。也就是说,如果您有以下语句:

char * pbin = "01001001";

那么您可以将pbin作为一个参数传送给该函数,使该函数返回一个int的值25

#include <stdio.h>

int bitoi(char *);

int main(void)
{
	char * pbin = "00011001";

	printf("二进制:%s 等于十进制止:%d\n", pbin, bitoi(pbin));
}

int bitoi(char * str)
{
	int val = 0;
	while (*str != '\0')
		//(2*val)2为其数val每运行一次增加一次幕。
		val = 2 * val + (*str++ - '0');
	return val;
}


2.编写一个程序,该程序用命令行参数读取两个二进制字符串,并打印对每个数使用~运算符的结果,以及对这两个数使用&、|和^运算符的结果。使用二进制字符串形式显示结果。

#include <stdio.h>
#include <string.h>
//用8位来测试INTSIZE的值为9
#define INTSIZE 9
int bitoi(char *);
char * itobi(int);

int main(int argc, char * argv[])
{
	int n1, n2;
	n1 = bitoi(argv[1]);
	n2 = bitoi(argv[2]);
	printf("取反\n");
	printf("%s\n%s\n", argv[1], itobi(~n1));
	printf("\n%s\n%s\n", argv[2], itobi(~n2));
	printf("\n与\n");
	printf(" %s\n %s\n %s\n", argv[1], argv[2], itobi(n1 & n2));
	printf("\n或\n");
	printf(" %s\n %s\n %s\n", argv[1], argv[2], itobi(n1 | n2));
	printf("\n异或\n");
	printf(" %s\n %s\n %s\n", argv[1], argv[2], itobi(n1 ^ n2));
}
int bitoi(char * str)
{
	int val = 0;
	while (*str != '\0')
		//(2*val)2为其数val每运行一次增加一次幕。
		val = 2 * val + (*str++ - '0');
	return val;
}
char * itobi(int n)
{
	int i = 1;
	static char str[INTSIZE];

	str[INTSIZE - 1] = '\0';
	int j = INTSIZE - 2;
	while (j >= 0)
	{
		str[j--] = (n & 1) + '0';
		n >>= 1;	
	}
	return str;
}	


3. 编写一个函数,该函数接受一个int参数,并返回这个参数中打开的位的数量。在程序中测试该函数

#include <stdio.h>
int open_count(int n);
char * itobi(int n);
int main(void)
{
	int i = 118191;
	printf("%d的二进制形式:%s\n", i, itobi(i));
	printf("%d二进制形式打开的位数量:%d\n", i, open_count(i));

	return 0;
}
int open_count(int n)
{
	int temp = 1;
	int i, count = 0;
	for (i = 0; i < 8 * sizeof(int); i++)
	{
		if (n & temp)
			count++;
		n >>= 1;
	}
	return count;
}
char * itobi(int n)
{
	int i = 1;
	static char str[8 * sizeof(int)];

	str[8 * sizeof(int)-1] = '\0';
	int j = 8 * sizeof(int)-2;
	while (j >= 0)
	{
		str[j--] = (n & 1) + '0';
		n >>= 1;
	}
	return str;
}


15_4. 编写一个函数,该函数接受两个int参数:一个值和一个位的位置。如果指定的位上的值是1,则

该函数返回1,否则返回0。在程序中测试该函数。

#include <stdio.h>
#include <stdlib.h>
#define INTSIZE (sizeof(int) * 8)
int fun(int n, int b);
char * itobi(int n);

int main(void)
{
	int num = 123234;
	int bit = 13;
	if (bit > INTSIZE || bit <= 0)
	{
		printf("位数超出范围\n");
		exit(EXIT_FAILURE);
	}	

	printf("%d的二进制形式:%s\n", num, itobi(num));
	printf("%d二进制形式中的第%d位为:%d\n", num, bit, fun(num, bit));

	return 0;
}

int fun(int n, int b)
{
	int i = 1;

	n >>= b - 1;
	if (n & i)
		return 1;

	return 0;
}
char * itobi(int n)
{
	int i = 1;
	static char str[8 * sizeof(int)];

	str[8 * sizeof(int)-1] = '\0';
	int j = 8 * sizeof(int)-2;
	while (j >= 0)
	{
		str[j--] = (n & 1) + '0';
		n >>= 1;
	}
	return str;
}


5.编写一个函数,该函数将一个unsigned int中的所有位向左旋转指定数量的位。

例如,rotate_l(x,4)将x中的所有位向左移动4个位置,而且从左端丢失的位会重新出现在右端。也就是说,把从高位移出的位放入低位。在程序中测试该函数。

#include <stdio.h>
#define UINTSIZE (sizeof(unsigned int)* 8)
unsigned int rotate_l(unsigned int x, int n);
char * itobi(int n);


int main(void)
{
	unsigned int num = 4123456;
	int bit = 6;

	printf("%s\n", itobi(num));
	printf("%s\n", itobi(rotate_l(num, bit)));
}
char * itobi(int n)
{
	int i = 1;
	static char str[UINTSIZE+1];

	str[UINTSIZE] = '\0';
	int j = UINTSIZE-1;
	while (j >= 0)
	{
		str[j--] = (n & 1) + '0';
		n >>= 1;
	}
	return str;
}
unsigned int rotate_l(unsigned int x, int n)
{
	unsigned int y;
	y = x >> (UINTSIZE - n);
	x <<= n;

	return x | y;
}


6.设计一个位字段结构用来存储以下信息:

Font ID:0到255之间的一个数

Font Size:0到127之间的一个数

Bold: Off (0)或on (1)

Italic: Off (0)或on (l)

Underline: Off (0)或on (1)

在程序中使用这个结构来显示字体参数,并使用循环的菜单来让用户改变参数。例如,程序的一个运行示例如下:

ID SIZE ALIGNMENT   B   I   U

1   12   left     off off off


f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

s

Enter font size (0-127): 36


ID SIZE ALIGNMENT   B   I   U

1   36   left     off off off

f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

a

Select alignment:

l)left   c)center   r)right

r


ID SIZE ALIGNMENT   B   I   U

1   36  right     off off off

f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

i


ID SIZE ALIGNMENT   B   I   U

1   36  right     off  on off

f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

q

Bye!

达个程序应该使用&操作符和合适的掩码来保证Font ID和Font size信息被转换到指定的范围内。

#include <stdio.h>
#include <string.h>
#define LEFT 0
#define CENTER 1
#define RIGHT 2
#define OFF 0
#define ON 1
#define FONTID 0xFF
#define FONTSIZE 0x7F
typedef struct box{
	unsigned int Font_ID : 8;	//0到255之间的一个数 字体ID
	unsigned int Font_Size : 7;	//0到127之间的一个数 字体大小
	unsigned int Align : 2;		//left(0)或right(1) 对齐
	unsigned int Bold : 1;		//Off(0)或on(1) 黑体
	unsigned int Italic : 1;	//Off(0)或on(l) 斜体
	unsigned int Underline : 1;	//Off(0)或on(1) 下划线
}BOX;
void show_box(const BOX * pbox);
int menu(void);
int get_ch(char * str);
void get_id(BOX * pbox);
void get_size(BOX * pbox);
void set_align(BOX * pbox);

int main(void)
{
	BOX box_info = { 1, 12, LEFT, OFF, OFF, OFF };
	char ch;
	
	show_box(&box_info);
	while ((ch = menu()) != 'q')
	{
		switch (ch)
		{
		case 'f':get_id(&box_info);
			break;
		case 's':get_size(&box_info);
			break;
		case 'a':set_align(&box_info);
			break;
		case 'b':box_info.Bold = ~box_info.Bold;
			break;
		case 'i':box_info.Italic = ~box_info.Italic;
			break;
		case 'u':box_info.Underline = ~box_info.Underline;
			break;
		default:printf("\nError!\n");
		}
		printf("\n");
		show_box(&box_info);
	}
	printf("Bye!\n");
	return 0;
}
void show_box(const BOX * pbox)
{
	char *a[] = { "letf", "center","right" };
	char *b[] = { "off", "on" };
	char *i[] = { "off", "on" };
	char *u[] = { "off", "on" };
	printf(" ID SIZE ALIGNMENT  B   I   U \n");
	printf("%3d %4d %9s %3s %3s %3s\n", pbox->Font_ID, pbox->Font_Size,
		a[pbox->Align], b[pbox->Bold], i[pbox->Italic], u[pbox->Underline]);
}
int menu(void)
{
	puts("f)change font    s)change size    a)change alignment");
	puts("b)toggle bold    i)toggle italic  u)toggle underline");
	puts("q)quit");

	return get_ch("fsabiuq");
}
int get_ch(char * str)
{
	int ch;

	while (ch = getchar(), strchr(str, ch) == NULL)
	{
		while (getchar() != '\n')
			;
		printf("Error! please enter (%s):", str);
	}
	while (getchar() != '\n')
		;
	return ch;
}
void get_id(BOX * pbox)
{
	int f;
	do
	{
		printf("Enter font ID(0-255):");
		scanf("%d", &f);
	} while (f > 255 || f < 0);
	pbox->Font_ID = f & FONTID;
	while (getchar() != '\n')
		;
}
void get_size(BOX * pbox)
{
	int s;
	do
	{
		printf("Enter font ID(0-255):");
		scanf("%d", &s);
	} while (s > 127 || s < 0);
	pbox->Font_Size = s & FONTSIZE;
	while (getchar() != '\n')
		;
}
void set_align(BOX * pbox)
{
	puts("Select alignment :");
	puts("l)left   c)center   r)right");
	switch (get_ch("lcr"))
	{
	case 'l':pbox->Align = LEFT; break;
	case 'c':pbox->Align = CENTER; break;
	case 'r':pbox->Align = RIGHT; break;
	default:printf("\nError\n");
	}
}


7.编写一个与练习6所描述的功能相同的程序。使用一个unsigned long来保存字体信息,使用位运算符而不是位成员来管理这些信息。

#include <stdio.h>
#include <string.h>
#define FONTID 0x00FF
#define FONTSIZE 0x7F00
#define ALIGN 0x18000
#define LEFT 0x00000
#define CENTER 0x08000
#define RIGHT 0x10000
#define BOLD 0x20000
#define ITALIC 0x40000
#define UNDERLINE 0x80000

void show_box(unsigned long f);
int menu(void);
int get_ch(char * str);
void get_id(unsigned long * pfont);
void get_size(unsigned long * pfont);
void set_align(unsigned long * pfont);

int main(void)
{
	unsigned long font = 1 | (12<<8) | LEFT | BOLD | ITALIC | UNDERLINE;
	char ch;
	
	show_box(font);
	while ((ch = menu()) != 'q')
	{
		switch (ch)
		{
		case 'f':get_id(&font);
			break;
		case 's':get_size(&font);
			break;
		case 'a':set_align(&font);
			break;
		case 'b':font ^= BOLD;
			break;
		case 'i':font ^= ITALIC;
			break;
		case 'u':font ^= UNDERLINE;
			break;
		default:printf("\nError!\n");
		}
		printf("\n");
		show_box(font);
	}
	printf("Bye!\n");
	return 0;
}
void show_box(unsigned long f)
{
	printf("  ID SIZE ALIGNMENT  B   I   U \n");
	printf("%4d %4d ", f & FONTID, (f & FONTSIZE)>>8);
	switch (f & ALIGN)
	{
	case LEFT: printf("%9s", "left"); break;
	case RIGHT: printf("%9s", "right"); break;
	case CENTER: printf("%9s", "center"); break;
	default: printf("%9s", "unknown"); break;
	}
	printf(" %3s %3s %3s\n\n", 
		(f & BOLD) == BOLD ? "off" : "on",
		(f & ITALIC) == ITALIC ? "off" : "on",
		(f & UNDERLINE) == UNDERLINE ? "off" : "on");

}
int menu(void)
{
	puts("f)change font    s)change size    a)change alignment");
	puts("b)toggle bold    i)toggle italic  u)toggle underline");
	puts("q)quit");

	return get_ch("fsabiuq");
}
int get_ch(char * str)
{
	int ch;

	while (ch = getchar(), strchr(str, ch) == NULL)
	{
		while (getchar() != '\n')
			;
		printf("Error! please enter (%s):", str);
	}
	while (getchar() != '\n')
		;
	return ch;
}
void get_id(unsigned long * pfont)
{
	int f;
	do
	{
		printf("Enter font ID(0-255):");
		scanf("%d", &f);
	} while (f > 255 || f < 0);
	f = f & FONTID;
	*pfont &= ~FONTID;
	*pfont |= f;
	while (getchar() != '\n')
		;
}
void get_size(unsigned long * pfont)
{
	int s;
	do
	{
		printf("Enter font ID(0-255):");
		scanf("%d", &s);
	} while (s > 127 || s < 0);
	s = (s << 8) & FONTSIZE;
	*pfont &= ~FONTSIZE;
	*pfont |= s;
	while (getchar() != '\n')
		;
}
void set_align(unsigned long * pfont)
{
	puts("Select alignment :");
	puts("l)left   c)center   r)right");
	switch (get_ch("lcr"))
	{
	case 'l':*pfont &= ~ALIGN; *pfont |= LEFT; break;
	case 'c':*pfont &= ~ALIGN; *pfont |= CENTER; break;
	case 'r':*pfont &= ~ALIGN; *pfont |= RIGHT; break;
	default:printf("\nError\n");
	}
}