概要地介绍 C 语言,主要是通过实际的程序引入 C 语言的基本元素
1.1 入门 【Hello World】 1.4 符号常量 【A 打印华氏温度与摄氏温度对照表】 1.5 字符输入/输出 1.5.1 【B 文件复制】 1.5.2 【C 统计字符】 1.5.3 【D 行计数】 1.5.4 【E 单词计数】 1.6 数组 【F 统计各个数字、空白符以及所有其它字符出现的次数】 1.7 函数 【实现 power(base, n) 函数:计算整数 base 的 n 次幂】 1.9 字符数组 【寻找最长的文本行】 |
1.1 入门
1 2 3 4 5 6 7 | #include <stdio.h> int main(int argc, char *argv[]) { printf("hello, world\n"); return 0; } |
1.4 符号常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdio.h> #define LOWER 0 #define UPPER 300 #define STEP 20 /* print Fahrenheit-Celsius table */ int main() { int f; for (f = LOWER; f <= UPPER; f = f + STEP) printf("%3d %6.1f\n", f, (5.0/9.0)*(f-32)); } |
从这个程序中,你应该学习:
1 定义符号常量
2 使用 printf 进行格式化输出
1.5 字符输入/输出
1.5.1 文件复制
1 2 3 4 5 | 读一个字符; while (该字符不是文件结束指示符) { 输出刚读入的字符; 读下一个字符; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int main(int argc, char *argv[]) { int c; c = getchar(); while (c != EOF) { putchar(c); c = getchar(); } return 0; } |
赋值语句可以和条件判断合并到一起,就有如下更为精炼的版本
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> int main(int argc, char *argv[]) { int c; while ((c = getchar()) != EOF) putchar(c); return 0; } |
1.5.2 统计字符
使用 while 循环
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> /* count characters in input; 1st version */ int main(int argc, char *argv[]) { int nc = 0; while (getchar() != EOF) ++nc; printf("%d\n", nc); return 0; } |
while 循环改成 for 循环很容易, while (表达式) -> for ( ; 表达式 ; )
1 2 3 4 5 | while (getchar() != EOF) ++nc; 等价于 for ( ; getchar() != EOF ; ) ++nc; |
还可以把初始化部分放到 for 的第一个分号之前, 把执行语句放到第2个分号之后,这是有可能出现 for 的循环体为空的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> /* count characters in input; 2st version */ int main(int argc, char *argv[]) { int nc; for (nc = 0; gechar() != EOF; ++nc) ; printf("%.0f\n", nc); return 0; } |
1.5.3 行计数
实际上就是统计出现的回车符 ( '\n' )的个数
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int main(int argc, char *argv[]) { int c, nl = 0; while ((c = getchar()) != EOF) if (c == '\n') ++nl; printf("%d\n", nl); return 0; } |
1.5.4 单词计数
这里的程序对书上的程序进行了简化,只统计单词个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #define IN 1 /* inside a word */ #define OUT 0 /* outside a word */ int main(int argc, char *argv[]) { int c, nw = 0, state = OUT; while ((c = getchar()) != EOF) { if (c == ' ' || c == '\n' || c == '\t') state = OUT; else if (state == OUT) { state = IN; ++nw; } } printf("%d\n", nw); } |
1.6 数组
统计各个数字、空白符(包括空格符、制表符( '\t' )及换行符)以及所有其它字符出现的次数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <stdio.h> /* count digits, white space, others */ int main(int argc, char *argv[]) { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); } |
1.7 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> int power(int m, int n); /* test power function */ int main(int argc, char *argv[]) { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n", i, power(2,i), power(-3,i)); return 0; } /* power: raise base to n-th power; n >= 0 */ int power(int base, int n) { int i, p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; } |
power函数还可以这么写:
1 2 3 4 5 6 7 8 | int power(int base, int n) { int p; for (p = 1; n>0; n--) p = p * base; return p; } |
使用 自减运算符后,还可以变得更简洁
1 2 3 4 5 6 7 8 | int power(int base, int n) { int p = 1; while (n-->0) p = p * base; return p; } |
1.9 字符数组
字符数组是 C 语言中最常用的数组类型。下面我们通过编写一个程序,来说明字符数组以及操作字符数组的函数的用法。该程序读入从标准输入读入一组文本行,并把最长的文本行打印出来。该算法的基本框架非常简单:
while (还有未处理的行) if (该行比已处理的最长行还要长) { 保存该行为最长行 保存该行的长度 } 打印最长的行 |
这里的程序和书上更简单的,没有了copy函数,而是直接使用了C语言中的库函数,getline 函数也做了大幅简化,使用了 fgets函数来实现 getline,详情请见第145页。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <stdio.h> #include <string.h> define MAXLINE 1000 /* maximum input line length */ int getline(char line[], int maxline); int main(int argc, char *argv[]) { int len, max; char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */ max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; strcpy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); return 0; } /* getline: read a line into line, return length */ int getline(char line[],int max) { if (fgets(line, max, stdin) == NULL) return 0; else return strlen(line); } |
提示:尽量避免使用 gets 函数,因为这个函数存在缓冲区溢出漏洞