您的位置:首页 > 编程语言

C Primer Plus (第五版) 第十五章 位操作 编程练习

2015-06-11 17:49 337 查看
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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息