c语言谭浩强第五版---全书笔记+习题(二)

用while、do-while和for语句实现循环
案例:求1+2+3+4+…+100;的值

    int i=1,num=0;
    while (i<=100){
        num=num+i;
        i++;
    }
    printf("累计之和是:%d",num);
//用do-while实现
    int i=1,sum=0;
    do {
        sum=sum+i;
        i++;
    }while (i<=100);
    printf("累计的值是:%d",sum);
//用for语句实现
    int i,sum=0;
    for(i=1;i<=100;i++){
        sum=sum+i;
    }
    printf("累计的值是:%d",sum);

案例:for语句的三个表达式,i=1可以省略,但是后面的";" 不能省略;省略之后要在for循环之前 初始化i的值,如int i=1;
表达式三也可以省略,如下:

    int i,sum=0;
    for(i=1;i<=100;){
        sum=sum+i;
        i++;     //省略的时候,可以在循环体中使循环变量增值
    }

表达式13,可以是一个简单的表达式,也可以是逗号表达式,如下:

for(i=0,j=100;i<=j;i++,j--)k=i+j;

逗号表达式内,自左向右顺序求解,如下:

for(i=i;i<=100;i++,i++)sum=sum+i; 

相当于

 for(i=i;i<=100;i+2)sum=sum+i;

表达式2一般是关系表达式(i<=100)或者逻辑表达式(a
但也可以是数值表达式或字符表达式,只要其值是非0就执行循环体,如下:

for(i=1;(c=getchar()!='\n';i+=c));

for循环中定义的变量只能在for循环中使用

whiledo-while的比较

  • do-while是先执行循环体,最少执行一次
  • while是先执行判断,可能一次都不执行
  • 三种循环方式都能用break;结束循环。用continue;结束本次循环;

案例
全系1000名学生,慈善募捐,累计捐到10万元就结束,计算人均捐款;

  • 可以在文件头定义下常量# define SUM=100000; 下面的程序可以直接用哦
    float amount,total,aver;
    int i;
    for(i=1;i<=1000;i++){
        printf("please enter amount:");
        fflush(stdout);
        scanf("%f",&amount);
        total=total+amount;
        if (total>=100000)break;
    }
    aver=total/i;
    printf("捐献总额是:%f。捐献人数是:%d。人均捐献是:%f",total,i,aver);

	//要求输出100~200不能被3整除的整数。需要你用到continue
    printf("The number divisible by 3 is:");
    for(int i=100;i<=200;i++){
        if(i%3==0){
            printf("%d ",i);
        }
    }

输出以下4*5的矩阵
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20

    for(int i=1;i<=4;i++){
        for(int j=1;j<=5;j++){
            if (j==5){
                printf("%d \n",j*i);break;   //结束本次循环,外层循环依然执行
            }else{
                printf("%d ",j*i);
            }
        }
    }

计算π的近似值:π/4=1-1/3+1/5-1/7+…求π的近似值,直到发现某一项的绝对值小于10^(-6); 10的负6次方

 double pi=0.0,term=1.0,n=1.0;
    int sign=1;
    while (fabs(term)>=1e-6){   //e前面是一
        pi=pi+term;
        n=n+2;
        sign=-sign;
        term=sign/n;
    }
    pi=pi*4;
    printf("pi=%10.8f\n",pi);

求斐波那契数列前40个数。有如下特点:
第1和2两个数是1,1。从第三个数开始,是前面两个数字之和。如:1,1,2,3,5,8,13…

int a=1;
int b=1;
int c;
for(int i=1;i<=38;i++){
    c=a+b;   // 2  3  5  8  13 ....
    a=b;     // 1  2  3  5  8  ....
    b=c;     // 2  3  5  8  13 ....
}
printf("前40个数字之和是:%d",c);

求100~200的全部素数。 (除了1和它本身以外,不能被整除的数) 2是唯一的偶数素数,所有循环的时候要排除偶数

int k;
printf("All prime number between 100 and 200 are: ");
for(int n=101;n<200;n+=2){
    k=sqrt(n);
    for(int i=2;i<=k;i++){
        if(n%i!=0){
            printf("%d ",n);break;
        }
    }
}

译密码,为了保密,往往按一定规律将其转成密码。收报再按照约定的规律译回原文。
规律:A变成E,a变成e,即变成其后面第4个字符。输入China,输出对应的密码(Glmre)

char c=getchar();
while(c!='\n'){
    if((c>='a' && c<='z') || (c>='A' && c<='Z')){
        if((c>='W' && c<='Z' || c>='w'&&c<='z')){
            c=c-22;
        }else {
            c=c+4;
        }
    }
    printf("%c",c);
    c=getchar();
}

输入两个数m和n,求其最大公约数和最小公倍数。
几个自然数公有的倍数,叫做这几个数的公倍数,其中最小的一个自然数,叫做这几个数的最小公倍数。
几个整数中公有的约数,叫做这几个数的公约数;其中最大的一个,叫做这几个数的最大公约数。

int a,b,num1,num2,temp;
printf("please input two number:\n");
fflush(stdout);
scanf("%d,%d",&num1,&num2);
if(num1<num2){
    temp = num1;
    num1 = num2;
    num2 = temp;
}
a = num1;  //大的那个数
b = num2;
while(b!=0){   //利用辗除法,a=25,b=15,a%b=10,b%10=5,10%5=0,最后一个为被除数余数的除数就是5,5就是所求最大公约数
    temp = a%b;
    a=b;
    b=temp;
}
printf("lcm:%d\n",a);   //lowest common multiple(倍数)
printf("gcd:%d\n",num1*num2/a);  //greatest common divisor(除数 因子)

求S=a+aa+aaa+…+aaaaa…(n个a)。键盘上输入一个一个位数n,求S的值。

int S=0,n,a=2,temp=0;
printf("please enter a number:\n");
fflush(stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
    temp=temp*10+a;
    S+=temp;
    printf("%d\n",temp);   //打印出每次加的值
}
printf("total is:%d",S);

求1!+2!+3!+4!+…+20!的值。 阶乘5!就是12345

int i,j;
double sum,a;
for(i=1;i<=20;i++){
    for(j=1,a=1;j<=i;j++){
        a=a*j;
    }
    sum+=a;
    printf("%d!=%20.0f,sum=%20.0f\n",i,a,sum);
}
printf("%20.0f",sum);

求k=1,k到100的相加和,k平方到50的相加和,1/k到10的相加和。

double S,Sk=0.0,Sk1,Sk2;
for(int i=1;i<=100;i++){
    Sk=i+Sk;
}
printf("Sk的值:%f\n",Sk);

for(int j=1;j<=50;j++){
    Sk1=j*j+Sk1;
}
printf("Sk1的值:%f\n",Sk1);
for(int m=1;m<=10;m++){
    Sk2=(double)1/m+Sk2;   //需要强制转换一下,不然结果是int类型
}
printf("Sk2的值:%f\n",Sk2);
S=Sk+Sk1+Sk2;
printf("S的值:%f",S);

输出所有水仙花数,所谓水仙花数是指一个三位数,其各位数的立方等于该数本身;如:153=1³+5³+3³
因为水仙花数是三位数,所以不能小于100,也不能大于等于1000

for(int i=100;i<1000;i++){
    int a=i%10;
    int b=i/10%10;
    int c=i/100;
    if((a*a*a)+(b*b*b)+(c*c*c)==i)
        printf("%d是水仙花数\n",i);
}

一个数如果恰好等于它的因子之和,这个数称之为完整。例如6的因子是1,2,3。6=1+2+3
找出1000以内所有完整的数,按照6 its factors are 1,2,3

for(int i=1;i<=1000;i++){
    int sum=0;
    int n;
    for(int j=1;j<=i/2;j++){
        if(i%j==0){  //因子
            sum+=j;
        }
    }
    if(sum==i){
        printf("%d its factors are ",sum);
        for(n=1;n<=i/2;n++){//循环输出所有因子
            if(i%n == 0){
                if(n==i/2){
                    printf(",%d\n",n);  //最后一个因子要换行,这样最外层循环的时候 才会换行输出
                }else if(n==1){
                    printf("%d",n);
                }else{
                    printf(",%d",n);   //第一个因子不加逗号输出
                }
            }
        }
    }
}

有一个分数序列:2/1,3/2,5/3,8/5,13/8,21/13,…
求这个数列前20项之和

int a=2;
int b=1;
int temp;
float sum;
for(int i=0;i<20;i++){
    sum+=(float)a/b;
    temp=a;
    a=a+b;
    b=temp;
}
printf("The sum of the first 20 terms is %f",sum);

一个球从100米高度落下,每次落地后反弹回原高度的一半,在落下,在反弹。
求它在第10次落地时共经历多少米,第10次反弹多高

float totalDis=100.0,tenDis=100.0;  //初始化totalDis的距离是100,也就是第一次下落的距离
for(int i=0;i<10;i++){
    tenDis=tenDis/2;
    totalDis+=tenDis*2;   //一上一下 两次的距离
}
printf("The 10th rebound:%f\n",tenDis);
printf("The tenth landing was %f meters in total.",totalDis);

猴子第一天摘了若干个桃子,每天吃一半零1个。第10天只剩下1个。求共摘了多少个桃子

    int peachTotal=1;
    for(int i=0;i<9;i++){
        peachTotal=(peachTotal+1)*2;
    }
    printf("The number of peaches that the monkey picked on the first day was %d",peachTotal);

	//用迭代(辗转)法求 x=根号a。求平方根的迭代公式为:X(n+1)=(Xn+a/Xn) /2。要求前后两次求出的差的绝对值小于0.00001
    double x1,x2;
    float a;
    scanf("%f", &a);
    x2 = 1.0;
    for(;;){                         //死循环
        x1 = x2;                     //后一个值赋值给前一个
        x2 = (x1 + a / x1) / 2.0;    //重新算后一个值
        if (fabs(x1 - x2) < 0.00001) {   //判断
            printf("x1的值是%f,x2的值是%f",x1,x2);
            break;
        }
    }

用牛顿迭代法求下面方程在1.5附近的根 2x³-4x²+3x-6=0
关于牛顿迭代法,在计算方法课程中讲到,简单解释下,基本公式为:
Xn+1=Xn-f(Xn)/g*(Xn) 其中Xn+1为第n+1次迭代结果,Xn为第n次迭代结果,g*(Xn)为f((Xn))的导函数值。

int i=0;
double x1=1.5,x2=0;//迭代初值
while (fabs(x2-x1)>=1e-5)
{
    x1=x1-(2*x1*x1*x1-4*x1*x1+3*x1-6)/(6*x1*x1-8*x1+3);
    x2=x1-(2*x1*x1*x1-4*x1*x1+3*x1-6)/(6*x1*x1-8*x1+3);
    i++;
    printf("第%d次迭代  x1=%9.8f\tx2=%9.8f\n",i,x1,x2);
}
printf("\nx=%9.8f\t共迭代:%d次\n",x2,i);

打印菱形图案

int i;
int j;
int m;
int line=7;
int line1=7;
for(i=0;i<=line/2;i++){    //正三角形4行
    for(j=0;j<line/2-i;j++){    //空格
        printf(" ");
    }
    for(m=0;m<i*2+1;m++){    //*字符
        printf("*");
    }
    printf("\n");
}
for(i=1;i<=line/2;i++) {    //倒三角形3行
    for(j=0;j<i;j++){    //空格
        printf(" ");
    }
    for(m=0;m<line1-2;m++){    //*字符
        printf("*");
    }
    printf("\n");
    line1-=2;
}

两个乒乓球队进行比赛,各出三人。甲队为A,B,C三人,乙队为X,Y,Z三人,比赛名单已定,有打听知,A说他不和X比,C说不和X和Z比,编程找出比赛名单

char A, B, C, str;
for (str='X';str<='Z';str++) {  //X到Z
    if (str!='X'&&str!='Z') {//C不和X,Z比
        C=str;
    }
}
for(str='X';str<='Z';str++){
    if(str!='X'&&str!=C){
        A=str;
    }
}
for(str='X';str<='Z';str++){
    if(str!=A&&str!=C){
        B=str;
    }
}
printf("A的对手是%c\n", A);
printf("B的对手是%c\n", B);
printf("C的对手是%c\n", C);

一维数组

  • 定义:数组名[常量表达式] 如a[10],数组的下标从0开始
  • 常量表达式中包括符号常量和常量;如 int m [3+5]; 但是不能包含变量如 int m [a],下面三行定义是不行的:
    int n;
    scanf("%d",&n);
    int a[n]; 错误的定义数组方式,但是引用数组里面的某个元素是可以使用a[b]的形式的,如下面的case(案例)
  • 引用数组: a[0]=a[5]+a[7]+a[3*5];
  • 注意点!!!
    int a[10]; —前面有int,这是定义数组,包含10个元素
    a[6]; —这里表示引用 a数组中下标是 6的元素
  • 一维数组初始化
    int a[10]={0,1,2,3,4,5,6,7,8,9};
  • 也可以添加部分元素,如下
    int a[10]={0,1,2,3,4,5}; 余下的元素都是 0,默认值
  • 如果想让一个数组初始化元素都是 0,可以如下赋值
    int a[10]={0,0,0,0,0,0,0,0,0,0};或者 int a[10]={0};
  • 在数组赋初始值的时候,如果元素已经确定,可以不指定数组长度,如下
    int a[5]={0,1,2,3,4};可以写成 int a[]={0,1,2,3,4};

对10个数组元素一次赋值,0,1,2,3,4,5,6,7,8,9。并按逆序输出

int i,a[10];
for(i=0;i<10;i++){
    a[i]=i;
}
printf("逆序输出:");
printf("\n");
for(i=9;i>=0;i--){
    printf("the value of %dth element of the array is:%d",i,a[i]);
    printf("\n");
}

用数组处理斐波那契Fibonacci数列

int i;
int a[20]={1,1}; //数组的前两个元素的值是1,1
for(i=2;i<20;i++){
    a[i]=a[i-1]+a[i-2];
}
for(i=0;i<20;i++){
    printf("The value of %dth element of array is:%d",i,a[i]);
    printf("\n");
}

你可能感兴趣的:(C语言,c语言)