明解C语言入门篇_第8章_动手编写各种程序吧

前言

本文为业余学习《明解C语言入门篇》的记录,包含代码清单和练习题。
开始学习时间:2022年8月21日
+++++++++++++++++++++++++++++++
第1章 初识C语言
第2章 运算和数据类型
第3章 分支结构程序
第4章 程序的循环控制
第5章 数组
第6章 函数
第7章 基本数据类型
第8章 动手编写各种程序吧
第9章 字符串的基本知识
第10章 指针
第11章 字符串和指针
第12章 结构体
第13章 文件处理
+++++++++++++++++++++++++++++++

第8章、动手编写各种程序吧

8-1 函数式宏

代码清单 8-1

//整数的平方和浮点数的平方(函数)

#include <stdio.h>

int sqr_int(int x);
double sqr_double(double x);

int main()
{
    int n;
    double x;

    printf("请输入一个整数:");
    scanf("%d",&n);
    printf("该数的平方是%d。\n",sqr_int(n));

    printf("请输入一个实数:");
    scanf("%lf",&x);
    printf("该数的平方是%f。\n",sqr_double(x));

    return 0;
}

int sqr_int(int x)
{
    return x*x;
}

double sqr_double(double x)
{
    return x*x;
}

代码清单 8-2

//整数的平方和浮点数的平方(函数式宏)

#include <stdio.h>

#define sqr(x) ((x)*(x))

int main()
{
    int n;
    double x;

    printf("请输入一个整数:");
    scanf("%d",&n);
    printf("该数的平方是%d。\n",sqr(n));

    printf("请输入一个实数:");
    scanf("%lf",&x);
    printf("该数的平方是%f。\n",sqr(x));

    return 0;
}

练习 8-1

//定义一个函数式宏diff(x,y),返回x、y二值之差

#include <stdio.h>

#define diff(x,y) ((x)-(y))

int main()
{
    int x,y;

    printf("请输入两个整数:");
    scanf("%d %d",&x,&y);
    printf("两数之差为%d。\n",x>y?diff(x,y):diff(y,x));

    return 0;
}

练习 8-2

/*
现定义如下函数式宏,其功能为返回x、y中的较大值。
    #define max(x,y) (((x)>(y)) ? (x):(y))
而下面两个使用了该宏的表达式的功能为计算a、b、c、d中的最大值。
    max(max(a,b),max(c,d))
    max(max(max(a,b),c),d)
请显示并观察它们是如何展开的。
*/

#include <stdio.h>

#define max(x,y) (((x)>(y)) ? (x) : (y))

int main()
{
    int a,b,c,d;

    printf("请输入四个整数:");
    scanf("%d %d %d %d",&a,&b,&c,&d);
    printf("它们中的最大值为%d。\n",max(max(a,b),max(c,d)));
    //(a>b?a:b) > (c>d?c:d) ? (a>b?a:b) : (c>d?c:d)
    printf("它们中的最大值为%d。\n",max(max(max(a,b),c),d));
    //((a>b?a:b) > c ? (a>b?a:b) : c) > d ? ((a>b?a:b) > c ? (a>b?a:b) : c) :d

    return 0;
}

练习 8-3

/*
请定义一个函数式宏swap(type,a,b)以使type型的两值互换
*/

#include <stdio.h>

#define swap(type,a,b) {type temp;temp=(a);(a)=(b);(b)=temp;}

int main()
{
    double x,y;

    printf("x = ");    scanf("%lf",&x);
    printf("y = ");    scanf("%lf",&y);
    swap(double,x,y);
    printf("这两个数已经互换了。\n");
    printf("x = %f\n",x);
    printf("y = %f\n",y);

    return 0;
}

代码清单 8-3

/*
响铃并显示宏定义
(书上说这是误例,不可编译、执行。但在VC6中编译通过,结果正确。
原因在于书上if和else后面未加大括号{}。或者直接if和else语句后面不加分号;亦可)
*/

#include <stdio.h>

#define puts_alert(str) {putchar('\a'); puts(str);}

int main()
{
    int n;

    printf("请输入一个整数:");
    scanf("%d",&n);

    if (n)
        puts_alert("这个数不是0。")
    else
        puts_alert("这个数是0。")

    return 0;
}

代码清单 8-4

//响铃并显示宏定义

#include <stdio.h>

#define puts_alert(str) (putchar('\a'),puts(str))

int main()
{
    int n;

    printf("请输入一个整数:");
    scanf("%d",&n);

    if(n)
    {
        puts_alert("这个数不是0。");
    }
    else
    {
        puts_alert("这个数是0。");
    }

    return 0;
}

8-2 排序

代码清单 8-5

//读取学生的身高并排序

#include <stdio.h>

#define NUMBER 5

void bsort(int a[],int n);

int main()
{
    int i;
    int height[NUMBER];

    puts("请输入5人的身高。");

    for(i=0;i<NUMBER;i++)
    {
        printf("%d号:",i+1);
        scanf("%d",&height[i]);
    }

    bsort(height,NUMBER);

    puts("按升序排列。");

    for(i=0;i<NUMBER;i++)
    {
        printf("%d号:%d\n",i+1,height[i]);
    }

    return 0;
}

void bsort(int a[],int n)
{
    int i,j;

    for(i=0;i<n-1;i++)
    {
        for(j=n-1;j>i;j--)
        {
            if(a[j]<a[j-1])
            {
                int temp=a[j];
                a[j]=a[j-1];
                a[j-1]=temp;
            }
        }
    }
}

8-3 枚举类型

代码清单 8-6

//显示所选动物的叫声

#include <stdio.h>

enum animal { Dog, Cat, Monkey, Invalid};

void dog();
void cat();
void monkey();
enum animal select();

int main()
{
    enum animal selected;

    do
    {
        switch(selected=select())
        {
            case Dog    :    dog();        break;
            case Cat    :    cat();        break;
            case Monkey    :    monkey();    break;
        }
    }while(selected!=Invalid);

    return 0;
}

void dog(void)
{
    puts("汪汪!!");
}

void cat(void)
{
    puts("喵~~!!");
}

void monkey(void)
{
    puts("唧唧!!");
}

enum animal select(void)
{
    int temp;

    do
    {
        printf("0…狗 1…猫 2…猴 3…结束:");
        scanf("%d",&temp);
    }while(temp<Dog || temp>Invalid);

    return temp;
}

练习 8-4

//改写代码清单8-5,用冒泡排序法从前往后排序。

#include <stdio.h>
#define NUMBER 5

void fsort(int a[],int n);

int main()
{
    int i;
    int height[NUMBER];

    printf("请输入%d人的身高。\n",NUMBER);
    for(i=0;i<NUMBER;i++)
    {
        printf("%d号:",i+1);
        scanf("%d",&height[i]);
    }

    fsort(height,NUMBER);

    puts("按升序排序了。");

    for(i=0;i<NUMBER;i++)
    {
        printf("%d号:%d\n",i+1,height[i]);
    }

    return 0;
}

void fsort(int a[],int n)
{
    int i,j;
    for(i=n-1;i>0;i--)
    {
        for(j=0;j<i;j++)
        {
            if(a[j]>a[j+1])
            {
                int temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
}

练习 8-5

//定义表示性别、季节等的枚举类型,并有效使用它们。

#include <stdio.h>

enum sex {male,female};
enum season    {spring=1,summer,autumn,winter};

void select_sex(enum sex m);
void select_season(int n);

int main()
{
    enum sex a;
    int b;

    printf("请选择你的性别【0…男士】【1…女士)】:");
    scanf("%d",&a);

    printf("你最喜欢的季节是【1…春季】【2…夏季】【3…秋季】【4…冬季】:");
    scanf("%d",&b);

    select_sex(a);
    select_season(b);

    return 0;
}

void select_sex(enum sex m)
{
    switch (m)
    {
        case male    :    printf("先生,");            break;
        case female    :    printf("女士,");            break;
        default        :    printf("请正确选择性别!");    break;
    }
}

void select_season(int n)
{
    switch (n)
    {
        case spring    :    puts("你最喜欢的是春季。");        break;
        case summer    :    puts("你最喜欢的是夏季。");        break;
        case autumn    :    puts("你最喜欢的是秋季。");        break;
        case winter    :    puts("你最喜欢的是冬季。");        break;
        default        :    puts("请正确选择季节。");        break;
    }
}

8-4 递归函数

代码清单 8-7

/*
    计算阶乘
*/

#include <stdio.h>

int factorial(int n);

int main()
{
    int num;

    printf("请输入一个整数:");
    scanf("%d",&num);

    printf("%d的阶乘为%d。\n",num,factorial(num));

    return 0;
}

int factorial(int n)
{
    return n>0?n*factorial(n-1):1;
}

练习 8-6

//不使用递归调用的方式来实现函数factorial。

#include <stdio.h>

int facorial(int n);

int main()
{
    int num;

    printf("请输入一个整数:");
    scanf("%d",&num);

    printf("%d的阶乘是%d。\n",num,factorial(num));

    return 0;
}

int factorial(int n)
{
    int result=1;
    int i;

    for(i=1;i<=n;i++)
    {
        result*=i;
    }

    return result;
}

练习 8-7

/*
    编写函数求出从n个不同整数中取出r个整数的组合数。
    此题转自知乎橘子香发表的内容,地址如下:
    https://zhuanlan.zhihu.com/p/466202314    
*/

#include<stdio.h>

int combination(int n,int r);
 
int main(void)
{
    int n;
    int r;
 
    do
    {
        printf("请输入整数n:");
        scanf("%d",&n);
        printf("请输入整数r:");
        scanf("%d",&r);
        if(n<=0||r<0||n<r)
        {
            puts("请输入正确数量!");
        }
    }while(n<=0||r<0||n<r);
 
    printf("%d个整数中取%d个整数的组合数为%d。\n",n,r,combination(n,r));
 
    return 0;
}

int combination(int n,int r)
{
    if (r == 1)
    {
        return n;
    }
    else if (r==0 || r==n)
    {
        return 1;
    }
    else 
    {
        return combination(n-1,r-1)+combination(n-1,r);
    }
}

练习 8-8

/*
    创建一个函数,使用辗转相除法求两个整数值x和y的最大公约数。
*/

#include <stdio.h>

int gcd(int x,int y);

int main()
{
    int x,y;

    printf("请输入整数x:");    scanf("%d",&x);
    printf("请输入整数y:");    scanf("%d",&y);

    printf("(%d,%d) = %d。\n",x,y,gcd(x,y));

    return 0;
}

int gcd(int x,int y)
{
    int max,min;
    int remainder;

    x>y?(max=x,min=y):(max=y,min=x);
    remainder=max%min;
    if(remainder!=0)
    {
        max=min;
        min=remainder;
        gcd(max,min);
    }
    else
    {
        return min;
    }

}

8-5 输入输出和字符

代码清单 8-8

//将标准输入的数据复制到标准输出

#include <stdio.h>

int main()
{
    int ch;
    while ((ch=getchar()) != EOF)
    {
        putchar(ch);
    }

    return 0;
}

代码清单 8-9

//计算标准输入流中出现的数字字符数

#include <stdio.h>

int main()
{
    int i,ch;
    int cnt[10]={0};

    while((ch=getchar()) != EOF)
    {
        switch(ch)
        {
        case '0' :    cnt[0]++;    break;
        case '1' :    cnt[1]++;    break;
        case '2' :    cnt[2]++;    break;
        case '3' :    cnt[3]++;    break;
        case '4' :    cnt[4]++;    break;
        case '5' :    cnt[5]++;    break;
        case '6' :    cnt[6]++;    break;
        case '7' :    cnt[7]++;    break;
        case '8' :    cnt[8]++;    break;
        case '9' :    cnt[9]++;    break;
        }
    }
    puts("数字字符的出现次数");
    for(i=0;i<10;i++)
    {
        printf("'%d':%d\n",i,cnt[i]);
    }

    return 0;
}

练习 8-9

//创建一个程序,计算标准输入中出现的行数

#include <stdio.h>

int main()
{
    int ch,line_num=0;

    while((ch=getchar()) != EOF)
    {
        if(ch=='\n')
        {
            line_num++;
        }
    }

    printf("行数为%d\n",line_num);

    return 0;
}

代码清单 8-10

//计算标准输入流中出现的数字字符数(第2版)

#include <stdio.h>

int main()
{
    int ch,i;
    int cnt[10]={0};

    while((ch=getchar()) != EOF)
    {
        if(ch>='0' && ch<='9')
        {
            cnt[ch-'0']++;
        }
    }

    puts("数字字符出现的次数");
    for(i=0;i<10;i++)
    {
        printf("'%d':%d\n",i,cnt[i]);
    }

    return 0;
}

代码清单 8-11

//显示EOF和数字字符的值

#include <stdio.h>

int main()
{
    int i;

    printf("EOF = %d\n",EOF);

    for(i=0;i<10;i++)
    {
        printf("'%d' = %d\n",i,'0'+i);
    }

    return 0;
}

练习 8-10

//改写代码清单8-10,将数字字符的出现次数用并排的*表示。

#include <stdio.h>

int main()
{
    int i,j;
    int ch;
    int max,temp;
    int cnt[10]={0};

    while ((ch=getchar()) != EOF)
    {
        if (ch>='0' && ch<='9')
        {
            cnt[ch-'0']++;
        }
    }

    puts("----横向分布图----");

    for(i=0;i<10;i++)
    {
        printf("%d:",i);
        for(j=0;j<cnt[i];j++)
        {
            putchar('*');
        }
        putchar('\n');
    }

    max=cnt[0];
    for(i=1;i<10;i++)
    {
        if(max<cnt[i])
        {
            max=cnt[i];
        }
    }
    temp=max;

    puts("---------------------纵向分布图---------------------");
    for(i=1;i<=max;i++)
    {
        for(j=0;j<10;j++)
        {
            if(cnt[j]>=temp)
            {
                printf("  *  ");
            }
            else
            {
                printf("     ");
            }
        }
        temp-=1;
        puts("");
    }

    puts("--------------------------------------------------");
    for(i=0;i<10;i++)
    {
        printf("  %d  ",i);
    }
    puts("");

    return 0;
}

总结

summary1

#include <stdio.h>

enum RGB {Red,Green,Blue};

int main()
{
    enum RGB color;

    printf("0~2的值:");
    scanf("%d",&color);

    printf("你选择了");
    switch (color)
    {
        case Red    : printf("红色。\n");    break;
        case Green    : printf("绿色。\n");    break;
        case Blue    : printf("蓝色。\n");    break;
    }

    return 0;
}

summary2

#include <stdio.h>

#define alert() (putchar('\a'))
#define putchar_ln(c) (putchar(c),putchar('\n'))

int main()
{
    int ch;
    int sum=0;

    while ((ch=getchar()) != EOF)
    {
        if(ch>='0' && ch<='9')
        {
            sum+=ch-'0';
        }

        if(ch=='\n')
        {
            alert();
            putchar('\n');
        }
        else
        {
            putchar_ln(ch);
        }
    }

    printf("所有数字之和为%d。\n",sum);

    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值