第4章 循环结构程序设计
4.循环结构程序设计
运行环境以Dev-C++为主
4.0 编写循环程序要解决的3个问题
- 1.循环变量赋初值
- 2.循环条件
- 3.循环变量值的调整
- 目的在于让循环条件在某时变为假,结束循环
4.1 while循环:“当型”循环
- 1.一般形式
while(表达式) { // 表达式可以是任意类型的表达式
语句序列;
}
- 2.执行逻辑
- 2.1 计算表达式的值,若结果为真(非0),则进入2.2,开始一次循环周期;否则进入2.3
- 2.2 执行“{}”内的语句序列(循环体)
- 2.3 结束循环,执行while循环后方(“}”之后)语句
- 3.注意
- 避免出现“死循环”,会破解死循环
- 当第一次判断表达式的值为假(0)时,循环体执行0次
- 当循环体中只有一条语句时可省略“{}”,但不建议这么做。养成加“{}”的习惯
- 一般用于循环次数不明确的情况
- 4.while死循环案例
- 1.不带变量的死循环
#include <stdio.h> #include <windows.h> int main() { while(3) { printf("2022级网络技术班!\n"); Sleep(1000); } return 0; }
- 2.带变量的死循环
#include <stdio.h> int main() { int i = 3; while(i) { printf("2022级网络技术班!\n "); } return 0; }
- 3.带变量并破解死循环
#include <stdio.h> int main() { int i = 3; while(i) { printf("2022级网络技术班!\n "); i --; // -- i也可以 } return 0; }
- 4.带变量、破解死循环代码量缩减
#include <stdio.h> int main() { int i = 3; while(i --) { printf("2021级卓越3班!\n"); } return 0; }
- 5.while循环案例
- 1.编程求1+2+3+4+5之和。
// 分析:1.选择基本结构。题目需求一直在重复一个动作——做加法,很容易想到用循环结构!此处选择while循环(其他类型的循环也可以完成)。 // 2.如何通过变量来控制循环开始或结束? // 2.1 在程序中给定一个变量,这个变量通常用于控制循环的开始和结束,称其为“循环变量”(如案例中的int i;); // 2.2 该循环变量通常写在“表达式”中,定义时会给定一个初值(可随意),且能确定让循环结束(如a = ?; a = 1; a=100; a=9999); // 2.3 该循环变量有一定的范围(> >= < <=),循环执行过程中循环变量的值会改变(++ -- =),当其超出范围后循环结束(如while(a <= ?) a ++;)。 // 3.仅仅有了循环变量还不能得到最终的结果呢?“循环变量”i的值遍历了1、2、3、4、5这5个数;定义一个用于存储加和的变量sum,每当 // i增加了1,就把i累加到sum中。即 sum = sum + i; sum初值为0,不影响对i累加的值。当循环结束时,sum中存储的大概率就是求得的和。 #include <stdio.h> int main( ){ int sum, i; sum = 0; // 累加器sum置0 i = 1; // 循环变量i赋初值1 while (i <= 5) { sum = sum + i; // 将i值累加到sum中 i = i +1; // 改变循环变量i的值 } printf("1+2+3+4+5 = %d", sum ); return 0; }
- 2.编写循环程序求1+2+3+4+5+…+100之和。
// 分析:本题思路与上题一致,只将循环范围修改即可 int main( ){ int sum, i; sum = 0; i = 1; while (i <= 100) { sum = sum + i; i = i +1; } printf("1+2+3+...+100 = %d", sum ); return 0; }
- 3.编写循环程序求1-2+3-4+5-6+7-8的值。
// 方法1 // 分析:该程序与上例的最大区别在于公式中有加法也有减法,需要用代码完成题目中加减号的变换。怎样完成呢?把“1-2+3-4+5-6+7-8”这 // 个式子改头换面。“一会加一会减”的程序不容易写,但“一直加”的我们学过了。 // 1-2+3-4+5-6+7-8=1+(-2)+3+(-4)+5+(-6)+7+(-8)这样不够明显 // 1+2*(-1)+3+4 *(-1) +5+6 *(-1)+7+8 *(-1) 这样还不够明显 // 1*1+2*(-1)+3 *1 +4 *(-1) +5*1 +6 *(-1)+7 *1 +8 *(-1) // 运算逻辑为1-8看作循环变量 i,每循环一次就把1的值乘1或-1后累加到sum中。 #include <stdio.h> int main() { int i = 1, sum = 0; int t = 1; while(i <= 8) { sum = sum + i * t; i ++; t = -t; } printf("%d", sum); return 0; } // 方法2 // 利用奇偶数,观察原式发现加奇数,减偶数。 #include <stdio.h> int main(){ int i=1, sum=0; while(i<=8){ if(i%2!=0){ sum=sum+i; } else { sum=sum-i; } i++; } printf("sum=%d", sum); return 0; }
- 4.编程计算1+1/2+1/4+1/8+1/16+…的值,直到最后一项值小于0.0001。
//分析:1.此程序累加式中的规律:从首项1开始,依次乘以1/2就是下一项,但注意C程序中的1/2值为0; //2.定义循环变量i,初值为1.0,循环条件为i >= 0.0001; //3.定义累加变量sum,初值为0.0,每经历一次循环就将i累加到sum中,同时i的值自动减半。 #include <stdio.h> int main(){ float t = 1.0; double sum = 0; while(t >= 0.0001) { sum = sum + t; t = t / 2; } printf(“sum=%f\n”, sum); return 0; }
- 5.从键盘上输入若干个整数,直到输入0为止,求它们的乘积。
// 分析:(1)无法确定此程序的循环次数,因此选用while或do…while循环; // 累积变量的初值应设定为1。由于累乘求得的结果数值可能较大,可选择long型。 // 由于输入的数用于累乘计算,且题目明确要求直到输入0时停止计算,由此推断循环变量和用于累积计算用到的变量是同一个; // 定义累积变量mult = 1,循环变量i,初值通过scanf读取。while循环中表达式为“i != 0”,累积计算表达式为mul = mul * i。 #include <stdio.h> int main( ){ int n; long t = 1; scanf("%d", &n); while (n != 0){ t= t * n; scanf("%d", &n ); } printf("%ld \n", t ); return 0; }
4.2 do...while循环:“直到型”循环
- 1.一般形式
do {
语句序列;
}while(表达式); // 表达式可以是任意类型的表达式
- 2.执行逻辑
- 2.1 执行循环体中的语句序列,开始一个循环周期
- 2.2 计算表达式的值,若结果为真(非0),则转到2.1,继续下一个循环周期;否则进入2.3
- 2.3 结束循环,执行do...while循环后方的语句
- 3.注意
- 先执行循环体,后判断条件,循环次数不低于1次
- while(表达式)后面的分号“;”不能遗漏
- “{}”不能省略,即使只有单一语句
- 一般用于循环次数不明确的情况
- 4.do...while循环案例
- 1.输入若干字符,以'*'作为输入结束符,分别用do...while和while语句实现。输入相同字符,比较它们运行结果有何不同。
//分析:1.循环变量赋初值(char ch = '';); //2.设定循环条件(ch != ‘*’); //3.循环变量值的调整(重新输入后循环体内也要加入一条scanf或 getchar输入语句) #include < stdio . h> int main() { char ch ; ch=getchar() ; do { putchar(ch) ; ch=getchar() ; }while(ch!='*'); return 0; } #include < stdio . h > int main() { char ch ; ch=getchar() ; while(ch!='*') { putchar(ch); ch=getchar( ); } return 0; }
- 2.输入一个整数,按相反次序输出。例如,输入54321,输出12345。
//分析:对于输入的任意一个整数N,可以做以下操作: //1.判断N是不是0,如果是,结束程序/循环;如果不是,进入第2步; //2.通过运算操作取出整数N的最后一位并打印输出,同时去掉N的最后一位得到新的整数N; //3.返回到第1步继续运算。 #include <stdio.h> int main() { int num, b; printf("请输入num的值:\n"); scanf("%d", &num); do { b = num % 10; printf("%d", b); num = num / 10; } while(num); return 0; }
4.3 for循环
- 1.一般形式
for(表达式1;表达式2;表达式3) {
语句序列;
}
-
2.执行逻辑
- 2.1 计算表达式1
- 2.2 计算表达式2,若结果为真,则转到2.3,否则进入2.5
- 2.3 执行语句序列
- 2.4 计算表达式3,转到2.2
- 2.5 结束循环,执行for语句后面(“}”之后)的语句
-
3.注意
- 关于3个表达式
- 表达式1用于循环变量(定义和)初始化,只在循环开始时执行1次,简单表达式或逗号表达式均可
- 表达式2作为循环条件,在每一轮循环开始前计算;
- 表达式3用于循环变量更新,简单表达式或逗号表达式均可
- 关于程序易读性
- 不建议删除“{}”,尤其在嵌套的循环中
- 不建议3个表达式中写逗号表达式,如下
for(sum=0, i=1; i<=10; sum=sum+i, i++) { ; }
- 不建议省略3个表达式中其中1~2个,如下
i = 1; for(; i<=10;) { sum = sum + i; i ++; }
- 关于累加和累乘变量
- 累加 sum = 0
- 累乘 multy = 1
- 先判断条件,后执行循环,循环次数不低于0次
- 当语句序列只有一个“;”时表示空语句
- 一般用于循环次数明确的情况
- 关于3个表达式
-
4.for循环案例
- 1.从键盘上输入10个整数,求其和。
// 分析:1.在使用while循环做过累加的编程题后,基本已经掌握了循环内部变量的累加问题。 //此时通常涉及到2个变量,一个用来存储累加的和,如sum;另一个作为变量累加到sum中,如i。 //2.该题的关键在于:写对for循环中3个表达式。已知“表达式1”用来实现循环变量的初始化工作,“表达式2”作为循环条件, //“表达式3”用于循环变量的更新。表达式1:i = 0 表达式2:i <= 9 / i < 10 表达式3:i ++ //for(i = 0; i <= 9; i ++) { xxx } //注意:由于本题中循环变量的值仅仅用于控制循环次数,并未和用于计算的10个数据的值发生关联,所以 //i的初值可以随意定义,只要能保证循环10次后结束就可以。 #include <stdio.h> int main( ){ int i, num, sum; sum = 0; for(i=1; i<=10; i++){ scanf("%d", &num ); sum = sum + num; } printf("这10个整数的和为:%d", sum ); return 0; }
4.4 多重循环
- 1.一般形式
for(表达式1;表达式2;表达式3) {
for(表达式4;表达式5;表达式6) {
语句序列;
}
}
while(表达式) {
while(表达式) {
语句序列;
}
}
- 2.执行逻辑(以双重for循环为例)
- 2.1 执行表达式1进行循环变量outer的初始化,随后执行表达式2
- 2.1.1 若结果为真,则进入内循环,继续按照for循环的执行逻辑运行
- 2.1.2 若结果为假,则退出外循环,循环结束
- 2.2 当内循环结束退出后,执行表达式3,随后执行表达式2,继续2.1.1或2.1.2
- 2.1 执行表达式1进行循环变量outer的初始化,随后执行表达式2
- 3.注意
- 循环嵌套层数不宜过多,2~3层即可。嵌套过多时考虑是否是算法逻辑有问题。
- 不要漏掉“{}”,否则会导致程序可读性差,分析某代码属于哪一层循环
- 理清代码执行逻辑,确认语句是在程序哪一部分起作用(外循环外、外循环内and内循环外、内循环内等)
- 外循环的循环变量outer初值、内循环循环变量inner初值、内外循环的取值范围(表达式2和表达式5)是无关联的还是相互限制的
- 4.嵌套循环案例
- 1.打印九九乘法表
// 分析:1.目前写过的循环程序:while、do...while、for全是“一维”(数轴 点)的; // 2.“九九乘法表”和之前的循环程序最大的差别在于它是“二维”(平面 点)的; // 3.从宏观上看,每一行的乘式的被乘数都是此行的行号; // 4.从微观上看,任意一行的某几个乘式中,乘数的值严格受被乘数约束。具体分析如第5行,被乘数均为5, // 乘数从左到右依次为1—2—3—4—5,即被乘数5约束着乘数为1~5,其他行也同样,被乘数N约束着乘数为1~N; // 5.假设现在刚好有一个变量i,它控制了乘法表的行数,我们很清晰地想到i属于1~9。针对1~9这9个数, // 任意抽出一个都可以代表某一行,则该行的算式个数j一定满足j <= i。 // 6.所以这里的i和j刚好构成了双层for循环的外侧和内侧。如何区分内层和外层循环?被控制的一方即为内层循环。 // 7.乘法表中存在一个“换行”动作,当每一行的乘数中所有可能的取值被遍历结束后,重新开始下一行。 // 反映到程序上就是当j = i时换行。 #include <stdio.h> int main( ) { int i, j; for(i=1; i<10; i++){ printf ( "%8d", i ); } printf (" \n---------------------------------" ); printf ("-----------------------------------\n" ); for ( i = 1; i < 10; i++ ){ for ( j = 1; j <= i; j++ ){ printf ( " %2d * %d = % -3d ", i, j , i*j ); } printf ( " \n " ); } return 0; }
- 2.分别输入5名学生的4门科目成绩,计算出每名学生的平均成绩。
// 分析:1.这个题目也是“二维”的,一方面涉及到学生,另一方面涉及到和每一位学生绑定的成绩,即成绩由学生和科目共同决定; // 2.从“学生”来看,总共有5名,可以用i从1~5遍历; // 3.从“科目”来看,总共有4门,可以用j从1~4遍历; // 4.九九乘法表中乘数的取值范围受被乘数控制,因此将被乘数作为外层循环,将乘数作为内层循环!类似地, // 这里我们假设科目受学生控制,因此学生作为外循环,科目作为内循环; // 5.为了计算平均成绩avg_score,要先计算总成绩sum,更要先由程序读入成绩score; // 6.分析到这里,所涉及的变量、双层循环的结构基本都已确定。 #include <stdio.h> int main(){ float stu_num,course_num, score, avg_score; printf("输入成绩:\n"); for(stu_num=1;stu_num<6;stu_num++){ float sum = 0; for(course_num=1;course_num<5;course_num++){ scanf("%f",&score); sum=sum+score; } avg_score=sum/4; printf("%d号学生的平均成绩是: %f\n",stu_num, avg_score); } return 0; }
4.5 break语句和continue语句
- 1.执行逻辑
- break用于循环结构可使程序提前跳出循环(强行结束),也可用于跳出switch结构
- continue使程序跳过循环体中后方语句,结束本轮循环,直接进入下一轮循环
- 2.适用结构
- break多用于for循环、while循环、do...while循环、switch语句,可配合if使用
- continue多用于for循环、while循环、do...while循环,可配合if使用
- 3.注意
- break跳出的是它所在的那一层循环,可能是内循环,也可能是外循环
- break跳出的是它所在的那一层switch,在嵌套的switch语句中尤其要注意
- 4.案例
- 1.求不同半径的圆柱体的体积,只计算体积在100以下的圆柱体(体积计算公式:V=πR^2H)。
// 分析:1.规定一个半径的范围,从小到大依次遍历,可以使用for循环; // 2.为方便程序的运行,可以指定一个固定的高度; // 3.循环体中计算每一个(R, H)确定的圆柱体积。一旦体积高于100,立刻通过break语句跳出循环。 #include <stdio.h> #define PI 3.14 int main( ) { int r; float h; double v; printf("请输入圆柱体的高:" ); scanf("%f", &h ); for(r=1; r<=10; r++){ v = PI * r * r * h; if(v > 100.0){ break; } printf("半径等于%d,体积等于 %.2f \n", r, v ); } printf("此时r = %d \n", r ); return 0; }
- 2.输出50~100之间所有不能被7整除的整数(计数变量的思想)。
// 分析:1.依次遍历50-100,可使用for循环,用循环变量i; // 2.循环体中判断所遍历的数中能否被7整除,能的话就直接开始下一个遍历的数字/结束本轮循环,否则原样输出; // 3.为优化显示结果,可以每行显示10个数,用到计数变量count。 #include <stdio.h> // 方法1:此程序用continue关键字实现 int main() { int num, cnt=0; for(num=50; num<=100; num ++){ if (num %7 == 0){ continue; } printf("%5d", num ); cnt++; if(cnt%10==0){ printf("\n"); } } printf("\n"); return 0; } ------------------------------------------------------------- #include <stdio.h>// 此程序不用关键字continue int main(){ int num, count = 0; for(num=50;num<=100;num++){ if(num%7!=0){ printf("%d ", num); count++; if(count%10==0){ printf("\n"); } } } return 0; }
4.6 循环结构程序设计实例
- 1.判断一个数是否是素数
// -------------------------------方法1-------------------------------
// 分析:判断素数的本质还是在于找到一个非1非本身的因数,只要存在这个因数,它就不是素数。
// 因此对于任意一个自然数N(N非零非1),我们要逐一确定2~N-1之内的所有数中是否存在被N整除的,只要存在一个就说明N不是素数,否则是素数。
// 用for循环遍历2~N-1,一旦出现非0非1的因数n就立刻结束循环,后续n+1~N-1的遍历都没有必要进行了。i充当循环变量,num充当用于判断的数。
// for循环有2种退出方式,要么“寿终正寝”,要么“强行break”。前者一定是因为触发了“表达式2不满足的件”,
// 即循环变量i的值一直增加到了num,此时num一定是素数!
#include <stdio.h>
int main() {
int i, num;
printf("请输入num的值:\n");
scanf("%d", &num);
for(i = 2; i <= num - 1; i ++) {
if(num % i == 0) {
break;
}
}
if(num == i) {
printf("%d是素数!\n", num);
}
else {
printf("%d不是素数!\n", num);
}
return 0;
}
// -------------------------------方法2-------------------------------
// 分析:有必要逐一确定2~N-1之内的所有因数吗?
// 如何把参考的因数范围缩小?可以通过范例去总结,如36,按照以前的思路我们需要逐一验证2~35,但对于32/33/34/35
// 这一类数没必要去验证,因为它们非常接近36并且基本不可能被36整除(本来循环也没执行到35,到2时就强行break了!)
// 但我们总会遇到执行到底的数字,比如17,按照以前的算法它会判断到16。所以现在我们需要从2~35之间找出一个界限L,
// 只判断2~L以内的因数就可以了。如何去找这个界限L呢?对于36,开平方6是它的一个因数,除以2得到18也是它的一个因数。
// 这两种方法(开方 除以2)都可以作为我们要找的这个界限L(2,18) (3,12) (4,9) (6,6) (9,4) (12,3) (18,2)。
// 再如27,开平方后介于5~6之间的这个数可以作为界限。只要2~界限L内的所有整数不是因数,那它就一定是素数!
// 用for循环遍历2~界限L,一旦出现非0非1的因数n就立刻结束循环,后续n+1~界限L的遍历都没有必要进行了。i充当循环变量,num充当用于判断的数。
#include <stdio.h>
#include <math.h>
int main() {
int i, num;
printf("请输入num的值:\n");
scanf("%d", &num);
for(i = 2; i <= sqrt(num); i ++) {
if(num % i == 0) {
break;
}
}
if(i > sqrt(num)) {
printf("%d是素数!\n", num);
}
else {
printf("%d不是素数!\n", num);
}
return 0;
}
// -------------------------------方法3-------------------------------
// 再用一种“标志变量”的方式打印,“标志变量”在编程中是一种很重要的思想。
// 它的初值设为1(即我们先默认num是素数),一旦for循环以break形式结束,此时num一定不是素数,就在if语句块中将“标志变量”置为0。
// 循环结束后通过判断“标志变量”的值就可以断定num是不是素数了。
#include <stdio.h>
#include <math.h>
int main() {
int i, num;
int flag = 1;
printf("请输入num的值:\n");
scanf("%d", &num);
for(i = 2; i <= sqrt(num); i ++) {
if(num % i == 0) {
flag = 0;
break;
}
}
if(flag == 1) {
printf("%d是素数!\n", num);
}
else {
printf("%d不是素数!\n", num);
}
return 0;
}
// 思考:1.代码中的“if(flag == 1)”能否改为“if(flag = 1)”?
// 2.代码中的“if(flag == 1)”能否改为“if(flag)”
- 2.找出100~200之间的所有素数
// 分析:在详细分析了判断num是否是素数的算法后,本题又增加了一个限制条件,要求找到100-200内的素数。
// 不同处在于:之前是输入一个数num,判断是否是素数;现在是100-200逐个判断。即外层再套一个for循环遍历一下100-200就行了。
// 关键:tag标志变量写在哪个位置更合适?
// tag标志变量要放在外循环内,内循环外,因为内层循环是对因数的判断,在判断开始前我们先默认最外层循环的这个数是素数,然后
// 根据内层循环的执行情况再决定是否对其重新赋值为0!
// 简而言之,在每一轮最外层循环开始时(即判断一个新的数是否是素数),都要重新对flag标志变量赋值。
#include <stdio.h>
#include <math.h>
int main() {
int num, j, tag, m, cnt = 0;
for(num = 101; num < 200; num += 2) { /* num增量为2 */
tag = 1;
m = sqrt(num);
for(j = 2; j <= m; j++) {
if(num % j == 0) {
tag=0;
break;
}
}
if (tag == 1) {
printf("%5d", num );
cnt ++;
if(cnt%12 == 0) {
printf("\n");
}
}
}
return 0;
}
- 3.输入两个整数,求它们的最大公约数。方法是采用“碾转相除法”,即反复模除取余,直到余数为0。
// 分析:自然语言法描述辗转相除法:
// 1.将第1个整数a模除第2个整数b(a>b),得到余数r;
// 2.将a赋值为b,将b赋值为r;
// 3.重复前2步,直到r为0(循环)
// 补充:假设有两个整数a、b,它们的最大公约数是p,最小公倍数是q。那么有这样的关系:ab=pq。
// -------------------------------方法1-------------------------------
#include <stdio.h> // 用while循环实现
int main() {
int a, b, temp, r;
printf("请输入2个整数:\n");
scanf("%d %d", &a, &b);
if(a < b) {
temp = a;
a = b;
b = temp;
}
r = a % b;
while(r) {
a = b;
b = r;
r = a % b;
}
printf("最大公约数为: %d\n", b);
return 0;
}
// -------------------------------方法2-------------------------------
#include <stdio.h> // 用do...while循环实现
int main() {
int a, b, temp, r;
printf("请输入2个整数:\n");
scanf("%d %d", &a, &b);
if(a < b) {
temp = a;
a = b;
b = temp;
}
do {
r = a%b;
a = b;
b = r;
}while(r)
printf("最大公约数为: %d\n", a);
return 0;
}
- 4.“百鸡问题”是我国古代数学家张丘建在他编写的《算经》里提出的一个不定方程问题,即“鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡。问鸡翁、母、雏各几何?”
// 分析:设公鸡(鸡翁)、母鸡(鸡母)和小鸡(鸡雏)的数量各为x、y和z只。因为总共100钱,若全部买公鸡,则最多买20只,显然x的变化范围在0~20之间。
// 同理,y的变化范围在0~33之间。所得的不定式方程应为方程1和方程2的联立。
// x+y+z=100 方程1
// 5x+3y+z/3=100 方程2
// 注意:不定式方程组可能有多组解,小鸡数量必须是3的倍数,也即方程2中的z/3必须能够整除,即程序中需要加一个限定条件“(z%3==0)”,不然会得到一些错误答案(如(4, 18, 79)、(4, 18, 80)),因为z/3会舍弃小数部分。
#include <stdio.h>
int main(){
int x, y, z;
for(x=0; x <= 20; ++x) {
for(y=0; y <= 34; ++y) {
z = 100 - x - y;
if ((z%3 == 0)&&(5*x+3*y+z/3 ==100)) {
printf("公鸡:%-2d 母鸡:%-2d 小鸡:%-2d\n", x, y, z );
}
}
}
return 0;
}
- 5.(百鸡问题变式1)从3个红球(x)、5个白球(y)和6个黑球(z)中任意取出8个,且其中必须要有红球和白球。请输出所有方案。
// 分析:本题和“百鸡问题”的本质一样。红球、白球和黑球的个数类比上题中公鸡、母鸡和小鸡的数量,三种球共摸8个对应上题中共100只。
// x+y+z = 8 方程1
// x>=1 且 y>= 1 方程2
#include <stdio.h>
int main() {
int x, y, z;
for(x=1; x<=3; x++) {
for(y=1; y<=5; y ++) {
z = 8 - x - y;
printf("红球:%d个 白球:%d个 黑球:%d个", x, y, z);
}
}
return 0;
}
- 6.(百鸡问题变式2)有1 2 3 4共4个数,能组成多少个互不相同且无重复数字的3位数?输出所有可能。
-------------------------------方法1-------------------------------
#include <stdio.h> // 使用嵌套循环实现
int main() {
int x, y, z;
for(x=1; x<=4; x++) {
for(y=1; y<=4; y ++) {
for(z=1; z<=4; y ++) {
if(i!=j && j != k && i != k) {
printf("%d\t", i*100+j*10+k);
}
}
printf("红球:%d个 白球:%d个 黑球:%d个", x, y, z);
}
}
return 0;
}
-------------------------------方法2-------------------------------
#include <stdio.h> // 使用拆分三位数的各位 十位 百位来实现
int main() {
int x, i, j, k;
for(x=102; x<=987; x++) {
i = x%10; // 个位
j = x/10%10; // 十位
k = x/100; // 百位
if(i != k && i != k && j != k) {
printf("%d\t", x);
}
}
return 0;
}
- 7.输入n的值,计算1+(1+2)+(1+2+3+)···+(1+2+3+···+n)的值。
#include <stdio.h>
int main(){
int sum = 0, total = 0;
int i, n;
scanf("%d", &n);
for(i = 1; i <= n; i ++){
sum = sum + i;
total = total + sum;
}
printf("total=%d", total);
return 0;
}
- 8.【改编 2024网络技能考试】春考报名系统在注册用户时,用户名有以下要求:
- 1.用户名只能有大小写字母和数字,不能出现其他字符
- 2.大写字母、小写字母和数字必须都要出现
/*
方法1:不用函数
小写字母ASKII码范围97-122 a-z
大写字母ASKII码范围65-90 A-Z
数字字符的范围48-57 0-9
*/
#include <stdio.h>
#include <string.h>
int main(){
char user_name[21], t;
int i, upper_flag = 0, lower_flag = 0, num_flag = 0;
printf("请输入用户名:\n");
gets(user_name);
int length = strlen(user_name);
if(length < 8 || length > 20) { # 写代码的准则:简单的逻辑处理放在前面;复杂的逻辑放在后面。
printf("用户名长度不合法,请保证字符串长在8-20之间!\n");
return 0;
}
else {
for(i = 0; user_name[i] != '\0'; i ++) {
t = user_name[i];
if(t < 48 || (t > 57 && t < 65) || (t > 90 && t < 97) || (t > 122)){
printf("只能包含大小写字母和数字!\n");
return 0;
}
else {
if(num_flag == 0 && (t >= 48 && t<=57)) {
num_flag = 1;
}
else if(upper_flag == 0 && (t >= 65 && t <= 90)) {
upper_flag = 1;
}
else if(lower_flag == 0 && (t >= 97 && t <= 122)) {
lower_flag = 1;
}
}
}
if(num_flag == 1 && lower_flag == 1 && upper_flag == 1){
printf("合法用户名!");
}
}
return 0;
}
// 方法2:使用函数(带返回值,退出函数)
#include <stdio.h>
#include <string.h>
int check_name(char name[]){
char t;
int length = strlen(name), i;
int num_flag = 0, upper_flag = 0, lower_flag = 0;
if(length < 8 || length > 20) {
return -1;
}
else {
for(i = 0; name[i] != '\0'; i ++) {
t = name[i];
if(t < 48 || (t > 57 && t < 65) || (t > 90 && t < 97) || (t > 122)){
return -2;
}
else {
if(num_flag == 0 && (t >= 48 && t<=57)) {
num_flag = 1;
}
else if(upper_flag == 0 && (t >= 65 && t <= 90)) {
upper_flag = 1;
}
else if(lower_flag == 0 && (t >= 97 && t <= 122)) {
lower_flag = 1;
}
}
}
if(num_flag == 1 && lower_flag == 1 && upper_flag == 1){
return 0;
}
}
}
int main(){
char user_name[21];
int flag;
printf("请输入用户名:\n");
gets(user_name);
flag = check_name(user_name);
if(flag == 0){
printf("合法用户名!");
}
else if(flag == -1) {
printf("用户名长度不合法,请保证字符串长在8-20之间!\n");
}
else {
printf("只能包含大小写字母和数字!\n");
}
return 0;
}
// 方法3:使用函数(不带返回值,退出程序)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void check_name(char name[]){
char t;
int length = strlen(name), i;
int num_flag = 0, upper_flag = 0, lower_flag = 0;
if(length < 8 || length > 20) {
printf("用户名长度不合法,请保证字符串长在8-20之间!\n");
exit(-1);
}
else {
for(i = 0; name[i] != '\0'; i ++) {
t = name[i];
if(t < 48 || (t > 57 && t < 65) || (t > 90 && t < 97) || (t > 122)){
printf("只能包含大小写字母和数字!\n");
exit(-2);
}
else {
if(num_flag == 0 && (t >= 48 && t<=57)) {
num_flag = 1;
}
else if(upper_flag == 0 && (t >= 65 && t <= 90)) {
upper_flag = 1;
}
else if(lower_flag == 0 && (t >= 97 && t <= 122)) {
lower_flag = 1;
}
}
}
if(num_flag == 1 && lower_flag == 1 && upper_flag == 1){
printf("合法用户名!");
exit(0);
}
}
}
int main(){
char user_name[21];
int flag;
printf("请输入用户名:\n");
gets(user_name);
check_name(user_name);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)