《C程序设计语言》习题解析 第1章 导言

来源:互联网 发布:知乎 进小区发传单 编辑:程序博客网 时间:2024/04/30 15:34

在学习C语言过程中,顺便整理了《C程序设计语言》一书中练习的代码,以便有不熟悉C语言的同学学习该书时有所参考。我也是刚接触C语言,代码中不当之处欢迎指出、讨论,愿我们共同进步!

后续将逐步更新章节习题。

更新习题目录:
习题1-13
习题1-14
习题1-15
习题1-16
习题1-17
习题1-18
习题1-19

练习1-13 编写一个程序,打印输入中单词长度的直方图。

#include <stdio.h>/*编写一个程序,打印输入中单词长度的直方图。*/#define IN 1#define OUT 0#define MAXSIZE 11 // max length of array#define OVFLOW 11 // input length of a word overflowint main(){    int c, i, j, novflow, count, state;    int nw[MAXSIZE];    novflow = state = count = 0;    for(i=0; i<MAXSIZE; i++){        nw[i] = 0;    }    while((c=getchar()) != EOF)    {        if(c == '\n' || c == '\t' || c == ' '){ // not a word            if(state == IN){                ++nw[count];                 state = OUT;            }        }else if(state == OUT){ // begining of a word            count = 1;            state = IN;        }else{ // in a word            ++count;        }        if(count >= OVFLOW){            count = 0;            state = OUT;            ++novflow;            continue;                   }    }    // print    for(i=1; i<MAXSIZE; ++i){        printf("%2d:", i);        for(j=0; j<nw[i]; ++j){            printf("*");        }        printf("\n");    }    printf("There are %d words overflow!", novflow);    return 0;}

1-13运行结果

练习1-14 编写一个程序,打印输入中各个字符出现的频度直方图

0-127 是7位ASCII 码的范围,是国际标准。
关于ASCII码参考:ACSII
ctype.h : 参考教材P227 isprint(c) c是包括空格的可打印字符

#include <stdio.h>#include <ctype.h>/*编写程序,打印输入中各个字符出现频度的直方图*/ #define IN 1#define OUT 0#define MAXSIZE 128int main(){    int c, i, len;    int nw[MAXSIZE];    len = 0;    for(i=0; i< MAXSIZE; ++i){        nw[i] = 0;    }    while( (c=getchar()) != EOF ){        if(c > 0 && c < MAXSIZE){            ++nw[c];        }    }    // print     for(i=1; i<MAXSIZE; ++i){        if(nw[i] > 0){            if(isprint(i)){ // 包含空格的可打印字符                 printf("%3d-%c:", i,i);            }else{                printf("%3d- :", i);            }            len = nw[i];            while(len>0){                putchar('*');                --len;            }            putchar('\n');        }    }    return 0;}

运行结果

练习1-15 重新编写1.2节中的温度转换程序,使用函数实现温度转换计算
本题是“使用函数实现温度转换计算”,意思是计算温度要用到函数:

#include <stdio.h>/*使用函数实现温度转换计算*/#define LOWER 0#define UPPER 300#define STEP 20float celsius(int fahr); int main(){    int fahr;    for(fahr=LOWER; fahr<=UPPER; fahr+=STEP)        printf("%3d %6.1f\n",fahr, celsius(fahr));    return 0;}float celsius(int fahr){    return (5.0/9.0)*(fahr-32.0);} 

练习1-16 修改打印最长文本行的程序的主程序main,使之可以打印任意长度的输入行,并尽可能多的打印文本。

下面代码可实现记录任意输入字符串的长度,同时可以打印MAXLINE个文本。

#include <stdio.h>#define MAXLINE 50 // 允许的输入行的最长长度 int getline(char line[], int maxline);void copy(char to[], char from[]); int main(){    int len; // 当前行的长度    int max; // 目前最长行的长度    char line[MAXLINE];    char longest[MAXLINE];      max = 0;    while((len = getline(line, MAXLINE)) > 0){        printf("%d, %s", len, line); // 打印长度         if(len > max){            max = len;            copy(longest, line);        }        if ( max > 0){            printf("%s", longest);        }    }    return 0;}/*getline:将一行读入,返回长度*/int getline(char s[], int lim){    int c, i, j;    j = 0;    for(i=0; (c=getchar())!=EOF && c!='\n'; ++i)                if(i<lim-2){            s[j] = c;            ++j;        }    if(c=='\n'){ // 由于打印一行之后要换行,所以要给\n留一个位置         s[j] = c;        ++j;        ++i;    }    // \0: 空字符,其值为0,它插入在数组末尾,以标记字符串的结束。    // 这一约定以被C语言采用。     s[j] = '\0';     return i;}/* copy char array */ void copy(char to[], char from[]){    int i;    i = 0;    while((to[i] = from[i]) != '\0')        ++i;}

练习1-17 编写一个程序,打印长度大于80字符的所有输入行

#include <stdio.h>/*1-17 编写一个程序,打印长度大于80字符的所有输入行 */#define MAXLINE 1000 // 允许的输入行的最长长度#define LOWERLIMIT 80 // 打印字符串长度的下限 int getline(char line[], int maxline);void copy(char to[], char from[]); int main(){    int len; // 当前行的长度    char line[MAXLINE];    char longest[MAXLINE];      max = 0;    while((len = getline(line, MAXLINE)) > 0){        printf("input length: %d\n", len);        if(len > LOWERLIMIT){            copy(longest, line);            printf("%s", longest);        }    }    return 0;}/*getline:将一行读入,返回长度*/int getline(char s[], int lim){    int c, i;    for(i=0; i< lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)        s[i]=c;    if(c=='\n'){        s[i] = c;        ++i;    }    s[i] = '\0';    return i;}void copy(char to[], char from[]){    int i;    i = 0;    while((to[i] = from[i]) != '\0')        ++i;}

练习1-18 编写一个程序,删除每个输入行末尾的空格及制表符,并删除全是空格的行

delTabAndSpace(s) 删除tab和空格
关于测试不太好测试,我是把\n去掉,输出的时候在string的末尾加一个字符看出有没有效果。

#include <stdio.h>/*1-18 编写一个程序,删除每个输入行末尾的空格及制表符,并删除全是空格的行 */#define MAXLINE 1000 // 允许的输入行的最长长度int getline(char line[], int maxline);int delTabAndSpace(char s[]); int main(){    char line[MAXLINE];    while((getline(line, MAXLINE)) > 0){        if(delTabAndSpace(line) > 0){            printf("%s", line);         }    }    return 0;}int delTabAndSpace(char s[]){    int i;    i = 0;    while(s[i] != '\n'){ /* find newline character */        ++i;    }    --i; /* back off from /n */    while(s[i] == ' ' || s[i] == '\t' ){        --i;    }    printf("i = %d\n", i);      if(i!=-1){        ++i;        s[i] = '\n'; /* put newline character back */               ++i;         s[i] = '\0';/* terminate the string */      }    printf("i = %d\n", i);          return i;} /*getline:将一行读入,返回长度*/int getline(char s[], int lim){    int c, i;    for(i=0; i< lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)        s[i]=c;    if(c=='\n'){        s[i] = c;        ++i;    }    s[i] = '\0';    return i;}

练习1-19 编写函数reverse(s), 将字符串s中的字符顺序颠倒过来。使用该函数编写一个程序,每次颠倒
一个输入行中的字符顺序

关键是 求s的长度 和 s 的转置

#include <stdio.h>/*1-19 编写函数reverse(s), 将字符串s中的字符顺序颠倒过来。使用该函数编写一个程序,每次颠倒一个输入行中的字符顺序 */#define MAXLINE 1000 // 允许的输入行的最长长度int getline(char line[], int maxline);void reverse(char s[]); int main(){    char line[MAXLINE];    while((getline(line, MAXLINE)) > 0){        reverse(line);        printf("%s", line);    }    return 0;}/* reverse string s */void reverse(char s[]){    int i, j, temp;    while(s[i]!='\0') /* find the ending of string s */        ++i;    --i; /* back off from \0*/    if(s[i]=='\n')        --i; /* leave new line in place */    j = 0;    while(j < i){        temp = s[j];        s[j] = s[i];        s[i] = temp;        ++j;        --i;        }}/*getline:将一行读入,返回长度*/int getline(char s[], int lim){    int c, i;    for(i=0; i< lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)        s[i]=c;    if(c=='\n'){        s[i] = c;        ++i;    }    s[i] = '\0';    return i;}

运行结果

参考文献:
[1] Brain W. Kernighan, Dennis M. Ritchie The C programming Languaue Second Edition
[2] Clovis T. Tondo, Scott E. Gimpel The C Answer Book Second Edition
[3] 谭浩强 C程序设计(第四版)

0 0
原创粉丝点击