1.编写一个函数,把二进制字符串转换为一个数值。例如,有下面的语句:
char * pbin = “01001001”;
那么把pbin作为参数传递给该函数后,它应该返回一个int类型的值25。
# include <stdio.h>
# include <limits.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
# define SIZE 33
int get_bstr(char * st , int n);
char * del_space(char * st);
int btoi(char * st);
int main(void)
{
char binstr[SIZE];
int num ;
printf("请输入二进制数(输入空行退出)\n");
while (get_bstr(binstr , SIZE) && binstr[0])
{
num = btoi(del_space(binstr));
printf("%s 是十进制是 %d\n" , binstr , num);
printf("请输入下一个二进制数(输入空行退出)\n");
}
return 0 ;
}
int get_bstr(char * st , int n)
{
char ch ;
int i = 0;
for (i = 0 ; i < n - 1 && (ch = getchar()) != '\n' && (isdigit(ch) || isspace(ch)) ; i++)
st[i] = ch ;
st[i] = '\0' ;
if (ch != '\n')
while (getchar() != '\n') ;
return i ;
}
char * del_space(char * st)
{
int i = 0 ;
char * find = NULL ;
while (find = strchr(st , ' '))
{
for (i = 0 ; find[i] ; i++)
find[i] = find[i + 1] ;
}
return st ;
}
int btoi(char * st)
{
int number = 0 ;
for (int i = 0 ; st[i] ; i++)
{
number <<= 1 ;
number |= (st[i] - '0');
}
return number ;
}
2.编写一个程序,通过命令行参数读取两个二进制字符串,对这两个二进制数使用~运算符、&运算符、|运算符和^运算符,并以二进制字符串形式打印结果(如果尤法使用交互式让程序读取字符串)。
# include <stdio.h>
# include <limits.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
# define SIZE 33
int str_bstr(char * st);
char * del_space(char * st);
int btoi(char * st);
void print_bstr(unsigned int n);
//int main(int argc , char * argv[])
int main(void)
{
char argv[3][SIZE] = {"a.exe" , "a0101b" , "341010"};
int num1 , num2 ;
/*
if (argc != 3)
{
fputs("参数错误", stderr);
exit(1);
}
*/
str_bstr(argv[1]) ;
str_bstr(argv[2]) ;
num1 = btoi(del_space(argv[1]));
num2 = btoi(del_space(argv[2]));
printf("~%s == " ,argv[1]);
print_bstr(~num1);
putchar('\n');
printf("~%s == " ,argv[2]);
print_bstr(~num2);
putchar('\n');
printf("%s & %s == " , argv[1] , argv[2]);
print_bstr(num1 & num2);
putchar('\n');
printf("%s | %s == " , argv[1] , argv[2]);
print_bstr(num1 | num2);
putchar('\n');
printf("%s ^ %s == " , argv[1] , argv[2]);
print_bstr(num1 ^ num2);
putchar('\n');
return 0 ;
}
int str_bstr(char * st)
{
int cur = 0 ; //当前索引位置
char ch ;
for (int i = 0 ; st[i]; i++)
if((isdigit(st[i]) && st[i] < '2') || isspace(st[i]))
{
ch = st[cur] ;
st[cur] = st[i] ;
st[i] = ch ;
cur++ ;
}
st[cur] = '\0' ;
return cur ;
}
char * del_space(char * st)
{
int i = 0 ;
char * find = NULL ;
while (find = strchr(st , ' '))
{
for (i = 0 ; find[i] ; i++)
find[i] = find[i + 1] ;
}
return st ;
}
int btoi(char * st)
{
int number = 0 ;
for (int i = 0 ; st[i] ; i++)
{
number <<= 1 ;
number |= (st[i] - '0');
}
return number ;
}
void print_bstr(unsigned int n)
{
static long loop = 0;
if (!loop && !n)
{
putchar('0');
return ;
}
if (n)
{
loop++ ;
print_bstr(n / 2) ;
}
else
return ;
putchar('0' + (n % 2));
if ((--loop % 4)== 0)
putchar(' ');
}
3.编写一个函数,接受一个int 类型的参数,并返回该参数中打开位的数量。在一个程序中测试该函数。
# include <stdio.h>
int count_openbit(unsigned int n);
int main(void)
{
int num ;
puts("请输入您要查看打开位总数的整数:(q 退出)");
while (scanf(" %d" , &num))
{
while (getchar() != '\n') ;
printf("%d 中打开位一共有%d个\n" , num , count_openbit(num));
puts("请输入您要查看打开位总数的整数:(q 退出)");
}
return 0 ;
}
int count_openbit(unsigned int n)
{
int count = 0 ;
while (n)
{
count += (n & 1) ;
n >>= 1 ;
}
return count ;
}
4.编写一个程序,接受两个int类型的参数,一个是值,一个是位的位置。如果指定位的位置为1,该函数返回1,否则返回0。在一个程序中测试该函数。
# include <stdio.h>
# include <stdlib.h>
# define COUNT_BIT 8
int bit_value(int value , int n);
int main(void)
{
int num ;
printf("请输入您要查看打开位状况的数(q 退出);");
while (scanf(" %d" , &num))
{
while (getchar() != '\n');
for (int i = 0 ; i < COUNT_BIT ; i++ )
printf("%d 第%d位打开状况: %s\n" ,num , i + 1 , bit_value(num , i + 1) ? "打开" : "关闭" );
printf("请输入您要查看打开位状况的数(q 退出);");
}
return 0 ;
}
int bit_value(int value , int n)
{
if (!n)
{
fputs("位置值不能为0.--bit_value" , stderr);
exit(1);
}
return (value & (1 << (n - 1)));
}
5.编写一个函数,把一个 unsigned int类型值中的所有位向左旋转指定数量的位。例如, rotate_l(x,4)把×中所有位向左移动4个位置,而且从最左端移出的位会重新出现在右端。也就是说,把高阶位移出的位放入低阶位。在一个程序中测试该函数。
# include <stdio.h>
# include <limits.h>
# include <stdlib.h>
void print_bstr(unsigned int num);
unsigned int rotate_l(unsigned int num , int loop);
int main(void)
{
int num ;
int loop ;
puts("请输入您要循环左移的值(q 退出)");
while (scanf(" %d" , &num))
{
while (getchar() != '\n');
puts("请输入您要循环左移的次数(q 返回上一级菜单)");
while (scanf(" %d" , &loop))
{
while (getchar() != '\n') ;
puts("===============================");
puts("您输入的值的二进制为");
print_bstr(num);
putchar('\n');
puts("循环左移后的二进制为");
print_bstr(rotate_l(num , loop));
putchar('\n');
puts("===============================");
puts("请输入您要循环左移的次数(q 返回上一级菜单)");
}
while (getchar() != '\n')
puts("请输入您要循环左移的值(q 退出)");
}
return 0 ;
}
unsigned int rotate_l(unsigned int num , int loop)
{
for (int i = 0 ; i < loop ; i++)
num = (num >> (CHAR_BIT * sizeof(unsigned int) - 1)) | (num << 1) ;
return num ;
}
void print_bstr(unsigned int num)
{
static int n = 0 ;
if (!num && !n)
return ;
if (num)
{
n++ ;
print_bstr(num >> 1);
}
else
return ;
putchar('0' + (num & 1));
if ((--n % 4) == 0)
putchar(' ');
}
6.设计一个位子段结构以储存下面的信息。
字体ID: 0~255之间的一个数;
字体大小: 0~127之间的一个数;
对齐: 0~2之间的一个数,表示左对齐、居中、右对齐;
加粗: 开(1)或闭(0);
斜体: 开(1)或闭(0);
在一个程序中使用该结构来打印字体参数,并使用循环菜单来让用户改变参数。例如,该程序的一个运行示例如下:
该程序要使用按位与运算符(&)和合适的掩码来把字体ID和字体大小信息转换到指定的范围内。
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <windows.h>
struct
{
unsigned int ID : 8 ;
unsigned int SIZE : 8 ;
unsigned int ALIGNMENT : 2 ;
unsigned int BOLD : 1 ;
unsigned int ITALIC : 1 ;
unsigned int UNDERLINE : 1 ;
}font;
void out_menu(void);
void show_setting(void);
int menu_choice(void);
void end(void);
void change_font(void);
void change_size(void);
void change_alignment(void);
void toggle_bold(void);
void toggle_italic(void);
void toggle_underline(void);
int main(void)
{
font.ID = 1 ;
font.SIZE = 12 ;
font.ALIGNMENT = 0 ;
font.BOLD = 0 ;
font.ITALIC = 0 ;
font.UNDERLINE = 0 ;
system("cls");
while (menu_choice())
{
system("cls");
}
return 0 ;
}
void out_menu(void)
{
static char * menu_str[] =
{
"Please select the menu label you need",
"f) change font s) change size a) change alignment",
"b) toggle bold i) toggle italic u) toggle underline",
"q) quit"
};
for (int i = 0 ; i < sizeof(menu_str) / sizeof(menu_str[0]) ; i++)
puts(menu_str[i]);
}
void show_setting(void)
{
int x ;
char tmp[10] ;
static char * set[] =
{
"ID" ,
"SIZE" ,
"ALIGNMENT" ,
"B" ,
"I" ,
"U"
};
const int width = 15 ;
for (int i = 0 ; i < sizeof(set) / sizeof(set[0]) ; i++)
printf("%*c%s%*c " , (width - strlen(set[i])) / 2 ,' ' , set[i],
(width - strlen(set[i])) / 2 ,' ' );
putchar('\n');
printf("%*c%d%*c " , (width - sprintf(tmp , "%d" , font.ID)) / 2 ,' ' , font.ID ,(width - sprintf(tmp , "%d" , font.ID)) / 2 ,' ');
printf("%*c%d%*c " , (width - sprintf(tmp , "%d" , font.SIZE)) / 2 ,' ' , font.SIZE ,(width - sprintf(tmp , "%d" , font.SIZE)) / 2 ,' ');
switch (font.ALIGNMENT)
{
case 0 : //left
printf("%*c%s%*c " , (width - strlen("left")) / 2 ,' ' , "left" , (width - strlen("left")) / 2 ,' ');
break ;
case 1: //center
printf("%*c%s%*c " , (width - strlen("center")) / 2 , ' ' , "center" , (width - strlen("center")) / 2 , ' ');
break ;
case 2 : //right
printf("%*c%s%*c " , (width - strlen("right")) / 2 , ' ' , "right" , (width - strlen("right")) / 2 , ' ' );
break ;
default :
printf("%*c%s%*c " , (width - strlen("Unknow type")) / 2 , ' ' , "Unknow type" , (width - strlen("Unknow type")) / 2 , ' ');
}
printf("%*c%s%*c " , (width - strlen(font.BOLD ? "on" : "off")) / 2 , ' ' , font.BOLD ? "on" : "off" , (width - strlen(font.BOLD ? "on" : "off")) / 2 , ' ');
printf("%*c%s%*c " , (width - strlen(font.ITALIC ? "on" : "off")) / 2 , ' ' , font.ITALIC ? "on" : "off" , (width - strlen(font.ITALIC ? "on" : "off")) / 2 , ' ');
printf("%*c%s%*c " , (width - strlen(font.UNDERLINE ? "on" : "off")) / 2 , ' ' , font.UNDERLINE ? "on" : "off", (width - strlen(font.UNDERLINE ? "on" : "off")) / 2 , ' ');
puts("\n");
}
int menu_choice(void)
{
const void (* menufun[])(void) = {end , change_font , change_size , change_alignment ,
toggle_bold , toggle_italic , toggle_underline};
const char * label = "qfsabiu" ;
char choice ;
char * find ;
int cmd = 0 ;
show_setting();
out_menu();
while (!scanf(" %c" , &choice) || !(find = strchr(label , tolower(choice))))
{
fputs("Invalid choice , please re-select" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
cmd = find - label;
menufun[cmd]();
return cmd ;
}
void end(void)
{
puts("Bye !");
}
void change_font(void)
{
unsigned int n = 0 ;
puts("Please enter the ID of your favorite font");
while (!scanf(" %d" , &n) || n >255)
{
if (n > 255)
fputs("Err: ID cannot exceed 0~255\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font.ID = n ;
}
void change_size(void)
{
unsigned int n = 0 ;
puts("Please enter the font size you want to set");
while (!scanf(" %d" , &n) || n > 127)
{
if (n > 127)
fputs("Err: Font sizes exceed 0~127\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font.SIZE = n ;
}
void change_alignment(void)
{
unsigned int n = 0 ;
puts("Please choose the alignment method");
puts("1) left 2)center 3)right");
while (!scanf(" %d" , &n) || n > 3)
{
if (n > 3)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font.ALIGNMENT = n - 1 ;
}
void toggle_bold(void)
{
unsigned int n = 0 ;
puts("Whether to open bold or not");
puts("0) close 1)open");
while (!scanf(" %d" , &n) || n > 1)
{
if (n > 1)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font.BOLD = n ;
}
void toggle_italic(void)
{
unsigned int n = 0 ;
puts("Whether to open italic or not");
puts("0) close 1)open");
while (!scanf(" %d" , &n) || n > 1)
{
if (n > 1)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font.ITALIC = n ;
}
void toggle_underline(void)
{
unsigned int n = 0 ;
puts("Whether to open underline or not");
puts("0) close 1)open");
while (!scanf(" %d" , &n) || n > 1)
{
if (n > 1)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font.UNDERLINE = n ;
}
7.编写一个与编程练习6功能相同的程序,使用unsigned long类型的变量储存字体信息,并且来管理这些信息。
用按位运算符而不是位成员来管理这些信息。
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <windows.h>
//声明字体位段结构体
unsigned int font = 8576;
void out_menu(void);
void show_setting(void);
int menu_choice(void);
void end(void);
void change_font(void);
void change_size(void);
void change_alignment(void);
void toggle_bold(void);
void toggle_italic(void);
void toggle_underline(void);
int main(void)
{
system("cls");
while (menu_choice())
system("cls");
return 0 ;
}
void out_menu(void)
{
static char * menu_str[] =
{
"Please select the menu label you need",
"f) change font s) change size a) change alignment",
"b) toggle bold i) toggle italic u) toggle underline",
"q) quit"
};
for (int i = 0 ; i < sizeof(menu_str) / sizeof(menu_str[0]) ; i++)
puts(menu_str[i]);
}
void show_setting(void)
{
static char * set[] =
{
"ID" ,
"SIZE" ,
"ALIGNMENT" ,
"B" ,
"I" ,
"U"
};
char tmp[10] ;
const int width = 15 ;
// 已知 ID:8位 size:8位 alignment:2位 bold:1位 italic:1位 underline:1位
// 一共是21位,int类型32位
unsigned int f = font & ((~0) >> (CHAR_BIT * sizeof(unsigned int) - 21)) ;
unsigned int id = f >> (21 - 8) ;
unsigned int size = (f >> (21 - 16)) & 0xff ;
unsigned int alignment = (f >> (21 - 18)) & 3 ;
unsigned int bold = (f >> 2) & 1 ;
unsigned int italic = (f >> 1) & 1 ;
unsigned int underline = f & 1 ;
for (int i = 0 ; i < sizeof(set) / sizeof(set[0]) ; i++)
printf("%*c%s%*c " , (width - strlen(set[i])) / 2 ,' ' , set[i],
(width - strlen(set[i])) / 2 ,' ' );
putchar('\n');
printf("%*c%d%*c " , (width - sprintf(tmp , "%d" , id)) / 2 ,' ' , id ,(width - sprintf(tmp , "%d" , id)) / 2 ,' ');
printf("%*c%d%*c " , (width - sprintf(tmp , "%d" , size)) / 2 ,' ' , size ,(width - sprintf(tmp , "%d" , size)) / 2 ,' ');
switch (alignment)
{
case 0 : //left
printf("%*c%s%*c " , (width - strlen("left")) / 2 ,' ' , "left" , (width - strlen("left")) / 2 ,' ');
break ;
case 1: //center
printf("%*c%s%*c " , (width - strlen("center")) / 2 , ' ' , "center" , (width - strlen("center")) / 2 , ' ');
break ;
case 2 : //right
printf("%*c%s%*c " , (width - strlen("right")) / 2 , ' ' , "right" , (width - strlen("right")) / 2 , ' ' );
break ;
default :
printf("%*c%s%*c " , (width - strlen("Unknow type")) / 2 , ' ' , "Unknow type" , (width - strlen("Unknow type")) / 2 , ' ');
}
printf("%*c%s%*c " , (width - strlen(bold ? "on" : "off")) / 2 , ' ' , bold ? "on" : "off" , (width - strlen(bold ? "on" : "off")) / 2 , ' ');
printf("%*c%s%*c " , (width - strlen(italic ? "on" : "off")) / 2 , ' ' , italic ? "on" : "off" , (width - strlen(italic ? "on" : "off")) / 2 , ' ');
printf("%*c%s%*c " , (width - strlen(underline ? "on" : "off")) / 2 , ' ' , underline ? "on" : "off", (width - strlen(underline ? "on" : "off")) / 2 , ' ');
puts("\n");
}
int menu_choice(void)
{
const void (* menufun[])(void) = {end , change_font , change_size , change_alignment ,
toggle_bold , toggle_italic , toggle_underline};
const char * label = "qfsabiu" ;
char choice ;
char * find ;
int cmd = 0 ;
show_setting();
out_menu();
while (!scanf(" %c" , &choice) || !(find = strchr(label , tolower(choice))))
{
fputs("Invalid choice , please re-select" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
cmd = find - label;
menufun[cmd]();
return cmd ;
}
void end(void)
{
puts("Bye !");
}
void change_font(void)
{
unsigned int n = 0 ;
puts("Please enter the ID of your favorite font");
while (!scanf(" %d" , &n) || n >255)
{
if (n > 255)
fputs("Err: ID cannot exceed 0~255\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font = (font & ~((0xff) << (21 - 8))) | (n << (21 - 8));
}
void change_size(void)
{
unsigned int n = 0 ;
puts("Please enter the font size you want to set");
while (!scanf(" %d" , &n) || n > 127)
{
if (n > 127)
fputs("Err: Font sizes exceed 0~127\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font =(font & ~((0xff) << (21 - 16))) | (n << (21 - 16));
}
void change_alignment(void)
{
unsigned int n = 0 ;
puts("Please choose the alignment method");
puts("1) left 2)center 3)right");
while (!scanf(" %d" , &n) || n > 3)
{
if (n > 3)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font = (font & ~(3 << 3)) | ((n - 1) << 3) ;
}
void toggle_bold(void)
{
unsigned int n = 0 ;
puts("Whether to open bold or not");
puts("0) close 1)open");
while (!scanf(" %d" , &n) || n > 1)
{
if (n > 1)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font = (font & ~(1 << 2)) | (n << 2) ;
}
void toggle_italic(void)
{
unsigned int n = 0 ;
puts("Whether to open italic or not");
puts("0) close 1)open");
while (!scanf(" %d" , &n) || n > 1)
{
if (n > 1)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font = (font & ~(1 << 1)) | (n << 1) ;
}
void toggle_underline(void)
{
unsigned int n = 0 ;
puts("Whether to open underline or not");
puts("0) close 1)open");
while (!scanf(" %d" , &n) || n > 1)
{
if (n > 1)
fputs("Err: Invalid selection, please re-enter the correct label\n" , stderr);
else
fputs("Err: Illegal input,Please try again.\n" , stderr);
while (getchar() != '\n') ;
}
while (getchar() != '\n') ;
font = (font & ~(1)) | n ;
}