1. 前言
不知道有多少同学正在自学C/C++, 无论你是一个在校学生, 还是已经是上班族. 如果你想从事或即将从事软件开发这个行业, C/C++都是一个几乎必须要接触的系统级程序开发语言. 虽然现在有Rust更安全的系统级编程语言作为C/C++的替代, 但作为入门, C应该还是要好好学的. C最早由B语言改进而来. 不出意外你应该已经想到了C/UNIX都是贝尔实验室的里奇和汤普逊所开发. 一个C影响了后来一系列开发语言, 一个UNIX影响了后来一系列操作系统. K&R C就是经典C, 那时C还没有标准化, 还没有ANSI标准, 所以K&R就是早期的C标准.
确切的说 K&R C 指的是由 C 语言创始人 Dennis Ritchie 和 Brian Kernighan 在其经典著作《The C Programming Language》(1978年第一版)中描述的早期 C 语言标准。也被称为 "经典 C" 或 "传统 C". Brian Kernighan 就是 K&R C中的K, Hello World程序就是他首先使用的. 当然这本书有第2版, 引入了一些ANSI的C标准. 这本书的练习题除部分少量的过时外, 大部分编程题还是很值得自己实践练习的.我这有两道练习题, 自己写了一下, 虽然不难, 但如果是初学者, 还是可以自己写完, 再看看别人的, 多参考学习.
写这些编程题有个感觉, 就像造车, 发动机要自己造, 变速箱要自己造, 底盘也要自己造, 外观要自己设计, 一切细节都要详细了解, 没有封装, 除了少量标准库函数可用, 一切要自己动手写. 就算是标准库中的函数, 你也完全根据它的功能, 自己去实现, 自己来封装. 那些大师早期哪有现成的库, 都是他们自己写的. 所以要多动手去写, 去实现自己的版本.
第 1 章内容不多, 尽量用本章介绍的内容来完成作业.
2. 练习 1 - 12 习题及代码
下面是两个练习题:
练习1-12 编写一个程序, 以每行一个单词的形式打印其输入.
下面是代码, 因为很短, 所以没有加注释, 另外输入中如果有多个空白符 (制表, 空格), 会忽略:
#include <stdio.h>
int main(void)
{
int ch;
while ((ch = getchar()) != EOF) {
if (ch != ' ' && ch != '\t' && ch != '\n') {
putchar(ch);
} else {
if (ch == '\n') {
putchar(ch);
} else {
while ((ch = getchar()) == ' ' || ch == '\t') {
continue;
}
putchar('\n');
putchar(ch);
}
}
}
return 0;
运行结果:
3. 练习 1 - 13 习题及代码
下面这道题在我的另几篇文章已实现垂直方向的直方图, 有兴趣的同学可以看另几篇文章.
练习1-13 编写一个程序, 打印输入中单词的直方图. 水平方向的直方图比较容易绘制, 垂直方向的直方图则要困难些.
下面是代码 (代码有一些问题,有兴趣的同学可以改进):
#include <stdio.h>
#define MAX 20 /*统计最长为20个字符的单词*/
#define MAXNUM 26 /*某个长度最多统计25个*/
void initwords(int *pw, int len);
void countwords(int *pw, int len);
void printhtgm(int *pw, int len);
void putpatterns(char ch, int n, int width);
void putspaces(int n);
void putline(int n);
void printXnum(int n);
int main(void)
{
int words[MAX + 1]; /*统计最长20个字符的单词*/
initwords(words, MAX + 1); /*初始化单词数量数组*/
countwords(words, MAX + 1); /*统计输入各长度㼿司数量*/
printhtgm(words, MAX + 1); /*打印水平直方图*/
return 0;
}
/*初始化单词数量数组*/
void initwords(int *pw, int len)
{
int i;
for (i = 1; i < len; i++) {
pw[i] = 0;
}
}
/*统计各长度单词数量*/
void countwords(int *pw, int len)
{
int ch, wordlen, wordin;
wordlen = wordin = 0;
while ((ch = getchar()) != '#') {
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
if (wordin == 0) { wordin = 1; }
if (wordlen < len - 1) { wordlen++; }
} else if (ch == ' ' || ch == '\t' || ch == '\n') {
if (wordin == 1) {
wordin = 0;
if (pw[wordlen] < MAXNUM - 1) { pw[wordlen]++; }
wordlen = 0;
}
}
}
if (pw[wordlen] < MAXNUM - 1) { pw[wordlen]++; }
}
/*打印水平直方图*/
void printhtgm(int *pw, int len)
{
int i;
putline(2);
putspaces(5);
putchar('Y');
putline(1);
for (i = len - 1; i > 0; i--) {
putspaces(3);
printf("%2d", i);
putchar('|');
putpatterns('*', pw[i], 2);
putline(1);
}
putspaces(5);
putchar('+');
putpatterns('-', MAXNUM * 2, 1);
putchar('>');
putspaces(1);
putchar('X');
putline(1);
printXnum(20);
putline(2);
}
/*打印X轴数字*/
void printXnum(int n)
{
if (n < 1 || n > MAXNUM) { return; }
int i;
putspaces(6);
for (i = 1; i <= n; i++) {
if (i >= 10) { putchar(' '); }
printf("%2d", i);
}
}
/*打印直方图案*/
void putpatterns(char ch, int n, int width)
{
if (n < 1 || n > MAXNUM * 2) { return; }
int i;
for (i = 0; i < n; i++) {
putspaces(width - 1);
putchar(ch);
}
}
/*打印Y轴缩进*/
void putspaces(int n)
{
int i;
for (i = 0; i < n; i++) {
putchar(' ');
}
}
/*空格打印*/
void putline(int n)
{
int i;
for (i = 0; i < n; i++) { putchar('\n'); }
}
运行结果:
下面是输入一些测试单词
下面是输入歌曲 << The day you went away >> 的歌词结果:
4. 结语
喜欢就点赞收藏, 您的支持是我创作的动力.