标签:c primer plus (第五版) 第十五章 位操作 编程练习
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"); } }
本文出自 “30岁学编程” 博客,请务必保留此出处http://xiongyi85.blog.51cto.com/8756903/1660958
C Primer Plus (第五版) 第十五章 位操作 编程练习
标签:c primer plus (第五版) 第十五章 位操作 编程练习
原文地址:http://xiongyi85.blog.51cto.com/8756903/1660958