【C语言】语言篇——程序设计入门

C站的小伙伴们大家好呀!我最近在学习刘汝佳老师的《算法竞赛入门经典》,跟着这本书来学习和做习题,在这里和大家一起分享进步。下面是本书的第一部分的语言篇。

算术表达式

#include<stdio.h>
int main(void)
{
	printf("%d\n",8/2);
	printf("%d\n",8/5);
	printf("%d\n",(-8)/5);
	printf("%d\n",8/(-5));
	return 0;
}

运行结果如下:
在这里插入图片描述
那如何计算和输出8/5的值呢?
我们来看下面的程序:

#include<stdio.h>
int main(void)
{
	printf("%.1f\n",8.0/5.0);
	printf("%.2f\n",8.0/5.0);
	printf("%.1f\n",8/5);
	printf("%d\n",8.0/5.0);
	return 0;
}

运行结果如下:
在这里插入图片描述
之所有有上面的输出,这是因为,在C语言中:

整数/整数=整数;
浮点数/浮点数=浮点数;
整数-浮点数=浮点数;

8和5被看作是整数,所以其商也为整数,1。
8.0和5.0被看作是浮点数,所以其商也是浮点数。
而%.1f和%.2f这里的"1"和"2"是小数点后的位数。

变量及其输入

#include <stdio.h>
int main(void)
{
	int a,b;
	scanf("%d%d",&a,&b);
	printf("%d\n",a+b);
	return 0;
}

 首先,声明两个整型变量a和b,然后利用scanf()函数从键盘读入数据并放到a和b中。
 scanf的占位符和变量的数据类型应一一对应,且每个变量前需加"&"符号。(可以把变量理解为"存放值的场所")在C语言中,变量有自己的数据类型,例如,int型变量存放整数值,而double型变量存放双精度浮点数。
例题1-1
输入底面半径r和高h,输出圆柱体的表面积,保留3位小数。

样例输入:
3.5 9
样例输出:
Area=274.889

分析
表面积=侧面积+底面积 × 2 \times 2 ×2
我们先来看下面这样一个错误的程序:

#include <stdio.h>
#define PI 3.14
int main(void)
{

	double r,h,s1,s2,Area;
	scanf("%d%d",&r,&h);//输入半径和高
	s1=2*PI*r*h;
	s2=2*PI*r*r;
	Area=s1+s2;
	printf("Area=%.3lf\n",Area);
	return 0;
}

错误原因:

代码实现

#include <stdio.h>
#define PI 3.14
int main(void)
{
    double r,h,s1,s2,Area;
	scanf("%lf%lf",&r,&h);//输入半径和高
	s1=2*PI*r*h;//侧面积
	s2=2*PI*r*r;//上底和下底底面积
	Area=s1+s2;
	printf("Area=%.3lf\n",Area);
	return 0;
}

 上述的代码中对于常量 π \pi π的处理是用宏定义来处理的。
编译程序时,所有的PI都会用3.14来替换,这一过程被称为编译时替换。在运行程序时,程序中所有的替换均已完成。

#define指令还可定义字符和字符串常量。前者使用单引号,后者使用双引号。如下所示:

#define ESC '\033'
#define OOPS "Now you have done it!"

此外,还可以利用关键字const类型限定符来定义常量。
const类型限定符
const所修饰的内容是不可变的,故只有可读性。
宏和const的区别是,在代码生成时所被处理的阶段不同,宏的替换在预编译(预处理)阶段,而const 常量则在编译阶段才确定,并分配内存。

const常量有数据类型,而宏没有数据类型。编译器只对宏在预编译阶段进行替换,却没有类型及安全检查,所以在替换过程中可能会出现错误。但是编译器却可以对const所定义的常量进行类型和安全检查,由宏引起的错误一般调试不出来,而const常量可以。

即,将上述代码改写为:

#include <stdio.h>
#include <math.h>
int main(void)
{

	double r,h,s1,s2,Area;
    const double PI = acos(-1.0);
	scanf("%lf%lf",&r,&h);//输入半径和高
	s1=2*PI*r*h;
	s2=2*PI*r*r;
	Area=s1+s2;
	printf("Area=%.3lf\n",Area);
	return 0;
}

补充:

接下来,我们看以下这条赋值语句

s1=2*PI*r*h;

 对于赋值语句,“赋值”是个动作,其确切的含义是,先计算右边的值,再赋值给左边的变量,覆盖它原来的值。变量是“喜新厌旧”的,即新的值将覆盖原来的值,一旦被赋予了新的值,变量中原来的值就丢失了。

顺序结构程序设计

例题1-2
输入一个三位数,分离出它的百位十位和个位,反转后输出。

样例输入:
127
样例输出:
721

分析
读入n,百位=n/100,十位=n/10%10,个位=n%10
代码实现

#include <stdio.h>
int main(void)
{
	int n;
	scanf("%d",&n);
	printf("%d%d%d\n",n%10,n/10%10,n/100);
	return 0;
}

这里有一个问题是,如果个位是0,例如输入250,输出052吗?
所以我们可以进一步改进:
方法一

#include <stdio.h>
int main(void)
{
	int n,m;
	scanf("%d",&n);
	m=n%10*100+n/10%10*10+n/100;
	printf("%d\n",m);
	return 0;
}

这样如果是输入250,就会输出52。
若改变输出格式,也可以输出052。

printf("%03d\n",m);

方法二分支结构:

#include <stdio.h>
int main(void)
{
	int n,m;
	scanf("%d",&n);
	if (n%10)   //个位不等于0
		printf("%d%d%d\n",n%10,n/10%10,n/100);
	else if (n%10==0)   //个位等于0
		printf("%d%d\n",n/10%10,n/100);
	return 0;
}

例题1-3
交换变量:输入两个整数m和n,交换二者的值,然后输出。

样例输入:
824 16
样例输出:
16 824

最简单的做法,输出时交换:

#include <stdio.h>
int main(void)
{
	int n,m;
	scanf("%d%d",&n,&m);
	printf("%d %d \n",m,n);
	return 0;
}

最经典的做法:三变量法:

#include <stdio.h>
int main(void)
{
	int n,m,t;
	scanf("%d%d",&n,&m);
	t=n;n=m;m=t;
	printf("%d %d\n",n,m);
	return 0;
}

不借助任何变量,进行交换:

#include<stdio.h>
int main()
{
 int m, n;
 scanf("%d%d", &m, &n);
 m = m + n;
 n = m - n;
 m = m - n;
 printf("%d %d\n", m, n);
 return 0;
}

分支结构程序设计

例题1-4
鸡兔同笼:
已知鸡和兔的总数量为n,总腿数为m。输入n和m,依次输出鸡的数目和兔的数目。如果无解,则输出No answer。
分析
假设鸡有a只,兔有b只,则a+b=n,2a+4b=m,联立解得a=(4n-m)/2,b=n-a。
怎样判断无解呢?
解出a或者b是负数。或者a或者b不是整数。

#include<stdio.h>
int main()
{
 int a, b, n, m;
 scanf("%d%d", &n, &m);
 a = (4*n-m)/2; b = n-a;
 if(m % 2 == 1 || a < 0 || b < 0)  //短路的方法计算逻辑表达式
 printf("No answer\n");
 else
 printf("%d %d\n", a, b);
 return 0;
}

C语言中的逻辑运算符,都是短路运算符,一旦能确定整个表达式的值,就不再进行计算了。
例题1-5:三个整数排序
输入三个整数,从小到大排序后输出。

样例输入
20 7 33
样例输出
7 20 33

分析
方法一这三个数有可能的六种排序:
abc,acb,bac,bca,cab,cba,所以我们可以利用分支结构一一列出:
(这里需要注意的是,千万不要忽略等于即不仅仅有可能是a<b<c,也有可能a<=b<=c)

#include <stdio.h>
int main(void)
{
	int a,b,c;
	scanf("%d%d%d",&a,&b,&c);
	if (a<=b && b<=c)
		printf("%d %d %d \n",a,b,c);
	else if (a<=c && c<=b)
		printf("%d %d %d \n",a,c,b);
	else if (b<=a && a<=c)
		printf("%d %d %d \n",b,a,c);
	else if (b<=c && c<=a)
		printf("%d %d %d \n",b,c,a);
	else if (c<=a && c<=b)
		printf("%d %d %d \n",c,a,b);
	else if (c<=b && c<=a)
		printf("%d %d %d \n",c,b,a);
	return 0;
}

方法二
利用前面讲过的三变量交换法,先检查a和b,使得a是a和b中最小的数,然后再检查,a和c使得a是a和c中最小的数(即a,b,c中最小的数),然后再检查b和c,使得b是b和c中最小的数。

#include <stdio.h>
int main(void)
{
	int a,b,c,t;
	scanf("%d%d%d",&a,&b,&c);
	if (a>b)
		t=a;a=b;b=t;
	if (a>c)
		t=a;a=c;c=t;
	if (b>c)
		t=b;b=c;c=t;
	printf("%d %d %d \n",a,b,c);
	return 0;
}

输出实验

转义字符\n

#include <stdio.h>
int main(void)
{
	printf("1\n2\n");
	printf("1\n\n2\n");
	return 0;
}

在这里插入图片描述
输出’’

#include <stdio.h>
int main(void)
{
	printf("\\\n");//编译器会把双斜线理解成单个字符'\'
	return 0;
}

在这里插入图片描述
表达式1/0 ,1.0/0.0,0.0/0.0

	printf("%d",0.0/0.0);
	printf("%d",1.0/0.0);
	printf("%d",1/0);

系统都会报错:

divide or mod by zero

习题

习题1-1平均数(average)
输入3个整数,输出他们的平均值,保留3位整数。

#include <stdio.h>
int main(void)
{
	double a,b,c;
	scanf("%lf%lf%lf",&a,&b,&c);
	printf("%.3lf\n",(a+b+c)/3);
	return 0;
}

习题1-2温度(temperature)
输入华氏温度f,输出对应的摄氏温度c,保留3位小数。提示:c=5(f-32)/9。

#include <stdio.h>
int main(void)
{
	double f;
	scanf("%lf",&f);
	printf("%.3lf\n",5*(f-32)/9);
	return 0;
}

习题1-3连续和(sum)
输入正整数n,输出1+2+3+……+n。

#include <stdio.h>
int main(void)
{
	int i,n,sum=0;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
		sum+=i;
	printf("%d\n",sum);
	return 0;
}

习题1-4正弦和余弦(sin和cos)
输入正整数n(n<360),输出n度的正弦、余弦函数值。

#include <stdio.h>
#include <math.h>
int main(void)
{
	double n;
	const double PI=3.1415;
	scanf("%lf",&n);
    printf("cos(%.1lf)=%lf,sin(%.1lf)=%lf\n",n,cos(n/180*PI),n,sin(n/180*PI));
	return 0;
}

这里需要注意的是,输入的n是角度,而cos(),sin()函数的参数是弧度制的,所以需要转化。
习题1-5
一件衣服95元,若消费满300元,可打八五折。输入购买衣服件数,输出需要支付的金额(单位:元),保留两位小数。

#include <stdio.h>
int main(void)
{
	int n;
	scanf("%d",&n);
	if (n*95>=300)
		printf("%.2lf\n",n*95*0.85);
	else
		printf("%d\n",n*95);
	return 0;
}

习题1-6 三角形(triangle)
输入三角形3条边的长度值(均为正整数),判断是否能为直角三角形的3个边长。如果可以,则输出yes,如果不能,则输出no。
如果根本无法构成三角形,则输出not a triangle。

#include <stdio.h>
int main(void)
{
	int a,b,c;
	scanf("%d%d%d",&a,&b,&c);
	if (a+b<=c || a+c<=b || b+c<=a)//无法构成三角形
		printf("not a triangle\n");
	else if (a*a+b*b=c*c || a*a+c*c=b*b || b*b+c*c=a*a)//直角
		printf("yes\n");
	else 
		printf("no\n");
	return 0;
}

习题1-7年份(year)
输入年份,判断是否为闰年。如果是,则输出yes,否则输出no。
判断闰年
能被4整除但不能被100整除,或者能被100整除。

#include <stdio.h>
int main(void)
{
	int n;
	scanf("%d",&n);
	if (n/400==0  ||  (n%4==0 && n/100!=0))
		printf("yes\n");
	else
		printf("np\n");
	return 0;
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

釉色清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值