前言
本文为业余学习《明解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;
}