现在的位置: 首页 > 设计导读 > 正文

【K&R C语言】第1章 导言

2011年04月13日 设计导读 ⁄ 共 2209字 ⁄ 字号 暂无评论

概要地介绍 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 函数,因为这个函数存在缓冲区溢出漏洞

抱歉!评论已关闭.