C Primer Plus第十五章编程练习答案

news/2024/11/27 15:36:04/

学完C语言之后,我就去阅读《C Primer Plus》这本经典的C语言书籍,对每一章的编程练习题都做了相关的解答,仅仅代表着我个人的解答思路,如有错误,请各位大佬帮忙点出!

由于使用的是命令行参数常用于linux系统或者vscode,但此代码是运行于vs2022的,测试截图就不弄了。

1.编写一个函数,把二进制字符串转换为一个数值。例如,有下面的语 句:

char * pbin = "01001001";

那么把pbin作为参数传递给该函数后,它应该返回一个int类型的值25。

#include <stdio.h>
#include <string.h>
int convert(const char* str)
{int sum = 0, len = strlen(str);for (int i = len - 1, exp = 1; i >= 0; --i, exp *= 2){sum += (str[i] - '0') * exp;}return sum;
}
int main(void)
{const char* pbin = "01001001";printf("binary %s is decimal %d\n", pbin, convert(pbin));return 0;
}

2.编写一个程序,通过命令行参数读取两个二进制字符串,对这两个二 进制数使用~运算符、&运算符、|运算符和^运算符,并以二进制字符串形 式打印结果(如果无法使用命令行环境,可以通过交互式让程序读取字符 串)。

#include <stdio.h>
#include <stdlib.h>
int bstr_to_dec(const char* str)
{int val = 0;while (*str){val = val * 2 + (*str++) - '0';}return val;
}
char* itobs(int n, char* str)
{int sz = 8 * sizeof(int);for (int i = sz - 1; i >= 0; --i, n >>= 1){str[i] = (n & 1) + '0';}str[sz] = '\0';return str;
}
int main(int argc, char* argv[])
{char bstr[8 * sizeof(int) + 1];char str1[20] = {0};char str2[20] = { 0 };printf("请输入两个字符串:");scanf("%s%s", str1, str2);int v1 = bstr_to_dec(str1);int v2 = bstr_to_dec(str2);printf("~%s = %s\n", str1, itobs(~v1, bstr));printf("~%s = %s\n", str2, itobs(~v2, bstr));printf("%s & %s = %s\n", str1, str2, itobs(v1 & v2, bstr));printf("%s | %s = %s\n", str1, str2, itobs(v1 | v2, bstr));printf("%s ^ %s = %s\n", str1, str2, itobs(v1 ^ v2, bstr));return 0;
}

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

#include <stdio.h>
char* itobs(int n, char* str)
{int sz = 8 * sizeof(int);for (int i = sz - 1; i >= 0; --i, n >>= 1){str[i] = (n & 1) + '0';}str[sz] = '\0';return str;
}
int onbits(int x)
{int sum = 0;for (int i = 8 * sizeof(int) - 1; i >= 0; --i){sum += (x >> i) & 1;}return sum;
}
int main(int argc, char* argv[])
{int x = 11;char bstr[8 * sizeof(int) + 1];printf("%d(%s) has %d bit on.\n", x, itobs(x, bstr), onbits(x));return 0;
}

4.编写一个程序,接受两个int类型的参数:一个是值;一个是位的位 置。如果指定位的位置为1,该函数返回1;否则返回0。在一个程序中测试 该函数。

#include <stdio.h>
int test_bit(int x, int pos)
{return (x >> pos) & 1;
}
char* itobs(int n, char* str)
{int sz = 8 * sizeof(int);for (int i = sz - 1; i >= 0; --i, n >>= 1){str[i] = (n & 1) + '0';}str[sz] = '\0';return str;
}
int main(int argc, char* argv[])
{int x = 11;int sz = 8 * sizeof(int);char bstr[8 * sizeof(int) + 1];printf("%d(%s):\n", x, itobs(x, bstr));for (int i = sz - 1; i >= 0; --i){printf("The position %d is %d\n", i + 1, test_bit(x, i));}return 0;
}

5.编写一个函数,把一个 unsigned int 类型值中的所有位向左旋转指定数 量的位。例如,rotate_l(x, 4)把x中所有位向左移动4个位置,而且从最左端 移出的位会重新出现在右端。也就是说,把高阶位移出的位放入低阶位。在 一个程序中测试该函数。

#include <stdio.h>
char* itobs(int n, char* str)
{int sz = 8 * sizeof(int);for (int i = sz - 1; i >= 0; --i, n >>= 1){str[i] = (n & 1) + '0';}str[sz] = '\0';return str;
}
unsigned int rotate_l(unsigned int n, unsigned int b)
{static const int size = 8 * sizeof(int);b %= size;return (n << b) | (n >> (size - b));
}
int main(int argc, char* argv[])
{unsigned int val = 11;unsigned int rot = rotate_l(val, 4);char bstr1[8 * sizeof(int) + 1];char bstr2[8 * sizeof(int) + 1];printf("%u rotated is %u.\n", val, rot);printf("%s rotated is %s.\n", itobs(val, bstr1), itobs(rot, bstr2));return 0;
}

6.设计一个位字段结构以储存下面的信息。

字体ID:0~255之间的一个数;

字体大小:0~127之间的一个数;

对齐:0~2之间的一个数,表示左对齐、居中、右对齐;

加粗:开(1)或闭(0);

斜体:开(1)或闭(0);

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

该程序要使用按位与运算符(&)和合适的掩码来把字体ID和字体大小 信息转换到指定的范围内。

#include <stdio.h>
#include <ctype.h>
#include <string.h>typedef unsigned int uint;
typedef struct
{uint id : 8;uint sz : 7;uint at : 2;uint b : 1;uint i : 1;uint u : 1;
} font;static font ft = { 1, 12, 0, 0, 0, 0 };
const char* state[4] = { "off", "on" };
const char* alignment[7] = { "left", "center", "right" };
void eatline(void)
{while (getchar() != '\n')continue;
}
int get_first(void)
{int ch;do{ch = getchar();} while (isspace(ch));eatline();return ch;
}
int get_choice(void)
{int ch;printf("ID    SIZE    ALIGNMENT      B       I       U\n");printf("%-7u%-9u%-12s", ft.id, ft.sz, alignment[ft.at]);printf("%-8s%-8s%-8s\n", state[ft.b], state[ft.i], state[ft.u]);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");while (ch = get_first(), NULL == strchr("fsabiuq", ch)){printf("Please enter with f, s, a, b, i, u or q: ");}return ch;
}
void change_font(void)
{int ch;uint id;printf("Enter font id (0-255): ");while (scanf("%u", &id) != 1){while ((ch = getchar()) != '\n'){putchar(ch);}printf(" is not a id.\n");printf("Please enter a number such as 0, 5 or 255: ");}ft.id = id & 0XFF;
}
void change_size(void)
{int ch;uint sz;printf("Enter font sz (0-127): ");while (scanf("%u", &sz) != 1){while ((ch = getchar()) != '\n'){putchar(ch);}printf(" is not a size.\n");printf("Please enter a number such as 0, 5 or 127: ");}ft.sz = sz & 0x7F;
}
void change_alignment(void)
{int ch;printf("Select alignment:\n");printf("l) left    c) center    r) right\n");while (ch = get_first(), NULL == strchr("lcr", ch)){printf("Please enter with l, c or r: ");}ft.at = (ch == 'l' ? 0 : ch == 'c' ? 1 : 2);
}
void change_toggle(int ch)
{if (ch == 'b'){ft.b ^= 1;}else if (ch == 'i'){ft.i ^= 1;}else{ft.u ^= 1;}
}
int main(void)
{int ch;while ((ch = get_choice()) != 'q'){switch (ch){case 'f':{change_font();break;}case 's':{change_size();break;}case 'a':{change_alignment();break;}case 'b':case 'i':case 'u':{change_toggle(ch);break;}}putchar('\n');}printf("Bye!\n");return 0;
}

7.编写一个与编程练习 6 功能相同的程序,使用 unsigned long 类型的变 量储存字体信息,并且使用按位运算符而不是位成员来管理这些信息。

#include <stdio.h>
#include <ctype.h>
#include <string.h>
typedef unsigned long ulong;
static ulong ft = 0x00001180;
const char* state[4] = { "off", "on" };
const char* alignment[7] = { "left", "center", "right" };
void eatline(void)
{while (getchar() != '\n')continue;
}
int get_first(void)
{int ch;do{ch = getchar();} while (isspace(ch));eatline();return ch;
}
int get_choice(void)
{int ch;printf("ID    SIZE    ALIGNMENT      B       I       U\n");printf("%-7u%-9u%-12s", (ft >> 12) & 0XFF, (ft >> 5) & 0x7F, alignment[(ft >> 3) & 0x03]);printf("%-8s%-8s%-8s\n", state[(ft >> 2) & 1], state[(ft >> 1) & 1], state[ft & 1]);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");while (ch = get_first(), NULL == strchr("fsabiuq", ch)){printf("Please enter with f, s, a, b, i, u or q: ");}return ch;
}
void change_font(void)
{int ch;ulong id;printf("Enter font id (0-255): ");while (scanf("%lu", &id) != 1){while ((ch = getchar()) != '\n'){putchar(ch);}printf(" is not a id.\n");printf("Please enter a number such as 0, 5 or 255: ");}id &= 0XFF, id <<= 12;for (int i = 12; i < 20; ++i){ft &= ~(ulong)(1 << i);}ft |= id;
}
void change_size(void)
{int ch;ulong sz;printf("Enter font sz (0-127): ");while (scanf("%lu", &sz) != 1){while ((ch = getchar()) != '\n'){putchar(ch);}printf(" is not a size.\n");printf("Please enter a number such as 0, 5 or 127: ");}sz &= 0X7F, sz <<= 5;for (int i = 5; i < 12; ++i){ft &= ~(ulong)(1 << i);}ft |= sz;
}
void change_alignment(void)
{int ch;printf("Select alignment:\n");printf("l) left    c) center    r) right\n");while (ch = get_first(), NULL == strchr("lcr", ch)){printf("Please enter with l, c or r: ");}ft &= ~(ulong)(1 << 3), ft &= ~(ulong)(1 << 4);ft = ft | (ch == 'c' ? (ulong)(1 << 3) : ch == 'r' ? (ulong)(1 << 4) : 0);
}
void change_toggle(int ch)
{if (ch == 'b'){if (ft & 0x04){ft &= ~(ulong)(0x04);}else{ft |= (ulong)(0x04);}}else if (ch == 'i'){if (ft & 0x02){ft &= ~(ulong)(0x02);}else{ft |= (ulong)(0x02);}}else{if (ft & 0x01){ft &= ~(ulong)(0x01);}else{ft |= (ulong)(0x01);}}
}
int main(void)
{int ch;while ((ch = get_choice()) != 'q'){switch (ch){case 'f':{change_font();break;}case 's':{change_size();break;}case 'a':{change_alignment();break;}case 'b':case 'i':case 'u':{change_toggle(ch);break;}}putchar('\n');}printf("Bye!\n");return 0;
}


http://www.ppmy.cn/news/136025.html

相关文章

Linux驱动开发(I2C系统的重要结构体)

文章目录 前言一、I2C硬件框架二、i2c_adapter三、i2c_client四、i2c_msg总结 前言 本篇文章来讲解I2C系统的重要结构体&#xff0c;了解这些结构体对于编写I2C驱动来说是至关重要的&#xff0c;所以要想编写好一个I2C驱动程序那么就必须先了解这些结构体。 一、I2C硬件框架 …

如何破解excel打开密码

使用VBA 工程密码破解方法 新建一个excel文档&#xff0c;然后打开&#xff0c;同时按Alt和F11&#xff0c;进入VBA界面 点击菜单上的插入&#xff0c;模块 在新的窗口粘贴以下代码&#xff1a; Sub crack() Dim i As Long Dim FileName As String i 0 FileName Application…

Excel加密如何破解

我们遇到的加密的Excel一般是有打开密码或者有工作表保护的&#xff0c;或者两种都有的文件&#xff0c;有些情况可能是自己设置了密码的&#xff0c;这个时候自己重新把密码取消掉就可以了。但是遇到忘记密码或者不知道密码&#xff0c;这种情况就不是很好解决了。 不知道密码…

Excel文件解密软件

破解Excel文件的打开密码、也可以在不知道密码的情况下撤销工作表保护、编辑限制 解密软件&#xff1a;okfone EXCEL解密大师 链接 使用教程&#xff1a; 打开软件&#xff0c;点击进入【找回密码】开始进行破解打开密码&#xff0c;把Excel文件添加到软件中&#xff0c;选择…

EXCEL vba工程密码破解

这里写自定义目录标题 方法一:方法二: 方法一: 这种方法实际是避开VBA工程密码验证&#xff0c;即骗vba编辑器&#xff0c;该密码输入成功&#xff0c;请求放行。 不管他是破解还是欺骗 能达到我们的目的角开就行 1.新建一个工作簿&#xff0c;打开&#xff0c;按ALTF11&…

kail 暴力破解excel密码

excel密码破解 闲来无事&#xff0c;打开桌面上一个excel&#xff0c;居然需要密码&#xff0c;我靠&#xff0c;这是什么玩意&#xff0c;激起了我的好奇心&#xff0c;要不打打开&#xff0c;于是找出来闲来很久的KAIL&#xff0c;无所不能的linux系统 1、安装kail linux 这…

破解Excel工作表密码

打开受保护的Excel表格&#xff0c;按“ALT”“F11”键新建一个模块复制一下命令 Public Sub AllInternalPasswords()Breaks worksheet and workbook structure passwords. Bob McCormickprobably originator of base code algorithm modified for coverageof workbook struct…

使用宏破解EXCEL工作表保护密码的方法

前言 这也是以前写在自己网站的一篇文章&#xff0c;但是网站不打算续费了&#xff0c;所以搬运过来 原文 注&#xff1a;本文使用WPS 2016进行操作。 前段时间&#xff0c;有位朋友说文档保护的密码忘记了&#xff0c;现在需要修改&#xff0c;让我想想办法。 本来打算找…