5.C语言for循环
文章目录
5.1.1 for循环
- 引入:
- 阶乘:
n!=123*…*n
写一个程序,让用户输入n,然后计算出n! - 变量:
用户需要输入一个int的n,计算结果需要一个变量保存,可以是int的factor,在计算中需要有一个变量不断从1增到n,那可以是int的i。 - 程序:
- 阶乘:
//while循环:
int main()
{
int n;
scanf("%d", &n);
int fact = 1;//初始值
int i = 1;//循环当中判断条件
while (i <= n) {
fact *= i;//fact=fact*i
i++;
}
printf("%d!=%d\n", n, fact);
return 0;
}
for循环:
int main()
{
int n;
scanf("%d", &n);
int fact = 1;//初始值
int i = 1;//循环当中判断条件
for (i = 1; i <= n; i++)
//改法一:for (i = n; i >1; i--)
{
fact *= i;
}//初始动作;循环继续的条件;循环每轮要做的动作
printf("%d!=%d\n", n, fact);
return 0;
}
//改法二:
int i=n;
for(;n>1;n--){
fact*=n;
}
printf("%d!=%d\n",i,fact)
- ps:在for中三个条件可以省略一个的.
- 小套路:
在做求和程序时,记录结果的变量应该初始化为0,但在做求积的变量时记录结果应该初始化为1.- ps:(只有c99可以用)
循环控制变量i只在循环中被使用了,在循环外面没有用处,所以可以把变量i的定义写到for语句中.
for (int i = 1; i <= n; i++) {
fact *= i;
}
- ps:(只有c99可以用)
- 定义:
for循环像是一个计数循环:设定一个计数器,初始化它,然后在计数器到达某值之前,重复执行循环体,而它每执行一轮循环,计数器值以一定步进行调整,比如加1减1.- eg:
for(i=0//初始化;i<5//到达某个值;i=i+1//以一定步进行调整){
printf(“%d”,i);
}
for=对于 - eg:
for(count=10;count>0;count–)
读作:对于一开始的count=10,当count>0时,完成循环体,每一轮循环在做完循环体内语句后,使得count–.
- eg:
5.1.2 循环的计算和选择
- 循环次数:
for(i=0;i<n;i++)
则循环的次数是n,而循环结束后,i的值是n。循环的控制变量i,是从0开始还是从1开始,是判断i<n还是判断i<=n,对循环的次数,循环结束后变量的值都有影响.- eg:
1.{
int i;
for(i=0;i<5;i++){
printf("i=%d",i);
}
printf("\n最后i=%d\n",i);
return 0;
}
2.
{
int i;
for(i=1;i<=5;i++){
printf("i=%d",i);
}
printf("\n最后i=%d\n",i);
return 0;
}
- for和while的关系:
for==while
for(int i=1;i<=n;i++){
fact*=;
}
==
int i=1;
while(i<=n){
fact*=i;
i++;
}
- 格式:
- for(初始动作;条件;每轮的动作){
} - for中的每一个表达式都是可以省略的
- for(;条件;)==while(条件)
- for(初始动作;条件;每轮的动作){
- 循环的使用:
- for:有固定次数;
- do_while:必须执行一次的;
- while:其他情况都可以.
5.2.1 循环控制
- 素数:只能被1和自己整除的数,不包括1
eg:2,3,5,7,11,13,17…
程序:
int main()
{
int x;
scanf("%d", &x);
int i;
int isPrime = 1;//x是素数
for (i = 2; i < x; i++) {
if (x % i == 0) {
isPrime == 0;
break;
}
if (isPrime == 1) {
printf("是素数\n");
}
else {
printf("不是素数\n");
}
return 0;
}
- break VS continue
- break:跳出循环
- continue:跳过循环这一轮剩下的语句,进入下一轮
5.2.2 嵌套的循环
- 循环里面还是循环
- 找出100内的素数:
int main()
{
int x;
scanf("%d", &x);
//x = 6;
for (x = 2; x < 100; x++) {
int i;
int isPrime = 1;//x是素数
for (i = 2; i < x; i++) {
if (x % i == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
printf("%d ", x);
}
}
printf("\n");
return 0;
}
前50个素数:
while循环:
{
int x;
//scanf("%d", &x);
x = 2;
int cnt = 0;//计数器
while(cnt<50){
int i;
int isPrime = 1;//x是素数
for (i = 2; i < x; i++) {
if (x % i == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
printf("%d ", x);
cnt ++;
}
x++;
}
printf("\n");
return 0;
}
for 循环:
int main()
{
int x;
//scanf("%d", &x);
x = 2;
int cnt = 0;//计数器
//while(cnt<50){
for (x = 2; cnt < 50; x++) {
int i;
int isPrime = 1;//x是素数
for (i = 2; i < x; i++) {
if (x % i == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
printf("%d ", x);
cnt ++;
}
//x++;
}
printf("\n");
return 0;
}
5.2.3 从嵌套的循环中跳出
- 凑硬币:(枚举)
- 如何用1角,2角,5角的硬币凑出10元以下的金额?
1.接力break
int main()
{
int x;
int one, two, five;
int exit = 0;
scanf("%d", &x);
for (one = 1; one < x * 10; one++) {
for (two = 1; two < x * 10 / 2; two++) {
for (five = 1; five < x * 10 / 5; five++) {
if (one + two * 2 + five * 5 == x * 10) {
printf("可以用%d个1角加上%d个两角加上%d个5角得到%d\n元",one, two, five, x);
exit = 1;
break;
}
}if (exit == 1)break;
}if (exit == 1)break;
}
return 0;
}
2.goto
int main()
{
int x;
int one, two, five;
int exit = 0;
scanf("%d", &x);
for (one = 1; one < x * 10; one++) {
for (two = 1; two < x * 10 / 2; two++) {
for (five = 1; five < x * 10 / 5; five++) {
if (one + two * 2 + five * 5 == x * 10) {
printf("可以用%d个1角加上%d个两角加上%d个5角得到%d\n元",one, two, five, x);
goto out;
}
}if (exit == 1)break;
}if (exit == 1)break;
}
out:
return 0;
}
5.3.1 前n项求和:
- 1.f(n)=1+1/2+1/3+1/4…+1/n
int main()
{
int n;
int i;//分母
double sum = 0.0;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
sum += 1.0/ i;
}
printf("f(%d)=%f\n", n, sum);
return 0;
}
2.f(n)=1-1/2+1/3-1/4...+1/n
int main()
{
int n;
int i;//分母
double sum = 0.0;
//int sign = 1;
double sign = 1.0;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
//sum +=sign* 1.0/ i;
sum += sign / i;
sign = -sign;
}
printf("f(%d)=%f\n", n, sum);
return 0;
}
5.3.2 整数分解
- 输入一个非负整数,正序输出它的每一位数字
输入:13425
输出:1 3 4 2 5
#include<stdio.h>
int main()
{
int num;
scanf("%d", &num);
int ciMi = 1;
int i;
//int cnt =1;
int j=num;
while (j > 9) {
i = j % 10;// 5 2 4 3
//printf("%d\n", i);
j /= 10;// 1342 134 13 1
//printf("%d %d %d", i, num,ret);
ciMi=ciMi*10;// 10 100 1000 10000
}//printf("%d", cnt);
while (ciMi>0) {
int digit=num / ciMi ;
num %= ciMi;
ciMi /= 10;
printf("%d ", digit);
}
return 0;
}
5.3.3 最大公约数
- 输入两个数a和b,输出它们的最大公约数
输入: 12 18
输出:6 - 1.枚举
设t为2;
如果u和v都能被t整除,则记下这个t;
t+1后重复第二步,直到t等于u或v;
那么,曾今记下的最大的可以同时整除u和v的就是gcd(公约数)。
#include<stdio.h>
int main()
{
int a,b;
int min;
scanf("%d %d", &a, &b);
if (a < b) {
min = a;
}
else {
min = b;
}
int ret = 0;//结果
int i;
//i从1开始,防止没有最大公倍数,把1算进去
for (i = 1; i < min; i++) {
if (a % i == 0) {
if (b % i == 0) {
ret = i;//最小公约数
}
}
}
printf("%d和%d的最大公约数是%d.\n", a, b, ret);
return 0;
}
- 2.辗转相除法
如果b=0,计算结束,a就是最大公约数;
否则,计算a除以b的余数,让a=b,而b=那个余数;
回到第一步.
#include<stdio.h>
int main()
{
int a, b;
int t;
scanf("%d %d", &a, &b);
while (b != 0) {
t = a % b;
a = b;
b = t;
//printf("a=%d,b=%d,t=%d\n", a, b, t);
}
printf("gcd=%d\n", a);
return 0;
}
5.4 practice
05-0. 求序列前N项和(15)
本题要求编写程序,计算序列 2/1+3/2+5/3+8/5+… 的前N项之和。注意该序列从第2项起,每一项的分子是前一项分子与分母的和,
分母是前一项的分子。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中输出部分和的值,精确到小数点后2位。题目保证计算结果不超过双精度范围。
输入样例:
20
输出样例:
32.66*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
double zi=2.0;
double mu=1.0;
int n;
scanf("%d", &n);
double sum = 0.0;
sum += zi / mu;
int i;//遍历
for (i = 0; i < n; i++) {//2/1+3/2+5/3+8/5
double j = zi;
zi += mu;
sum += j / mu;
mu = j;
}
printf("%.2f", sum);//%.2f使得小数点后保留两位小数
return 0;
}
05-1. 约分最简分式(15)
分数可以表示为“分子/分母”的形式。编写一个程序,要求用户输入一个分数,
然后将其约分为最简分式。最简分式是指分子和分母不具有可以约分的成分了。
如6/12可以被约分为1/2。当分子大于分母时,不需要表达为整数又分数的形式,即11/8还是11/8;//if
而当分子分母相等时,仍然表达为1/1的分数形式。//if
输入格式:
输入在一行中给出一个分数,分子和分母中间以斜杠“/”分隔,如:12/34表示34分之12。
分子和分母都是正整数(不包含0,如果不清楚正整数的定义的话)。
提示:在scanf的格式字符串中加入“/”,让scanf来处理这个斜杠。
输出格式:
在一行中输出这个分数对应的最简分式,格式与输入的相同,即采用“分子/分母”的形式表示分数。如5/6表示6分之5。
输入样例:
60/120
输出样例:
1/2*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
//辗转相处法
{
int num1, num2;
scanf("%d %d", &num1, &num2);
int a = num1;//赋予后,使得原来的值不变,让另一个数进行操作
int b = num2;
//scanf("%d %d", &a, &b);
int yushu = 0;
while (b != 0) {
yushu = a % b;
a = b;
b = yushu;
}
//printf("gcd是%d", a);
int i = num1/a;
int j = num2/a;
printf("%d/%d", i , j);
return 0;
}
枚举法
{
int a, b;
scanf("%d %d", &a, &b);
int min = 0;
if (a > b) {
min = b;
}
else {
min = a;
}
int i = 0;//记录次数
int ret = 0;//最大公约数
for (i = 1; i < min; i++) {
if (a % i == 0 && b%i==0) {//判断条件,是否i的值被除后=0,进入下面,不能的话返回
ret = i;
}
}
int j = a / ret;
int k = b / ret;
printf("%d/%d", j, k);
return 0;
}
05-2. 念数字(15)
输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出“fu”字。十个数字对应的拼音如下:
0: ling
1: yi
2: er
3: san
4: si
5: wu
6: liu
7: qi
8: ba
9: jiu
输入格式:
输入在一行中给出一个整数,如:1234。
提示:整数包括负数、零和正数。
输出格式:
在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如yi er san si。
输入样例:
-600
输出样例:
fu liu ling ling*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
if (n < 0)
{
printf("fu ");
n = -n;
}
int k = n;//转换量
int digit = 0;
int ciMi = 1;
while (k>9) {//判断个位数,起到限制的作用
digit=k%10;// 90345
k /= 10;// 1234 123 90 9 0
ciMi *= 10;// 10 100 1000 10000 100000
printf("%d ",k);
}
printf("%d\n", ciMi);
int j = 0;//暂存量
while (ciMi > 0)
{
j = n / ciMi;
n %= ciMi;
ciMi /= 10;
printf("%d ", j);
switch (j)
{
case 0:
printf("ling ");
break;
case 1:
printf("yi ");
break;
case 2:
printf("er ");
break;
case 3:
printf("san ");
break;
case 4:
printf("si ");
break;
case 5:
printf("wu ");
break;
case 6:
printf("liu ");
break;
case 7:
printf("qi ");
break;
case 8:
printf("ba ");
break;
case 9:
printf("jiu ");
break;
default:
break;
}
}
return 0;
}
05-3. 求a的连续和(15)
输入两个整数a和n,a的范围是[0,9],n的范围是[1,8],
求数列之和S = a+aa+aaa+…+aaa…a(n个a)。如a为2、n为8时输出的是2+22+222+…+22222222的和。
输入格式:
输入在一行中给出两个整数,先后表示a和n。
输出格式:
在一行中输出要求的数列之和。
输入样例:
2 4
输出样例:
2468
*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a, n;
scanf("%d %d", &a, &n);
int i ;
int sum = 0;
int digit=0;
for (i = 0; i < n; i++)
{
digit =digit*10 + a;
sum += digit;
}
printf("%d", sum);
return 0;
}