选择结构
- 对于if语句而言,如果条件表达式是"!=0"或"==0",有一个信达雅的写法:
如if(n!=0)改写为if(n) - switch 语句格式
switch(表达式){
case 常量表达式1:
…
break;
case 常量表达式2:
…
break;
……
default:
…
}
如果没有break,将会全部执行。
练习:
例题4-1 一元二次方程求根
题目描述 求一元二次方程ax2+bx+c=0的根,三个系数a, b, c由键盘输入,且a不能为0,但不保证b2-4ac>0。
程序中所涉及的变量均为double类型。 输入 以空格分隔的一元二次方程的三个系数,双精度double类型 输出
分行输出两个根如下(注意末尾的换行): r1=第一个根 r2=第二个根 结果输出时,宽度占7位,其中小数部分2位。
如果方程无实根,输出一行如下信息(注意末尾的换行): No real roots!
#include <cstdio>
#include<cmath>
int main()
{
double a, b, c, p;
scanf("%lf %lf %lf", &a, &b, &c);
p =( b * b) - (4 * a*c);
if (a != 0 && p >= 0)
{
printf("r1=%7.2f\nr2=%7.2f", (-b + sqrt(p)) / (2 * a), (-b - sqrt(p)) / (2 * a));
}
else
{
printf("No real roots!");
}
return 0;
}
例题4-2 比较交换实数值
题目描述 从键盘输入2个实数,按照代数值由小到大的顺序输出这两个数。 输入 用空格分隔的两个实数。 输出
从小到大输出这两个实数,中间以空格来分隔,小数在前,大数在后。 小数点后保留2位小数。 末尾输出换行符。
#include <cstdio>
int main()
{
double a, b, c;
scanf("%lf %lf", &a, &b);
if (a > b)
{
c = a;
a = b;
b = c;
}
printf("%.2f %.2f\n", a, b);
return 0;
}
例题4-3 比较交换3个实数值,并按序输出
题目描述
从键盘输入3个实数a, b, c,通过比较交换,将最小值存储在变量a中,最大值存储在变量c中,中间值存储在变量b中,并按照从小到大的顺序输出这三个数a, b, c。
末尾输出换行。
输入
输入以空格分隔的三个实数
输出
按照从小到大的顺序输出这三个实数,中间以空格分隔,最小值在前,最大值在后。小数点后保留2位小数。
注意末尾的换行。
#include "stdafx.h"
#include <cstdio>
int main()
{
double a, b, c,d;
scanf("%lf %lf %lf", &a, &b,&c);
if (a > b)
{
d = a; a = b; b = d;
}
if (b > c)
{
d = b; b = c; c = d;
}
if (a>b)
{
d = a; a = b; b = d;
}
printf("%.2f %.2f %.2f\n", a, b,c);
return 0;
}
习题4-4 三个整数求最大值
题目描述
有3个整数a, b, c,由键盘输入,输出其中最大的数。
输入
以空格分割的三个整数。
输出
三个数中的最大值,末尾换行。
#include <cstdio>
int main()
{
int a, b, c,max;
scanf("%d %d %d", &a, &b,&c);
max = a;
if (max < b)
max=b;
if (max < c)
max = c;
printf("%d\n",max);
return 0;
}
习题4-10-1 奖金计算
题目描述
某企业发放的奖金根据利润提成。利润I低于或等于100000时,奖金可提10%;利润高于100000元,低于200000元(100000<I<=200000)时,低于100000元的部分仍按10%提成,高于100000元的部分提成比例为7.5%;200000<I<=400000时,低于200000元的部分仍按上述方法提成(下同),高于200000元的部分按5%提成;400000<I<=600000元时,高于400000元的部分按3%提成;600000<I<=1000000时,高于600000元的部分按1.5%提成;I>1000000元时,超过1000000元的部分按1%提成。
从键盘输出当月利润I,求应发奖金数,奖金精确到分。
要求用if语句实现。
输入
企业利润,小数,双精度double类型
输出
应发奖金数,保留2位小数,末尾换行。
#include <cstdio>
int main()
{
double I,bonus;
scanf("%lf", &I);
if (I <= 100000)
bonus = I * 0.1;
if (I > 100000 && I <= 200000)
bonus = 10000 + (I - 1000000 * .075);
if (I > 200000 && I <= 400000)
bonus = 100000 * 0.175 + (I - 200000)*.05;
if (I > 400000 && I <= 600000)
bonus = 100000 * 0.225 + (I - 400000)*.03;
if (I >600000 && I <=1000000)
bonus = 100000 * 0.255 + (I - 600000)*.015;
if (I > 1000000)
bonus = 100000 * 0.27 + (I - 1000000)*0.01;
printf("%.2f\n", bonus);
return 0;
}
循环结构
- while语句:
while(条件){
……
}//注意这里没有分号
- do while语句
do{
…
}while(条件);//注意这里有分号
- for语句
for(表达式A;表达式B;表达式C){
…
}//注意这里没有分号
另外,C语言中不允许在for语句的表达式A中定义变量,但C++可以。
- break /continue 语句
练习:
例题5-1-1 连续自然数求和
求1+2+3+…+100
要求用while语句实现
输入
无
输出
要求的和,末尾输出换行。
#include <cstdio>
int main()
{
int sum=0,i=1;
while(i<=100)
{
sum += i;
i++;
}
printf("%d\n", sum);
return 0;
}
例题5-1-2 连续自然数求和
题目描述
求1+2+3+…+100,即求
要求用do…while语句实现
输入
无
输出
计算结果,注意末尾输出换行。
#include <cstdio>
int main()
{
int sum=0,i=1;
do
{
sum += i;
i++;
} while (i <= 100);
printf("%d\n", sum);
return 0;
}
例题5-1-3 连续自然数求和
题目描述
求1+2+3+…+100,即求
要求用for语句实现
输入
无
输出
计算结果,末尾输出换行。
#include <cstdio>
int main()
{
int sum=0;
for (int i = 1; i <= 100; i++)
{
sum += i;
}
printf("%d\n", sum);
return 0;
}
例题5-1-4 连续自然数求和
题目描述
输入一个正整数N,求1+2+…+N,即求
要求在程序中使用break语句。
输入
要求输入的数据一定是一个正整数。
输出
计算的结果,连续N个自然数的和,末尾输出换行。
#include <cstdio>
int main()
{
int sum=0,i=1,N;
scanf("%d", &N);
while(1)
{
if (i > N) break;
else
{
sum += i;
i++;
}
}
printf("%d\n", sum);
return 0;
}
例题5-1-5 连续自然数求和
题目描述
编程实现求1+2+3+…和的程序,要求得到使使和数大于1000的最小正整数。
输入
无
输出
输出使1+2+3+…+N>1000的最小正整数N,末尾输出换行。
#include <cstdio>
int main()
{
int sum=0,i=1;
while(1)
{
if (sum <= 1000)
{
sum += i;
i++;
}
else
{
printf("%d\n", i-1);
break;
}
}
return 0;
}
例题5-6 矩阵输出
题目描述 输出以下4*5的矩阵
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
要求使用循环实现,注意每行输出5个数字,每个数字占3个字符的宽度,右对齐。
#include <cstdio>
int main()
{
for(int i=1;i<=4;i++)
for (int j = 1; j <= 5; j++)
{
if (j%5)
printf("%3d", i*j);
else
printf("%3d\n", i*j);
}
return 0;
}
例题5-7 求圆周率pi的近似值
题目描述
用如下公式π/4=1-1/3+1/5-1/7
求圆周率PI的近似值,直到发现某一项的绝对值小于10-6为止(该项不累加)。
要求输出的结果总宽度占10位,其中小数部分为8位。
程序中使用浮点型数据时,请定义为双精度double类型。
如果需要计算绝对值,可以使用C语言数学库提供的函数fabs,如求x的绝对值,则为fabs(x).
输入
无
输出
PI=圆周率的近似值
输出的结果总宽度占10位,其中小数部分为8位。
末尾输出换行。
…
#include <cstdio>
#include<cmath>
int main()
{
double i=0,pi=0;
while ((1 / (2*i+1)) >= 1E-6)//注意这里的1E-6
{
pi += (pow(-1,i)/( 2*i+1));//pow 最好两个参数都为double
i++;
}
printf("PI=%10.8f\n", 4 * pi);
return 0;
}
例题5-8 Fibonacci数列
题目描述
输入一个正整数n,求Fibonacci数列的第n个数。
Fibonacci数列的特点:第1,2个数为1,1。从第3个数开始,概述是前面两个数之和。即:
要求输入的正整数n不超过50.
输入 一个不超过50的正整数 输出 Fibonacci数列的第n个数,末尾输出换行。
#include <cstdio>
#include<cmath>
int main()
{
int n, output,a=1,b=1;
scanf("%d", &n);
if (n <= 50)
{
if (n == 1 || n == 2) printf("1\n");
else
{
for (int i = 3; i <= n; i++)
{
output = a + b;
a = b;
b = output;
}
printf("%d\n", output);
}
}
}
习题5-10 分数序列求和
题目描述
有如下分数序列
2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前 20 项之和。
求出次数列的前20项之和。
请将结果的数据类型定义为double类型。
输入 无 输出 小数点后保留6位小数,末尾输出换行。
int main()
{
double mun, den=3,a=2,b=3,output=(double)2/1+(double)3/2;
for (int i = 3; i <= 20; i++)
{
mun = a + b;
a = b;
b = mun;
output += (mun / den);
den = b;
}
printf("%.6f\n", output);
}
数组
- 如果想要给整个数组都赋初值0,可以有如下形式:
int a[10]={0};
int a[10]={};
- 如果数组的大小比较大(大概10^6级别),则需要将定义在主函数外面,否则会使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大。
- memset——对数组中每一个元素赋相同的值
格式: memset(数组名,值,sizeof(数组名));
一般有两种函数可以实现:memset/fill;
使用memset 要添加 string.h;
建议初学者赋0或-1,因为memset使用 “按字节赋值”;
如果要赋其他数字(比如1),建议使用fill;
memset的执行速度大于fill。
示例:
#include "stdafx.h"
#include <cstdio>
#include<cstring>
int main()
{
int a[5] = { 1,2,3,4,5 };
memset(a, 0, sizeof(a));
for (int i = 0; i < 5; i++)
{
printf("%10d", a[i]);
}
printf("\n");
memset(a, -1, sizeof(a));
for (int i = 0; i < 5; i++)
{
printf("%10d", a[i]);
}
printf("\n");
memset(a, 1, sizeof(a));
for (int i = 0; i < 5; i++)
{
printf("%10d", a[i]);
}
printf("\n");
}
输出结果:
0 0 0 0 0
-1 -1 -1 -1 -1
16843009 16843009 16843009 16843009 16843009
请按任意键继续. . .
- 字符数组的初始化有两种方式:
char str[15]={'G','O','O','D',' ','S','T','O','T','Y','!'};
char str[15]="GOOD STORY!";//注意单双引号的差别
注意,第二种方法仅限于初始化,程序其他的地方不能直接赋值整个字符串
- 字符数组输入函数:scanf / getchar / gets
- 字符串数组输出函数: printf / putchar / puts
- scanf “%s” 识别 空格作为字符串的结尾,不加&;
- getchar / putchar 输入输出单个字符,可以用来吸收换行符
示例:
int main()
{
char str[5][5];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
str[i][j] = getchar();
}
getchar();//这句可以把输入中每行末尾的换行符吸收掉!!!
}
putchar('\n\n\n');
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
putchar(str[i][j]);
}
putchar('\n');//注意单引号
}
}
有吸收换行符则输出结果=输入结果,没有吸收会误识别换行符
-
gets用来输入一行字符串,以换行符作为结束,
因此,scanf后如果要使用gets,需要先用getchar吸收scanf后的换行符 -
puts用输出一行字符串,并紧跟着一个换行
-
字符数组的存放方式
一维/二维数组的第二维 的末尾都有一个空字符\0表示存放的字符串的结尾;
空字符\0在使用gets或scanf输入字符串时会自动添加在字符串的后面并占用一个字符位;
puts/printf就是通过识别\0作为字符串的结尾来输出的。
只有char型数组需要\0作为结尾,int不需要;
\0不是空格;
字符数组的长度一定比实际存储字符串的长度至少多1;
如果不是使用scanf函数的%s或gets函数输入字符串(如使用getchar),请一定在输入的每个字符串后加入“\0”,否则printf和pufs输出字符串会因为无法识别字符串末尾而输出一大堆乱码。 -
string.h头文件中的函数
memset / strlen / strcmp / strcpy / strcat
strlen(字符数组): 得到字符数组中第一个\0前的字符的个数;
strcmp(字符数组1,字符数组2):比较,1小返回负数,相等0,1大正数;
strcpy(字符数组1,字符数组2):把字符数组2包括结束符"\0"一起复制给1;
strcat(字符数组1,字符数组2):把2接到1后面 -
stdio.h头文件中的函数
sscanf / sprintf
可以看成string+scanf/sring+printf
sscanf(字符数组1,“格式”,&字符串2);把字符数组1里的内容写到2所在地址;
sprintf(字符数组1,“格式”,字符串2);把字符串2写到1字符串数组里;
示例:
#include "stdafx.h"
#include <cstdio>
#include<cstring>
int main()
{
int n;
char str[100] = "123";
sscanf(str, "%d", &n);
printf("%d\n", n);
return 0;
}
输出结果:123
int main()
{
int n=123;
char str[100];
sprintf(str, "%d", n);
printf("%s\n", str);
return 0;
}
输出结果:123;
sscanf和printf可以进行复杂格式的输入和输出
示例:
将字符数组中str的内容按"%d:%lf,%s"的格式写到int型变量n、double型变量db、char型数组str2中,再将它们反序组合到str3中
#include "stdafx.h"
#include <cstdio>
#include<cstring>
int main()
{
int n;
double db;
char str1[100]="2019:3.14,hello",str2[100],str3[100];
sscanf(str1, "%d:%lf,%s", &n, &db, str2);
printf("n=%d,\ndb=%f,\nstr2=%s\n", n, db, str2);
sprintf(str3, "%s:%lf,%d", str2, db, n);
printf("str3=%s", str3);
return 0;
}
输出结果:
n=2019,
db=3.140000,
str2=hello
str3=hello:3.140000,2019请按任意键继续. . .
练习
习题6-4 有序插入
题目描述 有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入到数组中。
假设数组长度为10,数组中前9个数(这9个数要求从键盘上输入,输入时要满足自小到大的输入顺序)已经按从小到大进行排序。
然后再从键盘上输入一个整数,将此整数插入到前有序的9个数中,使得最终的10个数依然是从小到大有序的。
输入 第一行输入以空格分隔的9个整数数,要求按从小到大的顺序输入。
第二行输入一个整数
输出 从小到大输出这10个数,每个数一行。
#include <cstdio>
#include<cstring>
int main()
{
int a[15],b;
//scanf("%d %d %d %d %d %d %d %d %d",)
for (int i = 0; i <= 8; i++)
{
scanf_s("%d",&a[i]);
}
getchar();
scanf_s("%d", &b);
for (int i = 0; i <= 8; i++)
{
if (a[i] > b)
{
for (int j = 8; j >=i; j--)
{
a[j + 1] = a[j];
}
a[i] = b;
break;
}
}
for (int i = 0; i <= 9; i++)
{
printf("%d\n", a[i]);
}
return 0;
}
习题6-5 数组元素逆置
题目描述 将一个长度为10的整型数组中的值按逆序重新存放。
如:原来的顺序为1,2,3,4,5,6,7,8,9,0,要求改为0,9,8,7,6,5,4,3,2,1
输入 从键盘上输入以空格分隔的10个整数。
输出 按相反的顺序输出这10个数,每个数占一行。
#include <cstdio>
#include<cstring>
int main()
{
int a[10],b[10];
for (int i = 0; i <= 9; i++)
{
scanf_s("%d", &a[i]);
b[9 - i] = a[i];
}
//getchar();
for (int i = 0; i <= 9; i++)
{
printf("%d\n", b[i]);
}
return 0;
}
习题6-6 杨辉三角
按要求输入如下格式的杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1最多输出10层
输入 输入只包含一个正整数n,表示将要输出的杨辉三角的层数。 输出 对应于该输入,请输出相应层数的杨辉三角,每一层的整数之间用一个空格隔开
#include <cstdio>
#include<cstring>
int main()
{
int a[10][10],n;
scanf_s("%d", &n);
a[0][0] = 1;
printf("%d\n", a[0][0]);
for (int i = 2; i <= n; i++)
{
for(int j=1;j<=i;j++)
if (j == 1 )
{
a[i - 1][j - 1] = 1;
printf("%d ", a[i - 1][j - 1]);
}
else if (j == i)
{
a[i - 1][j - 1] = 1;
printf("%d\n", a[i - 1][ j - 1]);
}
else
{
a[i - 1][ j - 1] = a[i - 2][ j - 2] + a[i - 2][ j - 1];
printf("%d ", a[i - 1][j - 1]);
}
}
return 0;
}
习题6-12 解密
题目描述 有一行电文,已按如下规律译成密码:
A–>Z a–>z
B–>Y b–>y
C–>X c–>x
… …
即第一个字母变成第26个字母,第i个字母变成第(26-i+1)个字母,非字母字符不变。要求根据密码译回原文,并输出。
输入 输入一行密文 输出 解密后的原文,单独占一行。
#include <cstdio>
#include<cstring>
int main()
{
char str[100],str1[100];
scanf_s("%s", str,100);
int n;
n = strlen(str);
for (int i = 0; i <= n; i++)
{
if (str[i] >= 65 && str[i] <= 90)
str1[i] =26- (str[i] -65)+64;
else if (str[i] >= 97 && str[i] <= 122)
str1[i] = 26 - (str[i] - 97)+96;
else
str1[i] = str[i];
printf("%c", str1[i]);
}
return 0;
}
习题6-13 字符串比较
题目描述 比较两个字符串s1和s2的大小,如果s1>s2,则输出一个正数;若s1=s2,则输出0;若s1<s2,则输出一个负数。
要求:不用strcpy函数;两个字符串用gets函数读入。
例如:“A"与"C"相比,由于"A”<“C”,应输出负数,同时由于"A"与"C"的ASCII码差值为2,因此应输出"-2"。
同理:"And"和"Aid"比较,根据第2个字符比较的结果,“n"比"i"大5,因此应该输出"5”
输入 输入2行字符串
输出 一个整数,表示这两个字符串 比较的差值,单独占一行。
#include <cstdio>
#include<cstring>
int main()
{
char str1[100], str2[100];
gets_s(str1);
gets_s(str2);
int n = strlen(str1),output;
for (int i = 0; i <= n; i++)
{
if (str1[i] != str2[i])
{
output = str1[i] - str2[i];
printf("%d", output);
}
}
return 0;
}
例题6-1 逆序输出数组元素
题目描述 从键盘上输入10个整数,存储在一个长度为10的整型数组中,要求将输入的10个数逆序输出。
如输入为:0,1,2,3,4,5,6,7,8,9 输出为9,8,7,6,5,4,3,2,1,0
输入 10个整数,以空格分隔 输出 将输入的10个整数逆序输出,每个数占一行。
#include <cstdio>
#include<cstring>
int main()
{
int a[10], b[10];
for (int i = 0; i <= 9; i++)
{
scanf_s("%d", &a[i]);
b[9 - i] = a[i];
}
//getchar();
for (int i = 0; i <= 9; i++)
{
printf("%d\n", b[i]);
}
return 0;
}
例题6-2 数组求解Fibonacci数列问题
题目描述 Fibonacci数列的特点:第1,2个数为1,1。从第3个数开始,概述是前面两个数之和。即:
要求输出Fibonacci数列的前20个数。
输入 无 输出 Fibonacci数列的前20个数,每个数占一行。
#include <cstdio>
#include<cstring>
int main()
{
int a[20];
a[0] = 1;
a[1] = 1;
printf("%d\n", a[0]);
printf("%d\n", a[1]);
for (int i = 2; i <= 19; i++)
{
a[i] = a[i - 1] + a[i - 2];
printf("%d\n", a[i]);
}
return 0;
}
例题6-3 冒泡排序
题目描述 从键盘上输入10个整数,用冒泡法对这10个数进行排序(由小到大)。 输入 以空格分隔的10个整数 输出
依次输出排好序的10个整数,每个数占一行。
#include <cstdio>
#include<cstring>
int main()
{
int a[10],b;
for (int i = 0; i <= 9; i++)
{
scanf("%d", &a[i]);
}
for (int i = 0; i <= 8; i++)
{
for (int j = 0; j <= 8 - i; j++)
{
if (a[j] > a[j + 1])
{
b = a[j];
a[j] = a[j + 1];
a[j + 1] = b;
}
}
}
for (int i = 0; i <= 9; i++)
printf("%d\n", a[i]);
return 0;
}
例题6-4 矩阵转置
题目描述 将一个2行3列的矩阵(二维数组)行列互换,存储到另一个3行2列的矩阵中。
要求以整型数据为例来解答。
输入 输入2行数据,每行3个整数,以空格分隔。 输出 行列互换后的矩阵,3行,每行2个数据,以空格分隔。
#include <cstdio>
#include<cstring>
int main()
{
int a[2][3],b[3][2];
for (int i = 0; i <= 1; i++)
{
for (int j = 0; j <=2; j++)
{
scanf("%d", &a[i][j]);
b[j][i] = a[i][j];
}
}
for (int i = 0; i <= 2; i++)
{
for (int j = 0; j <= 1; j++)
{
if (j) printf("%d\n", b[i][j]);
else printf("%d ", b[i][j]);
}
}
return 0;
}
例题6-9 字符串求最大值
题目描述 从键盘上输入3个字符串,求出其中最大者。
输入 输入3行,每行均为一个字符串。输出 一行,输入三个字符串中最大者。
#include <cstdio>
#include<cstring>
int main()
{
char str1[100], str2[100],str3[100],max[100];
scanf("%s", str1);
scanf("%s", str2);
scanf("%s", str3);
if (strcmp(str1, str2) <= 0) sscanf(str2, "%s", max);
else sscanf(str1, "%s", max);
if(strcmp(max, str3) <= 0) sscanf(str3, "%s", max);
printf("%s", max);
return 0;
}