C程序设计语言:第一章练习

  练习1-1 在你自己的系统中运行”hello,world“程序。再有意去掉部分内容,会看到什么出错信息。

  练习1-2 做个实验,当printf函数的参数字符串中包含\c(其中c是上面的转义字符序列中未曾列出的某一个字符)时,观察一下啊情况。
  warning C4129: “c”: 不可识别的字符转义序列

  练习1-3 修改温度转换程序,使之能在转换表的顶部打印一个标题。

#include<stdio.h>
int main()
{
    float fahr, celsius;
    float lower, upper, step;

    lower = 0;
    upper = 300;
    step = 20;

    fahr = lower;
    printf(" Fahr    Celsius\n");
    while (fahr<=upper)
    {
        celsius = 5 * (fahr - 32) / 9;
        printf("%3.0f\t%6.1f\n", fahr, celsius);
        fahr = fahr + step;
    }
    getchar();
}

  练习1-4 编写一个程序打印摄氏温度转换为相应华氏温度的的对照表。

#include<stdio.h>
int main()
{
    float fahr, celsius;
    float lower, upper, step;

    lower = 0;
    upper = 300;
    step = 20;

    celsius= lower;
    printf(" Celsius    Fahr\n");
    while (celsius<=upper)
    {
        fahr = celsius * 9 / 5 + 32;
        printf("%3.0f\t%6.1f\n", celsius, fahr);
        celsius = celsius +step;
    }
    getchar();
}

  练习1-5 修改温度转换程序,要求以逆序(即按照从300度到0度的顺序)打印温度转换表。(尝试用for语句)

#include<stdio.h>
int main()
{
    float fahr, celsius;
    float lower, upper, step;

    lower = 0;
    upper = 300;
    step = 20;

    
    printf(" Fahr    Celsius\n");
    for (fahr = lower; fahr <= upper; fahr = fahr + step)
    {
        printf("%3.0f\t%6.1f\n", fahr, 5 * (fahr - 32) / 9);
    }
    getchar();
}

  练习1-6 验证表达式getchar()!=EOF的值是0还是1。

#include<stdio.h>
int main()
{
    int c;
    while (c=(getchar()!=EOF))
    {
        printf("%d isn't EOF\n", c);
    }
    printf("%d is EOF", c);
    getchar();
}

  练习1-7 编写一个打印EOF值的程序。

#include<stdio.h>
int main()
{
    printf("%d is EOF", EOF);
    getchar();
}

  练习1-8 编写一个统计空格、制表符、换行符个数的程序。

#include<stdio.h>
int main()
{
    int c, row_num, blank_num, t_num;
    row_num = blank_num = t_num = 0;
    while ((c=getchar())!=EOF)
    {
        switch (c)
        {
        case '\n':
            row_num++;
            break;
        case ' ':
            blank_num++;
            break;
        case '\t':
            t_num++;
        default:
            break;
        }
        printf("row_num:%d,blank_num:%d,t_num:%d\n", row_num, blank_num, t_num);
    }
}

  练习1-9 编写一个将输入复制到输出的程序,并将其中连续多个空格用一个空格代替。

#include<stdio.h>
int main()
{
    int a,b;
    while ((a=getchar())!=EOF)
    {
        if (a == ' '&& b==' ')  //如果发现a为空格,且排在后面的b也为空格则直接跳过该a
        {
            continue;
        }
        else
        {
            b = a;
        }
        printf("%c", b);
    }
}

  练习1-10 编写一个将输入复制到输出的程序,并将其中的制表符替换为\t,并把回退符替换为\b,并把反斜杠替换为\。这样可以将制表符和回退符以可见的方式显现出来。

#include<stdio.h>
int main()
{
    int c;
    while ((c=getchar())!=EOF)
    {
        switch (c)
        {
        case '\t':
            printf("\\t");      //putchar()一次只能输出一个字符不好实现效果
            break;
        case '\b':
            printf("\\b");
            break;
        case '\\':
            printf("\\\\");
            break;
        default:
            break;
        }
    }
}

  练习1-11 你准备如何测试单词计数程序?如果程序存在某种错误,那么什么样的输入最可能发现这类错误?

  该单词计数程序:

#include<stdio.h>

#define IN  1   //在单词内
#define OUT 0   //在单词外

//统计输入行数、单词数与字符数
int main()
{
    int c, nl, nw, nc, state;

    state = OUT;
    nl = nw = nc = 0;
    while ((c=getchar())!=EOF)
    {
        ++nc;
        if (c == '\n')
        {
            ++nl;
        }
        if (c == ' ' || c == '\n' || c == '\t')
        {
            state = OUT;
        }
        else if (state == OUT)
        {
            state = IN;
            ++nw;
        }
        printf("%d %d %d\n", nl, nw, nc);
    }
}

答:单词计数工作要从没有任何输入的情况下开始。此时,该程序的输出结果应该是“0 0 0”,即零行、零单词、零字符。
  接下来测试输入的单字符单词的情况。此时,该程序的输入结构应该是“1 1 2”,即一行、一个单词、两个字符(一个字符加上一个换行符)。
  再测试一个由两个字符组成的单词。此时,该程序的输入结果为“1 1 3”,即一行、一个单词、三个字符(两个字母加上一个换行符)。
  让后再测试两个单词的情况。首先,两个单词出现在同一行,此时的输出结果应该是“1 2 4”;然后,两个单词各占一行,此时的输出结果应该是“2 2 4”。
  那些满足边界条件的输入情况最有助于发现单词计数程序中的错误。这些边界条件包括:
  ——没有输入
  ——没有单词(只有换行符)
  ——没有单词(只有空格、制表符、和换行符)
  ——每个单词各占一行的情况(没有空格和制表符)
  ——单词出现于文本行行首的情况
  ——单词出现于一串空格之后的情况

  练习1-12 编写一个程序,以每行一个单词的形式打印其输入。
  自己的答案:

#include<stdio.h>

int main()
{
    int a, b, state;
    while ((a=getchar())!=EOF)
    {   //a不为空时,直接赋值给b
        if (a != ' ')
        {
            b = a;
            putchar(b);
        }
        //a位空时分b也为空即连续空格的情况,和b不为空格的情况
        if ((a == ' ')&&(b==' '))
        {
            continue;
        }
        if ((a == ' ') && (b != ' '))
        {
            b = a;
            putchar('\n');
        }
    }
}

  标准答案:

#include<stdio.h>

#define IN  1   //在单词内
#define OUT 0   //在单词外

//统计输入行数、单词数与字符数
int main()
{
    int c, state;

    state = OUT;
    while ((c=getchar())!=EOF)
    {
        if (c == ' ' || c == '\n' || c == '\t')
        {
            if (state == IN)
            {
                putchar('\n');      //一个单词输入结束
                state = OUT;
            }
        }
        else if (state == OUT)
        {
            state = IN;
            putchar(c);     //一个单词输入开始
        }
        else
        {
            putchar(c);     //在输入一个单词时
        }
    }
}

  练习1-13 编写一个程序,打印输入中单词长度的直方图。水平方向的直方图比较容易绘制,垂直方向的直方图则要困难些。

#include<stdio.h>

#define IN  1   //在单词内
#define OUT 0   //在单词外

int main()
{
    //c为输入的字符,state为当前状态,wLength为当前单词长度
    //Maxnum为数量最大的单词单词长度的个数
    int c,a,b,state,wLength,Maxnum;

    int wordLength[10];     //设置一个记录对应单词长度的个数的数组
    for (int i = 0; i < 10; i++)    //比如wordLength[1]表示单词长度为1的单词个数
    {
        wordLength[i] = 0;
    }

    state = OUT;
    wLength = 0;

    //记录输入中统计的得出的绘图数据
    //第一种方法
    while ((c=getchar())!=EOF)
    {   
        if ((c == ' ') || (c == '\t') || (c == '\n'))
        {
            if (state == IN)
            {
                state = OUT;
                ++wordLength[wLength];
                wLength = 0;
            }
            else
            {
                continue;
            }
        }
        else if(state==OUT)
        {
            wLength=1;
            state = IN;
        }
        else
        {
            ++wLength;
        }
    }

    //第二种统计数据方法
    /*
    while ((a = getchar()) != EOF)
    {
        if ((a != ' ') && (a != '\n'))
        {
            wLength++;
            b = a;
        }
        if (((a == ' ') || (a == '\n')) && (b == ' '))
        {
            continue;
        }
        else if (((a == ' ') || (a == '\n')) && (b != ' '))
        {
            wordLength[wLength]++;
            b = ' ';
            wLength = 0;
        }
    }
    */

    Maxnum = 9;
    /*这样写图表不漂亮
    for (int i = 0; i < 10; i++)
    {   
        if (Maxnum < wordLength[i + 1])
        {
            Maxnum = wordLength[i + 1];
        }
    }
    */

    for (int i = Maxnum; i >= 0; i--)
    {
        printf("%4d", i);
        for (int j = 0; j < 10; j++)
        {
            if (wordLength[j] >= i)
            {
                printf(" * ");
            }
            else
            {
                printf("   ");
            }   
        }
        printf("\n");
    }
    printf("   ");
    for (int i = 0; i < 10; i++)
    {
        printf("%3d", i);
    }

    getchar();
}

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

  基本思想跟上题类似。分三大块,第一块初始化各个数据,第二块采集各个数据,第三块画出直方图。本题可以利用ascii码来作为数组序号。

  练习1-15 重新编写1.2中的温度转换程序,使用函数实现温度转换计算。

#include<stdio.h>

void change(int lower, int upper, int step);

int main()
{
    float lower, upper, step;

    lower = 0;
    upper = 300;
    step = 20;
    change(lower, upper, step);

    getchar();
}

void change(int lower,int upper,int step)
{
    float fahr,celsius;
    fahr = lower;
    printf(" Fahr    Celsius\n");
    while (fahr <= upper)
    {
        celsius = 5 * (fahr - 32) / 9;
        printf("%3.0f\t%6.1f\n", fahr, celsius);
        fahr = fahr + step;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容