第十五章编程练习
本章第一个编程练习的内容是让我们将二进制字符串转换为一个数值,传递字符串指针,逻辑并不复杂,完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
int nfun(char * ptr);
int main(void){
char * pbin = "01001001";
int number;
number = nfun(pbin);
printf("01001001转换为十进制的值为:%d\n",number);
printf("Done!!!");
return 0;
}
int nfun(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
第二题要求我们通过命令行获取两个二进制字符串,对这两个二进制数使用四种位运算符,以二进制字符串形式打印结果。嘶,我们借用书中编程样例中的几个函数来展示二进制数字。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<stdlib.h>
char * itobs(int n, char * ps);
void show_bstr(const char * str);
int bstoi(char * ptr);
int main(int argc, char * argv[]){
char bin_str[CHAR_BIT * sizeof(int) + 1];
char jg_str[CHAR_BIT * sizeof(int) + 1];
if (argc != 3){
fprintf(stderr,"参数程序有误,请检查\n");
exit(EXIT_FAILURE);
}
int a, b;
a = bstoi(argv[1]);
b = bstoi(argv[2]);
char * jg = jg_str;
printf("使用~运算符\n");
itobs(~a,jg_str);
printf("%s 的~计算结果为:%s\n",argv[1],jg_str);
itobs(~b,jg_str);
printf("%s 的~计算结果为:%s\n",argv[2],jg_str);
printf("使用&运算符\n");
itobs(a&b,jg_str);
printf("%s & %s 的计算结果为:%s\n",argv[1],argv[2],jg_str);
printf("使用|运算符\n");
itobs(a|b,jg_str);
printf("%s | %s 的计算结果为:%s\n",argv[1],argv[2],jg_str);
printf("使用^运算符\n");
itobs(a^b,jg_str);
printf("%s ^ %s 的计算结果为:%s\n",argv[1],argv[2],jg_str);
printf("Done!!!");
return 0;
}
char * itobs(int n, char * ps){
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--,n>>=1){
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str){
int i = 0;
while (str[i]){
putchar(str[i]);
if (++i % 4 == 0 && str[i]){
putchar(' ');
}
}
}
int bstoi(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
接着,我们来看一下第三题的题目要求,要我们计算展示一个int类型的数据中打开位的数量为多少,完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<stdlib.h>
char * itobs(int n, char * ps);
void show_bstr(const char * str);
int bstoi(char * ptr);
int main(void){
char bin_str[CHAR_BIT * sizeof(int) + 1];
int input;
int number = 0;
scanf("%d",&input);
itobs(input,bin_str);
for (int i = 0; i < strlen(bin_str); i++){
if (*(bin_str + i) == '1'){
number++;
}
}
printf("%d中打开的位数量为%d\n",input,number);
printf("Done!!!");
return 0;
}
char * itobs(int n, char * ps){
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--,n>>=1){
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str){
int i = 0;
while (str[i]){
putchar(str[i]);
if (++i % 4 == 0 && str[i]){
putchar(' ');
}
}
}
int bstoi(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
接着,我们看一下第四题的要求,要我们接受两个int类型的值,一个为值,一个为位置,去看一下指定位置上的数据是否为开。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<stdlib.h>
char * itobs(int n, char * ps);
void show_bstr(const char * str);
int bstoi(char * ptr);
int main(){
char bin_str[CHAR_BIT * sizeof(int) + 1];
int input,wei;
int number = 0;
printf("请输入两个int类型的参数:\n");
scanf("%d %d",&input,&wei);
itobs(input,bin_str);
int w = 0;
for (int i = strlen(bin_str)-1; i >= 0 ; i--){
if (*(bin_str + i) == '1' && w == wei){
number = 1;
}
w++;
}
printf("%d中二进制第%d位,为%d\n",input,wei,number);
printf("Done!!!");
return 0;
}
char * itobs(int n, char * ps){
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--,n>>=1){
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str){
int i = 0;
while (str[i]){
putchar(str[i]);
if (++i % 4 == 0 && str[i]){
putchar(' ');
}
}
}
int bstoi(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
上面的实现,如果想放到单独的函数之中的话,将main()函数之中有用的部分抽离出来,然后做好合适的参数传递即可。下面,我们来看一下第五题的题目要求。要我们写一个函数实现,无符号整数值左移指定位,然后将左侧移出的高价位数据再次放到低阶位,完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<stdlib.h>
char * itobs(int n, char * ps);
void show_bstr(const char * str);
int bstoi(char * ptr);
unsigned int rotate_l(unsigned int n, unsigned int w);
int main(){
char bin_str[CHAR_BIT * sizeof(int) + 1];
char jg_str[CHAR_BIT * sizeof(int) + 1];
unsigned int input,wei,jgz;
int number = 0;
printf("请输入两个int类型的正数作为参数:\n");
scanf("%d %d",&input,&wei);
itobs(input,bin_str);
jgz = rotate_l(input,wei);
itobs(input,bin_str);
itobs(jgz,jg_str);
printf("%u也就是(%s)向左旋转%u位之后,得到%u,即(%s)\n",input,bin_str,wei,jgz,jg_str);
printf("Done!!!");
return 0;
}
unsigned int rotate_l(unsigned int n, unsigned int w){
const static int size = CHAR_BIT * sizeof(int);
char jg_s[CHAR_BIT * sizeof(int) + 1];
w %= size;
itobs(n,jg_s);
char z;
for (int i = 0; i < w; i++){
z = jg_s[0];
n<<=1;
itobs(n,jg_s);
jg_s[strlen(jg_s)-1] = z;
n = bstoi(jg_s);
}
return n;
}
char * itobs(int n, char * ps){
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--,n>>=1){
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str){
int i = 0;
while (str[i]){
putchar(str[i]);
if (++i % 4 == 0 && str[i]){
putchar(' ');
}
}
}
int bstoi(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
下面,我们来看一下第六题的题目要求,
(⊙o⊙)…,这一题的题目还蛮长的,细看一下,让我们去记录数据,有关于文字字体的数据,可以修改的那种数据。给了一个输出样例展示,我们就先按照这个样子去实现一下。完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<stdlib.h>
char * itobs(int n, char * ps);
void show_bstr(const char * str);
int bstoi(char * ptr);
struct{
unsigned int id : 8 ;
unsigned int size : 8 ;
unsigned int alignment : 2 ;
unsigned int bn : 1 ;
unsigned int in : 1 ;
unsigned int un : 1 ;
} font = {0,0,0,0,0,0};
void showMenu(void);
char getCz(void);
void showFont(void);
void functionF(void);
void functionS(void);
void functionA(void);
int main(){
char bin_str[CHAR_BIT * sizeof(int) + 1];
char jg_str[CHAR_BIT * sizeof(int) + 1];
char ch;
showFont();
showMenu();
ch = getCz();
while (getchar() != '\n')
continue;
while (ch != 'q'){
switch (ch)
{
case 'f':
functionF();
break;
case 's':
functionS();
break;
case 'a':
functionA();
break;
case 'b':
if (font.bn == 0){
font.bn = 1;
}else if (font.bn == 1){
font.bn = 0;
}
break;
case 'i':
if (font.in == 0){
font.in = 1;
}else if (font.in == 1){
font.in = 0;
}
break;
case 'u':
if (font.un == 0){
font.un = 1;
}else if (font.un == 1){
font.un = 0;
}
break;
default:
break;
}
showFont();
showMenu();
ch = getCz();
while (getchar() != '\n')
continue;
}
printf("Done!!!Bye!!!");
return 0;
}
void functionF(void){
unsigned int input;
printf("请输入新的字体号码:(0~255)\n");
while (scanf("%u",&input)!=1||input<0||input>255){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
font.id = input;
}
void functionS(void){
unsigned int input;
printf("请输入新的字体大小:(0~127)\n");
while (scanf("%u",&input)!=1||input<0||input>127){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
font.size = input;
}
void functionA(void){
char input;
printf("请选择新的对齐方式:\n");
printf("l)left c)center r)right\n");
while (scanf("%c",&input)!=1||!(input == 'l'||input == 'c'||input == 'r')){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
if (input == 'l'){
font.alignment = 0;
}else if (input == 'c'){
font.alignment = 1;
}else if (input == 'r'){
font.alignment = 2;
}
}
void showMenu(void){
printf("---------------------------菜单--------------------------\n");
printf("f)change font s)change size a)change alignment\n");
printf("b)toggle bold i)toggle italic u)toggle underline\n");
printf("q)quit\n");
}
char getCz(void){
char input;
while (scanf("%c",&input)!=1 || !(input == 'f'||input == 's'||input == 'a'
||input == 'b'||input == 'i'||input == 'u'||input == 'q') ){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
return input;
}
void showFont(void){
putchar('\n');
printf("ID SIZE ALIGNMENT B I U\n");
printf("%2u %4u ",font.id,font.size);
if (font.alignment == 0){
printf(" left ");
}else if (font.alignment == 1){
printf(" center ");
}else if (font.alignment == 2){
printf(" right ");
}
if (font.bn == 0){
printf(" off ");
}else if(font.bn == 1){
printf(" on ");
}
if (font.in == 0){
printf(" off ");
}else if(font.in == 1){
printf(" on ");
}
if (font.un == 0){
printf(" off ");
}else if(font.un == 1){
printf(" on ");
}
putchar('\n');
putchar('\n');
putchar('\n');
}
char * itobs(int n, char * ps){
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--,n>>=1){
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str){
int i = 0;
while (str[i]){
putchar(str[i]);
if (++i % 4 == 0 && str[i]){
putchar(' ');
}
}
}
int bstoi(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
第七题要求我们搞一个和练习6功能一样的程序,但是要用unsigned long类型的变量存储字体信息,而且使用按位运算符管理字体信息。(⊙o⊙)…首先我们先去看一下unsigned long的位数是多少。其实,作为起码32位的系统,应该是满足的。我们需要21位来存储信息,完整程序代码以及运行结果如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<stdlib.h>
#define IDMA 0x000
char * itobs(int n, char * ps);
void show_bstr(const char * str);
int bstoi(char * ptr);
static unsigned int fonts = 0x000000;
void showMenu(void);
char getCz(void);
void showFont(void);
void functionF(void);
void functionS(void);
void functionA(void);
unsigned int get_id();
unsigned int get_size();
unsigned int get_alignment();
unsigned int get_biu();
int main(){
char bin_str[CHAR_BIT * sizeof(int) + 1];
itobs(fonts,bin_str);
unsigned int fbn = get_biu(29);
unsigned int fin = get_biu(30);
unsigned int fun = get_biu(31);
char ch;
showFont();
showMenu();
ch = getCz();
while (getchar() != '\n')
continue;
while (ch != 'q'){
switch (ch)
{
case 'f':
functionF();
break;
case 's':
functionS();
break;
case 'a':
functionA();
break;
case 'b':
if (fbn == 0){
bin_str[29] = '1';
fonts = bstoi(bin_str);
}else if (fbn == 1){
bin_str[29] = '0';
fonts = bstoi(bin_str);
}
break;
case 'i':
if (fin == 0){
bin_str[30] = '1';
fonts = bstoi(bin_str);
}else if (fin == 1){
bin_str[30] = '0';
fonts = bstoi(bin_str);
}
break;
case 'u':
if (fun == 0){
bin_str[31] = '1';
fonts = bstoi(bin_str);
}else if (fun == 1){
bin_str[31] = '0';
fonts = bstoi(bin_str);
}
break;
default:
break;
}
showFont();
showMenu();
ch = getCz();
while (getchar() != '\n')
continue;
}
printf("Done!!!Bye!!!");
return 0;
}
void functionF(void){
unsigned int input;
char id[CHAR_BIT * sizeof(int) + 1];
char str[CHAR_BIT * sizeof(int) + 1];
printf("请输入新的字体号码:(0~255)\n");
while (scanf("%u",&input)!=1||input<0||input>255){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
itobs(input,id);
itobs(fonts,str);
int j = 24;
for (int i = 11; i <= 18; i++){
str[i] = id[j];
j++;
}
fonts = bstoi(str);
}
void functionS(void){
unsigned int input;
char id[CHAR_BIT * sizeof(int) + 1];
char str[CHAR_BIT * sizeof(int) + 1];
printf("请输入新的字体大小:(0~127)\n");
while (scanf("%u",&input)!=1||input<0||input>127){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
itobs(input,id);
itobs(fonts,str);
int j = 24;
for (int i = 19; i <= 26; i++){
str[i] = id[j];
j++;
}
fonts = bstoi(str);
}
void functionA(void){
char input;
char str[CHAR_BIT * sizeof(int) + 1];
printf("请选择新的对齐方式:\n");
printf("l)left c)center r)right\n");
while (scanf("%c",&input)!=1||!(input == 'l'||input == 'c'||input == 'r')){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
itobs(fonts,str);
if (input == 'l'){
str[27] = '0';
str[28] = '0';
}else if (input == 'c'){
str[27] = '0';
str[28] = '1';
}else if (input == 'r'){
str[27] = '1';
str[28] = '0';
}
fonts = bstoi(str);
}
void showMenu(void){
printf("---------------------------菜单--------------------------\n");
printf("f)change font s)change size a)change alignment\n");
printf("b)toggle bold i)toggle italic u)toggle underline\n");
printf("q)quit\n");
}
char getCz(void){
char input;
while (scanf("%c",&input)!=1 || !(input == 'f'||input == 's'||input == 'a'
||input == 'b'||input == 'i'||input == 'u'||input == 'q') ){
printf("您输入的值不合法,请重新输入!!\n");
while (getchar() != '\n')
continue;
}
return input;
}
unsigned int get_id(){
char id[9];
char str[CHAR_BIT * sizeof(int) + 1];
itobs(fonts,str);
int j = 0;
for (int i = 11; i <= 18 ; i++){
id[j] = str[i];
j++;
}
id[8] = '\0';
unsigned int r = bstoi(id);
return r;
}
unsigned int get_size(){
char id[9];
char str[CHAR_BIT * sizeof(int) + 1];
itobs(fonts,str);
int j = 0;
for (int i = 19; i <= 26 ; i++){
id[j] = str[i];
j++;
}
id[8] = '\0';
unsigned int r = bstoi(id);
return r;
}
unsigned int get_alignment(){
char id[9];
char str[CHAR_BIT * sizeof(int) + 1];
itobs(fonts,str);
int j = 0;
for (int i = 27; i <= 28 ; i++){
id[j] = str[i];
j++;
}
id[2] = '\0';
unsigned int r = bstoi(id);
return r;
}
unsigned int get_biu(int w){
char id[9];
char str[CHAR_BIT * sizeof(int) + 1];
itobs(fonts,str);
id[0] = str[w];
id[1] = '\0';
unsigned int r = bstoi(id);
return r;
}
void showFont(void){
putchar('\n');
printf("ID SIZE ALIGNMENT B I U\n");
unsigned int fid = get_id();
unsigned int fsize = get_size();
unsigned int falignment = get_alignment();
unsigned int fbn = get_biu(29);
unsigned int fin = get_biu(30);
unsigned int fun = get_biu(31);
printf("%2u %4u ",fid,fsize);
if (falignment == 0){
printf(" left ");
}else if (falignment == 1){
printf(" center ");
}else if (falignment == 2){
printf(" right ");
}
if (fbn == 0){
printf(" off ");
}else if(fbn == 1){
printf(" on ");
}
if (fin == 0){
printf(" off ");
}else if(fin == 1){
printf(" on ");
}
if (fun == 0){
printf(" off ");
}else if(fun == 1){
printf(" on ");
}
putchar('\n');
putchar('\n');
putchar('\n');
}
char * itobs(int n, char * ps){
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--,n>>=1){
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
void show_bstr(const char * str){
int i = 0;
while (str[i]){
putchar(str[i]);
if (++i % 4 == 0 && str[i]){
putchar(' ');
}
}
}
int bstoi(char * ptr){
int r = 0;
int count = strlen(ptr);
int m = 0;
for (int i = count -1; i >= 0; i--){
if (*(ptr + i) == '0'){
r += 0 * pow(2,m);
}else if (*(ptr + i) == '1'){
r += 1 * pow(2,m);
}
m++;
}
return r;
}
说实话,这按位运算符我着实弄不明白如何去运用,所以我用的方法比较笨,直接修改参数对应位上的值,是可以实现的,其实按位操作实际上也是单独修改某个位或者某几个位上面的值,可以说是大差不差,所以暂时用这个版本吧,因为比较赶时间嘛,等日后对位操作理解更深之后再回看这部分的内容。那么,接下来,要开始十六章喽。