zoukankan      html  css  js  c++  java
  • C语言循环结构细讲

    1.

    y = 1+2+3+4+5...+100的值

    int i = 1;//加数

    int sum = 0;//

    0 + 1 = 1

    1 + 2 = 3;

    1 + 2 + 3 = 6;

    1 + 2 + 3 + 4 = 10;

    。。。

    sum = sum + i;

    i++;

    sum = sum + i;

    i++;

    sum = sum + i;

    i++;

    。。

    =》循环结构

    循环的本质就是重复

    C语言中可以达到循环效果的语句

    1goto语句与if构成的

    2while

    3do while

    4for

    1goto语句

    goto  目标地点(在C语言中,某条指令的地址)

    “指令地址” :语句标号 (它下面那条指令的地址)

    “语句标号”:名字

    语句标号前面只允许有空白字符

    名字必须符合C语言中标识符的规定

    loop:

    i++;

    goto loop;

    语法形式:

    goto 语句标号;

    eg:

    把求1~100的和用goto语句实现

    int i = 1;//加数

    int sum = 0;//

    loop:

    sum = sum+i;

    i++;

    if(i < 100)

    {

    goto loop;

    }

    注意:

    主张限制使用goto语句

    如果乱用goto语句,会使程序的可读性很差

    (2)while循环

    语法形式:

    while(表达式)

    循环体语句

    “表达式”的值为真(非0),就执行“循环体语句”

    然后,在判断“表达式”的值,如果为真(非0),就继续执行“循环体语句”

    .....

    直到“表达式”的值为假(0)为止(循环结束)

    “表达式” :C语言中任意合法的表达式

    “循环体语句”:

    单语句 :只有有一个;语句

    复合语句

    {}/if/switch/for/while/do_while

    eg:

    while(i < 100)

    {

    i++;

    sum = sum +i;

    }

    =>编程建议

    不管while后面有没有语句,先打一对{}

    表示他的“管辖范围”

    练习:

    输入一个整数,以逆序的顺序输出

    12345

    =>54321

    n = 12345;

    x = 12345%10

    printf("%d",x);

    ....

    step1:

    求取个位数

    step2:

    打印

    ========

    step1:

    求取个位数

    step2:

    打印

    step3:

    把个位数拿到

    while(n != 0)

    {

    //step1:求取个位数

    x = n%10;

    //step2:打印

    printf("%d",x);

    //step3:把个位数拿掉

    n = n/10;

    }

    (3)do while

    语法形式:

    do

    循环体语句

    while(表达式);

    先执行“循环体语句”,然后在判断“表达式”的值,

    当表达式的值为真(非0),返回去执行上面的“循环体语句”,然后再一次

    判断“表达式”的值,如果为真,返回去执行上面的“循环体语句”,

    直到“表达式”的值为假(0),循环结束

    “表达式” :C语言中任意合法的表达式

    “循环体语句”:

    单语句 :只有有一个;语句

    复合语句

    {}/if/switch/for/while/do_while

    eg:

    do

    i++;

    sum = sum+i;

    while(I < 100);

    这个代码是有语句错误

    =>编程建议

    不管do后面有没有语句,先打一对{}

    表示他的“管辖范围”

    do

    {

    循环体语句

    }while(表达式);

    练习:

    n! (n由用户输入)

    4

    4*3*2*1

    类乘

    int i = 1;

    int s = 1;

    do

    {

    s = s*i;

    i++;

    }while(i <= n);

    (4)for循环

    语法形式:

    for(表达式1;表达式2;表达式3)

    循环体语句

    先做“表达式1”(仅仅执行一次),然后再去判断“表达式2”的值

    如果为真(非0),则执行“循环体语句”,

    执行完“循环体语句”,在执行“表达式3

    在判断“表达式2”的值,如果为真(非0),则执行“循环体语句”,

    执行完“循环体语句”,在执行“表达式3

    ....如此重复

    直到“表达式2”的值为假(0) 循环结束

    “表达式1”,“表达式2”,“表达式3

    任意C语言合法的表达式都可以

    “表达式1” :一个循环只做一次,初始化条件,可一个,可多个,用逗号隔开

    “表达式2”:判断表达式,它的值直接决定for循环是执行还是不执行

    “表达式3”:改变循环条件的地方,每当循环体语句做完之后,执行表达式3

    “表达式1”,“表达式2”,“表达式3”都可以为空

    但是;一个都不能少

    表达式2为空,则表示循环判断条件永远为真

    for(;;)    while(1);

    {

    }

    =>编程建议

    不管for后面有没有语句,先打一对{}

    表示他的“管辖范围”

    练习:

    1.求出所有的“水仙花数” 1.c

    “水仙花数”是一个三位数,并且它的个,十,百位上的数字的立方和等于它本身

    [100,999]

    100 ?

    if(0*0*0+0*0*0+1*1*1 == 100)

    {

    print 100

    }

    101 ?

    if(1*1*1+0*0*0+1*1*1 == 101)

    {

    print 101

    }

    。。。。

    999

    num : [100,999]

    x,y,z

    if(x*x*x+y*y*y+z*z*z == num)

    {

    }

    =============

    for(num = 100;num<=999;num++)

    {

    //求取num的个,十,百

    x=

    y=

    z=

    if(x*x*x+y*y*y+z*z*z == num)

    {

    }

    }

    2.判断一个整数x,是否为质数(素数) 2.c

    质数?

    除了1和它本身以外没有其他的因数,这样的数就称为质数

    6  :1 2 3 6

    x

    [2,x-1]

    2 是不是x的因子

    3 是不是x的因子

    。。。

    x-1 是不是x的因子

    =>

    for(i = 2;i < x;i++)

    {

    if(x % i == 0)//只要发现一个因子,不需要往下判断

    {

    printf("no ");

    break; //提前结束循环

    }

    }

    if(i== x)

    {

    printf("yes ");

    }

    一个循环结束有两种情况

    1)判断条件满足

    因为break跳出循环   =》提前结束 非正常死亡

    2)判断条件不满足

    “判断表达式”的值为0

    (5)breakcontinue

    break C语言中有两个作用

    1breakswitch中,用来跳出它所属的switch语句

    2break用在循环语句(while/do_while/for)中,用来跳出它所属的循环

    for()

    {

    while()

    {

    if()

    {

    break;//跳出while

    }

    }

    }

    /*

    test1.c: In function main:

    test1.c:9:3: error: break statement not within loop or switch

    break;

       ^

    */

    if()

    {

    break;

    } //有语法错误

    continue

    continue只能用于循环体内(while/do_while/for

    用于提前执行下一次循环(结束本次循环,继续下一次循环)

    作业:

    1、求1000以内所有的“完数”

    “完数”:如果一个数除了它本身以外其他因子之和等于其本身,这个数就是完数

    6 1 2 3 6

    m % n == 0;

    =mn的倍数 ,nm的因子(因数)

    num [1,1000]

    int sum = 0;

    for(num = 1;num <=1000;num++)

    {

    sum = 0;

    //判断num是不是一个完数

    for(x = 1; x <num;x++)

    {

    if(num % x == 0)

    {

    sum += x;

    }

    }

    if(sum == num)

    {

    printf("%d ",num);

    }

    }

    2.求两个数(a,b)的最大公约数和最小公倍数

    a % m == 0 =>am的倍数,ma的约数

    b  % m == 0 =>bm的倍数,mb的约数

    =>mab的公约数

    15 45

    算法一:

    “穷举法”

    a % x == 0 && b % x == 0

    [1,min(a,b)] 区间里面找

    找最大的公约数绝对不会大于min(a,b)

    => min = a <b ? a : b;

    for(;min >0;min--)

    {

    if(a % min== 0 && b % min == 0)

    {

    min就是最大公约数

    break;

    }

    }

    ======

    算法二:

    欧几里德算法

    GCD(a,b)

    假设a >= b

    GCD(b,a mod b)

    r = a mod b = a%b

    证明

    a,b的公约数集合 == b,a mod b的公约数的集合

    A ==  B

    AB的子集,BA的子集

    AB的子集 :

    GCD(a,b)

    xGCD(a,b)中任意一个元素

    a = K1 x (K1为整数)

    b = K2 x (K2为整数)

    r = a mod b

    =>a = K*b +r (K为整数)

    => K1x = kK2x +r

    =>r = (K1-KK2)x

    =>xr的约数

    xb的约数

    x属于b,r的公约数 =x 属于 GCD(b,r)

    GCD(15,10) => GCD(10,5) =>GCD(5,0)  =>5就是最大公约数

    GCD(125,64) =>(64,61) =>(61,3) =>(3,1) =>(1,0) =>1

    int a,b;

    scanf("%d%d",&a,&b);

    //确保 a>= b

    while(a % b != 0)

    {

    r = a%b;

    a = b;

    b = r;

    }

    //最大公约数为a

    优化:

    while(b)

    {

    r = a%b;

    a = b;

    b = r;

    }

    3.连续的正整数之和。一个正整数有可能可以被表示为nn>=2)个连续的正整数之和

    x = 15

    15 = 1+2+3+4+5

    15 = 4+5+6

    15 = 7+8

    "穷举法"

    i :1~x/2

    sum = i;

    if(sum == x)

    {

    }

    i++;

    sum += i;

    if(sum == x)

    {

    }

    ===========

    int i,x,num,sum;

    scanf("%d",&num);

    for(i = 1;i < num/2+1;i++)

    {

    sum = i;

    for(x = i+1;;x++)

    {

    sum += x;

    if(sum == num)

    {

    //输出处理

    break;

    }

    else if(sum > num)

    {

    break;

    }

    }

    }

    算法二:

    [L,R]

    sum = [l,r]区间各元素之和

    1:从1开始   1+ 2 +3 + 4+5+6

    if sum < num //往右边扩展区间

    r++;

    sum += r;

    if sum >num//

    sum -= l;

    l++;

    if sum == num //找到这个区间

    //输出处理

    r++;

    sum += r;

    15

    1+2+3+4+5...15

    4 +5 +6 +7

    =====

    for(l = 1,r = 1,sum = 1;l <= num/2;)

    {

    if(sum < num) //往右边扩展区间

    {

    r++;

    sum += r;

    }

    else if(sum >num)//把区间最左边的那个数拿掉

    {

    sum -= l;

    l++;

    }

    else

    {

    int i;

    //输出处理

    //15 = 1+2+3+4+5

    printf("%d = ",num);

    for(i = l;i<r;i++)

    {

    printf("%d+",i);

    }

    printf("%d ",r);

    r++;

    sum += r;

    }

    }

  • 相关阅读:
    github提交用户权限被拒
    vue数据响应式的一些注意点
    总结一下做移动端项目遇到的坑
    react-router
    promise-async-await
    递归函数
    Linux基础
    所有的数据处理都是map-reduce
    Mac下配置JAVA_HOME
    MySQL高级
  • 原文地址:https://www.cnblogs.com/qihuanye-229110/p/11147334.html
Copyright © 2011-2022 走看看