C语言--经典100题_从键盘输入一个大写字母,如果是“j”,则下一行输入两个正整数,表示一个举行的长和

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注运维)
img

正文

60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?

/\*
题目:企业发放的奖金根据利润提成。

利润(I)低于或等于10万元时,奖金可提10%;
利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
20万到40万之间时,高于20万元的部分,可提成5%;
40万到60万之间时高于40万元的部分,可提成3%;
60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
\*/
#include <stdio.h>

int main(){
    float profit,bounse;
    printf("输入利润(单位:万元):");scanf("%f",&profit);
    if(profit<=10){
        bounse=0.1\*profit;
    }else if(profit>10&&profit<20){
        bounse=0.1\*10+0.075\*(profit-10);
    }else if(profit>=20&&profit<40){
        bounse=0.1\*10+0.075\*10+0.05\*(profit-20);
    }else if(profit>=40&&profit<60){
        bounse=0.1\*10+0.075\*10+0.05\*20+0.03\*(profit-40);
    }else if(profit>=60&&profit<100){
        bounse=0.1\*10+0.075\*10+0.05\*20+0.03\*20+0.015\*(profit-60);
    }else if(profit>=100){
        bounse=0.1\*10+0.075\*10+0.05\*20+0.03\*20+0.015\*40+0.01\*(profit-100);
    }
    printf("奖金= %f 万元\n",bounse);
}

运行结果:

输入利润(单位:万元):12
奖金= 1.150000 万元

3、题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?

菜鸟教程:答案

/\*
题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
\*/
#include <stdio.h>
#include <math.h>

int main(){
    double real_aqrt,int_sqrt,result;
    for(int i=0;i<30;i++){
        real_aqrt=sqrt(i+100);
        int_sqrt=(int)real_aqrt;
        result=real_aqrt-int_sqrt;
        // printf("1——real\_aqrt=%lf,int\_sqrt=%lf\n",real\_aqrt,int\_sqrt);
        if(result==0){
            real_aqrt=sqrt(i+100+168);
            int_sqrt=(int)real_aqrt;
            // printf("2——real\_aqrt=%lf,int\_sqrt=%lf\n",real\_aqrt,int\_sqrt);
            if(result==0){
                printf("该数:%d\n",i);
            }
            
        }
    }
}

运行结果:

该数:0
该数:21

【2020-10-11】

4、题目:输入某年某月某日,判断这一天是这一年的第几天?
/\* 题目:输入某年某月某日,判断这一天是这一年的第几天? \*/
#include <stdio.h>

int main(){
    int year=2020,month=10,day=1;
    // printf("输入日期:");
    // printf("年:");scanf("%d",year);
    // printf("月:");scanf("%d",month);
    // printf("日:");scanf("%d",day);
    
    int count,isLeap;
    isLeap=(year%400==0||(year%4==0&&year%100!=0))?1:0; // 1-闰年,0-平年
    switch(month){
        case 1:
            count=day;
            break;
        case 2:
            count=day+31;
            break;
        case 3:
            count=day+31+28;
            if(isLeap){
                count++;
            }
            break;
        case 4:
            count=day+31\*2+28;
            if(isLeap){
                count++;
            }
            break;
        case 5:
            count=day+31\*2+30+28;
            if(isLeap){
                count++;
            }
            break;
        case 6:
            count=day+31\*3+30+28;
            if(isLeap){
                count++;
            }
            break;
        case 7:
            count=day+31\*3+30\*2+28;
            if(isLeap){
                count++;
            }
            break;
        case 8:
            count=day+31\*4+30\*2+28;
            if(isLeap){
                count++;
            }
            break;
        case 9:
            count=day+31\*5+30\*2+28;
            if(isLeap){
                count++;
            }
            break;
        case 10:
            count=day+31\*5+30\*3+28;
            if(isLeap){
                count++;
            }
            break;
        case 11:
            count=day+31\*6+30\*3+28;
            if(isLeap){
                count++;
            }
            break;
        case 12:
            count=day+31\*6+30\*4+28;
            if(isLeap){
                count++;
            }
            break;
        default:
            break;
    }
    printf("所属年度第 %d 天",count);
}

运行结果:

所属年度第 275 天

优化

/\* 题目:输入某年某月某日,判断这一天是这一年的第几天? \*/
#include <stdio.h>

int main(){
    int year=2020,month=10,day=1;
    // printf("输入日期:");
    // printf("年:");scanf("%d",&year);
    // printf("月:");scanf("%d",&month);
    // printf("日:");scanf("%d",&day);
    
    int count,isLeap;
    isLeap=(year%400==0||(year%4==0&&year%100!=0))?1:0; // 1-闰年,0-平年
    switch(month){
        case 1:
            count=day; break;
        case 2:
            count=day+31; break;
        case 3:
            count=day+31+28; break;
        case 4:
            count=day+31\*2+28; break;
        case 5:
            count=day+31\*2+30+28; break;
        case 6:
            count=day+31\*3+30+28; break;
        case 7:
            count=day+31\*3+30\*2+28; break;
        case 8:
            count=day+31\*4+30\*2+28; break;
        case 9:
            count=day+31\*5+30\*2+28; break;
        case 10:
            count=day+31\*5+30\*3+28; break;
        case 11:
            count=day+31\*6+30\*3+28; break;
        case 12:
            count=day+31\*6+30\*4+28; break;
        default:
            break;
    }
    if(isLeap&&month>2){
        count++;
    }
    printf("所属年度第 %d 天",count);
}

5、题目:输入三个整数x,y,z,请把这三个数由小到大输出。
/\* 题目:输入三个整数x,y,z,请把这三个数由小到大输出。 \*/
#include <stdio.h>

int main(){
    int x=3,y=2,z=1;
    // printf("输入x,y,z:");scanf("%d,%d,%d",&x,&y,&z);
    
    // 排序
    int min,mid,max;
    min=mid=max=x;
    if(y<min){
        min=y;
    }else{
        mid=y;
    }
    if(z<min){
        max=mid;
        mid=min;
        min=z;
    }else if(z<mid){
        max=mid;
        mid=z;
    }else{
        max=z;
    }
    printf("由小到大输出:%d,%d,%d",min,mid,max);
}

运行结果:

由小到大输出:1,2,3

方法二

/\* 题目:输入三个整数x,y,z,请把这三个数由小到大输出。 \*/
#include <stdio.h>

int main(){
    int x=6,y=5,z=4;
    // printf("输入x,y,z:");scanf("%d,%d,%d",&x,&y,&z);
    
    // 排序--注意 x y z 的比较顺序
    int temp;
    if(y<x){
        temp=y; y=x; x=temp;
    }
    if(y<x){
        temp=z; z=y; y=temp;
    }
    if(y<x){ // 和第一次判断一样的内容
        temp=y; y=x; x=temp;
    }
    printf("由小到大输出:%d,%d,%d",x,y,z);
}

6、题目:用*号输出字母C的图案。
/\*
题目:用\*号输出字母C的图案。
\*/
#include <stdio.h>

int main(){
    printf(" \*\*\*\n");
    printf(" \*\n");
    printf(" \*\n");
    printf("\*\n");
    printf("\*\n");
    printf(" \*\n");
    printf(" \*\n");
    printf(" \*\*\*\n");
}

/\*
题目:用\*号输出字母C的图案。
\*/
#include <stdio.h>
#include <math.h>

int main(){
    int row=5;
	int mid;
	mid = row%2==0 ? row/2 : (row/2+1); // 判断mid是奇数/偶数
    
	for(int i=1;i<=row;i++){
        for(int j=0;j<abs(mid-i);j++){
            printf(" ");
        }
		printf("\*");
		if(i==1||i==row){ // 第一行和最后一行多补一个
			printf(" \*");
		}
        printf("\n");
    }
}

在这里插入图片描述
在这里插入图片描述

错误:

/\*
题目:用\*号输出字母C的图案。
\*/
#include <stdio.h>

int main(){
    int i=20;
    for(int k=1;k<=i/2;k++){
        for(int j=i/2;j>=1;j--){
            printf("\*");
            if(j==1){
                printf("@\n");
            }
            i--;
        }
    }
    i=20;
    for(int k=1;k<=i/2;k++){
        for(int j=1;j<=i/2;j++){
            printf("\*");
            if(j==1){
                printf("@\n");
            }
            i++;
        }
    }
}

7、【买的资料】题目:有一数组,删除其中奇数元素,留下偶数元素,且不改变原顺序。
重点:int j=0; arr[j]=arr[i]; j++;等价于int j=0; arr[j++]=arr[i];
/\*
题目:有一数组,删除其中奇数元素,留下偶数元素,且不改变原顺序。
\*/
#include <stdio.h>

int renew\_arr(int arr[]){
    int j=0;
    for(int i=0;arr[i];i++){
        if(arr[i]%2==0){
            arr[j]=arr[i]; // 偶数,则保存
            j++; // 重点
        }
    }
    arr[j]='\0'; // 添加结束符号
    // return 0;
}

int main(){
    int arr[]={9,1,4,2,3,6,5,8,7};
    renew\_arr(arr);
    for(int k=0;arr[k];k++){
        printf("%5d",arr[k]);
    }
}

打印结果:

    4    2    6    8

8、【买的资料】题目:将字符串中下标为奇数、同时ASCII码为奇数的字符保留,其余字符组成新字符串。
/\*
题目:将字符串中下标为奇数、同时ASCII码为奇数的字符保留,其余字符组成新字符串。
\*/
#include <stdio.h>
int main(){
    char str[]="ABCDEFG12345",new_str[256];
    int ASCII_value,j=0,k=0;
    
	for(int i=0;str[i];i++){
	    ASCII_value=str[i];
		if(i%2!=0&&ASCII_value%2!=0){
			str[j++]=str[i];
		}else{
		    new_str[k++]=str[i];
		}
	}
	str[j]='\0';// 赋结束符
	new_str[k]='\0';

	printf("保留元素:%s\n", str);
	printf("新字符串:%s\n", new_str);
}

运行结果:

保留元素:135
新字符串:ABCDEFG24

【2020-10-11】图案/形状输出

8、题目:输出9*9口诀。
/\*题目:输出9\*9口诀。\*/
#include <stdio.h>
int main(){
    for(int i=1;i<=9;i++){
        for(int j=1;j<=i;j++){
            printf("%d\*%d=%-3d",i,j,i\*j); // -3d表示左对齐,占3位
        }
        printf("\n");
    }
}

运行结果:

1\*1=1
2\*1=2  2\*2=4
3\*1=3  3\*2=6  3\*3=9
4\*1=4  4\*2=8  4\*3=12 4\*4=16
5\*1=5  5\*2=10 5\*3=15 5\*4=20 5\*5=25
6\*1=6  6\*2=12 6\*3=18 6\*4=24 6\*5=30 6\*6=36
7\*1=7  7\*2=14 7\*3=21 7\*4=28 7\*5=35 7\*6=42 7\*7=49
8\*1=8  8\*2=16 8\*3=24 8\*4=32 8\*5=40 8\*6=48 8\*7=56 8\*8=64
9\*1=9  9\*2=18 9\*3=27 9\*4=36 9\*5=45 9\*6=54 9\*7=63 9\*8=72 9\*9=81

9、题目:图案打印——输出国际象棋棋盘。
/\*
题目:要求输出国际象棋棋盘。
\*/
#include <stdio.h>
int main(){
    int row=8,col=8;
    for(int i=1;i<=8;i++){
        for(int j=1;j<=8;j++){
            if(i%2==1 && j%2==1){
                printf("口");
            }else if(i%2==1 && j%2==0){
                printf("一");
            }else if(i%2==0 && j%2==1){
                printf("一");
            }else if(i%2==0 && j%2==0){
                printf("口");
            }
        }
        printf("\n");
    }
}

运行结果:

口一口一口一口一
一口一口一口一口
口一口一口一口一
一口一口一口一口
口一口一口一口一
一口一口一口一口
口一口一口一口一
一口一口一口一口

以下形式的输出,需要进行如下操作:ASCII码需要在437 OEM-美国,所以需要修改默认代码页936(ANSI/OEM-简体中文GBK)为437 OEM-美国
在这里插入图片描述

10、题目:图案打印——打印楼梯,同时在楼梯上方打印两个笑脸。
/\*题目:打印楼梯,同时在楼梯上方打印两个笑脸。\*/
#include <stdio.h>
int main(){
    printf("☺☺\n");
    for(int i=1;i<10;i++){
        for(int j=1;j<=i;j++){
            printf("口口");
        }
        printf("\n");
    }
}

运行结果:

☺☺
口口
口口口口
口口口口口口
口口口口口口口口
口口口口口口口口口口
口口口口口口口口口口口口

效果图:
在这里插入图片描述

*11、题目:古典问题(兔子生崽):有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(输出前40个月即可)
11.1 思路
  • 找出规律
  • 规律转换成合适的数学公式表示
  • 数学公式转换成合适的算法编程实现
规律分析:每个月兔子的对数(couple):1,1,2,3,5,8,11……

可得,后一个数=前两个数之和

11.2 递归实现
/\*
题目:古典问题(兔子生崽):有一对兔子,从出生后第3个月起每个月都生一对兔子,
小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(输出前40个月即可)
\*/
#include <stdio.h>

int fun(int n){
    int couple_sum;
    for(int i=1;i<=n;i++){
        if(i==1||i==2){
            couple_sum=1;
        }else{
            couple_sum=fun(i-1)+fun(i-2);
        }
    }
    return couple_sum;
}

int main(){
    int month=40,sum=2;
    for(int i=1;i<=40;i++){
        sum=2\*fun(i);
        printf("第 %d 个月:%d 只 ",i,sum);
        printf("第 %d 个月:%d 对\n",i,sum/2);
    }
}

在这里插入图片描述
递归计算耗时,上图是部分计算结果

11.3 改进:迭代实现
#include <stdio.h>
int main(){
    int f1=1,f2=1,i;
    for(i=1;i<=20;i++){
        printf("%12d%12d",f1,f2); // 兔子对数couple
        f1=f1+f2;
        f2=f1+f2;
        if(i%2==0) printf("\n"); // 换行
    }
}

在这里插入图片描述

12、题目:素数/质数

题目:判断101到200之间的素数/质数。

  • break:跳出距离 break 最近的循环
  • continue:结束本次循环,继续下次循环
/\*题目:判断101到200之间的素数/质数。\*/
#include <stdio.h>

int main(){
    int mid;
    for(int i=101;i<=200;i++){
        mid=(i%2==0)?(i/2):(i/2+1); // 取前一半数
        int is_prime=1; // 每开始一次外循环,重新执行初始化
        int j; 
        for(j=2;j<=mid;j++){
            if(i%j==0){
                is_prime=0; // 不是素数
                break; // 跳出内循环
            }
        }
        if(is_prime){
            printf("%d 是素数\n",i);
        }
    }
}

运行结果:

101 是素数   103 是素数   107 是素数
109 是素数   113 是素数   127 是素数
131 是素数   137 是素数   139 是素数
149 是素数   151 是素数   157 是素数
163 是素数   167 是素数   173 是素数
179 是素数   181 是素数   191 是素数
193 是素数   197 是素数   199 是素数

13、题目:水仙花数

题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数 本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。

/\*
题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
\*/
#include <stdio.h>

int main(){
    int num=153,one,two,three;
    three=num/100;
    two=num%100/10;
    one=num%100%10;
    int sum;
    sum=three\*three\*three+two\*two\*two+one\*one\*one;
    if(sum==num){
        printf("%d 是水仙花数\n",num);
    }else{
        printf("%d 不是水仙花数\n",num);
    }
}

14、题目:将一个正整数分解质因数。

例如:输入90,打印出90=233*5

/\*
题目:将一个正整数分解质因数。例如:输入90,打印出90=2\*3\*3\*5。
\*/
#include <stdio.h>

int main(){
    int num=153,mid;
    mid=(num%2)?(num/2):(num/2+1); // 取前一半
    
    printf("%d=",num);
    for(int i=2;i<=mid;i++){
        if(num%i==0){
            printf("%d\*",i);
            num=num/i;
        }
        if(i>=mid){
            printf("%d",num); // 最后一个因子
        }
    }
}


【2020-10-12】

15、题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。

条件语句嵌套:

/\*
题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
\*/
#include <stdio.h>

int main(){
    int score=90;
    
    if(score<60){
        printf("%d - C\n",score);
    }else{
        if(score<90){
            printf("%d - B\n",score);
        }else{
            printf("%d - A\n",score);
        }
    }
}

条件运算符嵌套:

#include <stdio.h>

int main(){
    int score=90;
    char grade;
    
    grade=(score>=90)?'A':(score>60)?'B':'C';
    printf("分数:%d-等级:%c",score,grade);
}

16、题目:最大公约数和最小公倍数

输入两个正整数m和n,求其最大公约数和最小公倍数。

/\*
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
\*/
#include <stdio.h>

int main(){
    int m=12,n=26,min,max;
    min=m>n?n:m;
    max=m>n?m:n;
    int common_divisor,common_multiple;
    for(int i=1;i<=min;i++){
        if((m%i==0) && (n%i==0)){
            common_divisor=i;
        }
    }
    for(int j=max;j<=m\*n;j++){
        if((j%m==0) && (j%n==0)){
            common_multiple=j;
			break; // 找到第一个公约数就关闭循环
        }
    }
    printf("最大公约数:%d\n最小公倍数:%d\n",common_divisor,common_multiple);
}

运行结果:

最大公约数:2
最小公倍数:156

【2020-10-16】

17、题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
/\*
题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
\*/
/\*
分析:scanf结束符为空格、回车,gets结束符为回车,因此选用gets做输入函数
\*/
#include <stdio.h>
#include <string.h>

int main(){
    char str[256];
    printf("输入:");
    gets(str);
    
    int str_length,count_ch=0,count_num=0,count_space=0,count_other=0;
    str_length=strlen(str);
    
    // 统计
    for(int i=0;i<str_length;i++){
    // for(int i=0;str[i]!='\0';i++){ // 也可以
        if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z')){ // 字母
            count_ch++;
        }else if(str[i]>='0'&&str[i]<='9'){ // 数字
            count_num++;
        }else if(str[i]==' '){
            count_space++;
        }else{
            count_other++;
        }
    }
    printf("字母:%d 个\n",count_ch);
    printf("数字:%d 个\n",count_num);
    printf("空格:%d 个\n",count_space);
    printf("其他:%d 个\n",count_other);
}

运行结果:

输入:I am a student.1 2 3 456 789
字母:11 个
数字:9 个
空格:7 个
其他:1 个

18、题目:求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
/\*
题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。
例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
\*/
#include <stdio.h>

// 递归--构造倍数
int multiple(int n){
    int result=0;
    if(n==1){
        result=1;
    }else if(n==2){
        result=10;
    }else{
        result=10\*multiple(n-1);
    }
    return result;
}

// 迭代--构造加数
int addend(int a,int n){
    int addend=0;
    printf("\n计算过程 %d:addend=",n);
    for(int i=1;i<=n;i++){
        addend=addend+a\*multiple(i);
        if(i<n){
            printf("%d+",addend);
        }else{
            printf("%d",addend);
        }
    }
    return addend;
}

int main(){
    int a,n,sum=0;
    printf("数字a:");scanf("%d",&a);
    printf("加数个数:");scanf("%d",&n);
    for(int i=1;i<=n;i++){
        sum=sum+addend(a,i);
    }
    printf("\n\n计算结果:%d\n",sum);
}

运行结果:

数字a:2
加数个数:5

计算过程 1:addend=2
计算过程 2:addend=2+22
计算过程 3:addend=2+22+222
计算过程 4:addend=2+22+222+2222
计算过程 5:addend=2+22+222+2222+22222

计算结果:24690

19、题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。编程找出1000以内的所有完数。例如6=1+2+3.

完全数:它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。

/\*
题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。编程找出1000以内的所有完数。
例如6=1+2+3.
\*/
/\* 步骤:1.求出因子;2.求因子之和 \*/
#include <stdio.h>

int getFactor(int n){
    int sum=0;
    for(int i=1;i<n;i++){
        if(n%i==0){ // 因子
            sum=sum+i;
        }
    }
    return sum;
}

int main(){
    for(int i=1;i<=1000;i++){
        if(getFactor(i)==i){
            printf("\*\*\*\*\*\*\*\*\*\* %d 是完数\n",i);
        }
    }
}

运行结果:

\*\*\*\*\*\*\*\*\*\* 6 是完数
\*\*\*\*\*\*\*\*\*\* 28 是完数
\*\*\*\*\*\*\*\*\*\* 496 是完数

【2020-10-18】

20、题目:小球自由下落

题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?

/\*
题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;
再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
\*/
/\*
分析:每次反弹后,高度减半:1/2HIGH,1/4HIGH,1/8HIGH...
\*/
#include <stdio.h>
#define HIGH 100
#define COUNT 10

// 每次反弹高度
float return\_high(int n){
	float cur_high;
	float denominator=1;
    for(int i=1;i<=n;i++){
        denominator=denominator\*2; // 2的n次方
    }
    cur_high=1/denominator\*HIGH;
	return cur_high;
}

int main()
{
	float sum=HIGH;
   	for(int i=1;i<=COUNT;i++){
   	    sum=sum+2\*return\_high(i);
   	    printf("第 %d 次反弹,反弹后高度为:%f\n",i,return\_high(i));
   	}
   	printf("共经过 %f 米\n",sum);
}

改进:

/\*
分析:每次反弹后,高度减半:HIGH/2,HIGH/4,HIGH/8...
\*/
#include <stdio.h>
#define HIGH 100
#define COUNT 10

int main()
{
	float sum=HIGH,cur_high=HIGH;
   	for(int i=1;i<=COUNT;i++){
   	    cur_high=cur_high/2;
   	    sum=sum+2\*cur_high;
   	    printf("第 %d 次反弹,反弹后高度为:%f 米\n",i,cur_high);
   	}
   	printf("共经过 %f 米\n",sum);
}

运行结果:

第 1 次反弹,反弹后高度为:50.000000 米
第 2 次反弹,反弹后高度为:25.000000 米
第 3 次反弹,反弹后高度为:12.500000 米
第 4 次反弹,反弹后高度为:6.250000 米
第 5 次反弹,反弹后高度为:3.125000 米
第 6 次反弹,反弹后高度为:1.562500 米
第 7 次反弹,反弹后高度为:0.781250 米
第 8 次反弹,反弹后高度为:0.390625 米
第 9 次反弹,反弹后高度为:0.195312 米
第 10 次反弹,反弹后高度为:0.097656 米
共经过 299.804688 米


21、题目:猴子吃桃问题

题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下
的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。

迭代实现

/\*
题目:猴子吃桃问题:
猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
以后每天早上都吃了前一天剩下的一半零一个。
到第10天早上想再吃时,见只剩下一个桃子了。
求第一天共摘了多少。
\*/
#include <stdio.h>
#define DAY 10

int main(){
	int total;
   	for(int i=1;i<=DAY;i++){
   	    if(i==1){
	        total=1;
	    }else{
	        total=2\*(total+1);
	    }
   	}
   	printf("桃子总数: %d 个\n",total);
}

递归实现:

#include <stdio.h>
#define DAY 10

int peach(int n){
    int result;
    if(n==1){
        result=1;
    }else{
        result=2\*(peach(n-1)+1);
    }
    return result;
}

int main(){
   	printf("桃子总数: %d 个\n",peach(DAY));
}

运行结果:

桃子总数: 1534 个

*22、题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。

答案:

/\*
题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。
有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
\*/
#include <stdio.h>

int main(){
    char a,b,c;
    for(a='x';a<='z';a++) {
        for(b='x';b<='z';b++) {
            if(a!=b) {                                    // 限定:a≠b
                for(c='x';c<='z';c++) {
                    if(a!=c&&b!=c) {                      // 限定:b≠c
                        if(a!='x'&&c!='x'&&c!='z') {      // 筛选出满足条件的组合
                            printf("顺序为:\na--%c\nb--%c\nc--%c\n",a,b,c);
                        }
                    }
                }
            }
        }
    }
}

运行结果:

顺序为:
a--z
b--x
c--y

【2020-10-19】

*23、题目:图案打印——菱形

下半部分的模型建立是重点

/\*题目:打印菱形\*/
#include <stdio.h>
#include <math.h>

int main() { 
	int row=10,mid;
	mid=(row%2==0)?(row/2):(row/2+1);
	
	for(int i=1;i<=row;i++){
	    for(int j=1;j<=abs(mid-i);j++){
	        printf(" ");
	    }
	    for(int k=1;k<2\*abs(mid-abs(mid-i));k++){
	        printf("\*");
	    }
	    printf("\n");
	}
}

运行结果:

    \*
   \*\*\*
  \*\*\*\*\*
 \*\*\*\*\*\*\*
\*\*\*\*\*\*\*\*\*
 \*\*\*\*\*\*\*
  \*\*\*\*\*
   \*\*\*
    \*

24、题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和。

递归实现:分子、分母分别找规律

/\*
题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
\*/
#include <stdio.h>
#include <math.h>

#define COUNT 20

float fun(int n,int flag){
    float result;
    if(n==1){
        result=flag?1:2; // flag:0-分子,1-分母
    }else if(n==2){
        result=flag?2:3;
    }else{
        result=fun(n-1,flag)+fun(n-2,flag);
    }
    return result;
}

int main() { 
	float sum=0;
	for(int i=1;i<=COUNT;i++){
	    sum=sum+fun(i,0)/fun(i,1);
	}
	printf("结果:%f",sum);
}

迭代实现:按分数找规律——a=a+b,b=a

#include <stdio.h>
#include <math.h>

#define COUNT 20

int main() { 
	float sum=0,a=2,b=1,temp;
	for(int i=1;i<=COUNT;i++){
	    sum=sum+a/b;
	    temp=a;
	    a=a+b;
	    b=temp;
	}
	printf("结果:%f",sum);
}

运行结果:

结果:32.660263

25、题目:求1+2!+3!+…+20!的和。

递归实现:注意,数据类型需要是long double,因为20!太大了

/\*题目:求1+2!+3!+...+20!的和。\*/
#include <stdio.h>
#define COUNT 20

long double fun(int n){
    long double result=n;
    if(n==1){
        result=1;
    }else{
        result=result\*fun(n-1);
    }
    return result;
}

int main() { 
	long double sum=0;
	// printf("sum=");
	for(int i=1;i<=COUNT;i++){
	    sum=sum+fun(i);
	    // printf("%LF +",fun(i));
	}
	printf("结果:%LF",sum);
}

迭代实现:

/\*题目:求1+2!+3!+...+20!的和。\*/
#include <stdio.h>
#define COUNT 20

int main() { 
	long double sum=1,temp=1;
	// printf("sum=%LF +",temp);
	for(int i=2;i<=COUNT;i++){
	    temp=temp\*i;
	    sum=sum+temp;
	    // printf("%LF +",temp);
	}
	printf("结果:%LF",sum);
}

运行结果:

sum=1.000000 +2.000000 +6.000000 +24.000000 +120.000000 +720.000000 +5040.000000 +40320.000000 +362880.000000 +3628800.000000 +39916800.000000 +479001600.000000 +6227020800.000000 +87178291200.000000 +1307674368000.000000 +20922789888000.000000 +355687428096000.000000 +6402373705728000.000000 +121645100408832000.000000 +2432902008176640000.000000
结果:2561327494111820313.000000

【2020-10-21】

26、题目:利用递归方法求5!
/\*题目:利用递归方法求5!。\*/
#include <stdio.h>

// 递归
int recursion(int n){
    // int result=n; // 方式一
    int result; // 方式二
    if(n==1){
        result=1;
    }else{
        // result=result\*recursion(n-1); // 方式一
        result=n\*recursion(n-1); // 方式二
    }
    return result;
}

// 迭代
int iteration(int n){
    int result=1;
    for(int i=1;i<=n;i++){
        result=result\*i;
    }
    return result;
}

int main() {
    printf("递归:5!=%d\n",recursion(5));
    printf("迭代:5!=%d\n",iteration(5));
}

运行结果:

递归:5!=120
迭代:5!=120

27、题目:利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。
/\*题目:利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。\*/
#include <stdio.h>
#include <string.h>

// 递归
void recursion(char \*p, int cur){
    printf("%5c",\*p);
    if(cur){
        recursion(p-1,cur-1);
    }
}

// 迭代
void iteration(char str[]){
    int length=strlen(str);
    for(int i=length-1;i>=0;i--){
        printf("%5c",str[i]);
    }
}

int main() {
    char str[]="abcde"; // 逆序打印
    
    // 递归
    char \*p; p=str;
    int length=strlen(str);
    recursion(p+length-1,length-1);
    
    // 迭代
    // iteration(str);
}

运行结果:

    e    d    c    b    a

28、题目:递归。有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?
/\*
题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。
问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。
请问第五个人多大?
\*/
#include <stdio.h>
#define AMOUNT 5

// 递归
int recursion(int n){
    int age;
    if(n==1){
        age=10;
    }else{
        age=recursion(n-1)+2;
    }
    return age;
}

// 迭代
int iteration(int n){
    int age=10;
    for(int i=2;i<=n;i++){
        age+=2;
    }
    return age;
}

int main() {
    printf("第 %d 个人年龄:%d\n",AMOUNT,recursion(AMOUNT));
    printf("第 %d 个人年龄:%d\n",AMOUNT,iteration(AMOUNT));
}

运行结果:

第 5 个人年龄:18
第 5 个人年龄:18

*29、题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
#include <stdio.h>

int main() {
    int num;
    do{ // 限制输入数据大小
		printf("输入:");scanf("%d",&num);
	}while(num>100000);
    printf("逆序打印:");
    int count=0;
	for(int i=num;i>0;i=i/10){ // 注意:i!=0,需要i>0
		count++;
		printf("%d ",i%10);
    }
	printf("\n%d 位数\n",count);
}

输入:512
逆序打印:2   1   5
3 位数

#include <stdio.h>

int main() {
    int num;
    do{
		printf("输入:");scanf("%d",&num);
	}while(num>100000);
    printf("逆序打印:");
    int count=0,a,b;
	while(num){
        a=num/10;
        b=num%10; // 个位
        if(a||b){
            count++;
            printf("%2d",b); // 末位
        }
		//if(num>10){ // 注意:不能限制num>10
			num=num/10; // 每次减去末位
		//}
    }
	printf("\n%d 位数\n",count);
}

【2020-10-22】

*30、题目:回文数,首尾比较

题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。

/\*
题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
\*/
#include <stdio.h>

// 判断是几位数
int num\_length(int num){
    int length=0;
    for(int i=num;i>0;i=i/10){
		if(i>10){
			length++;
		}
    }
    return length;
}
// 判断是几位数
int member\_hunder(int num){
    int result=1;
    for(int j=1;j<=num\_length(num);j++){
        result=result\*10;
    }
    return result; // 整十、百、签……
}

// 判断回文数:首尾数字比较
void iteration(int num){
    int first,last; // 记录首尾数字
    
    int flag1=num,flag2=num,flag=0; // flag用于统计首尾相同的次数;flag1用于从后往前逐位推进,flag2用于从前往后逐位推进
    while(flag1){
        last=flag1%10;
        first=flag2/member\_hunder(flag2);
        if(first==last){
            flag++;
            printf("首:%d = 尾:%d\n",first,last);
        }
        flag1=flag1/10; // 后→前
        flag2=flag2-flag2/member\_hunder(flag2)\*member\_hunder(flag2); // 前→后
        // printf("flag1=%d,flag2=%d\n\n",flag1,flag2);
    }
    printf("匹配对数=%d,数值长度=%d\n",flag,num\_length(num)+1);
    if(flag>=(num\_length(num))){
        printf("%d 是回文数\n",num);
    }else{
        printf("%d 非回文数\n",num);
    }
}

int main() {
    int num=12321;
    iteration(num);
}

运行结果:

首:1 = 尾:1
首:2 = 尾:2
首:3 = 尾:3
首:2 = 尾:2
首:1 = 尾:1
匹配对数=5,数值长度=5
12321 是回文数

使用 for 循环:

// 判断回文数:首尾数字比较
void iteration(int num){
    int first,last;
    int mid=(getLength(num)%2==0?getLength(num)/2:getLength(num)/2+1);
    
    int flag1=num,flag2=num,flag=0; // flag用于统计首尾相同的次数
    
    for(int i=1;i<=mid;i++){
        last=flag1%10;
        first=flag2/memberHundred(flag2);
        if(first==last){
            flag++;
            // printf("首:%d = 尾:%d\n",first,last);
        }
        flag1=flag1/10; // 后→前
        flag2=flag2-flag2/memberHundred(flag2)\*memberHundred(flag2); // 前→后
        // printf("flag1=%d,flag2=%d\n\n",flag1,flag2);
    }
    
    printf("匹配对数=%d,数值长度=%d\n",flag,getLength(num)+1);
    if(flag>=mid){
        printf("%d 是回文数\n",num);
    }else{
        printf("%d 非回文数\n",num);
    }
}

需要用到两组变化,第一组:前→后;第二组:后→前
第一组每次获取最高位数字,第二组每次获取最低位数字

last=flag1%10; // 获取低位数字(首位)
first=flag2/memberHundred(flag2); // 获取高位数字(末位)

变化次数前→后后→前
0512512
11251
225
*31、题目:逐字比较

题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母。

#include <stdio.h>
#include <string.h>

struct week{
    char dayStr[20];
}day[7]={{"monday"},{"tuesday"},{"wednesday"},{"thursday"},{"friday"},{"saturday"},{"sunday"}},tempDay[3];

int compare(int index){ // index:当前比较的是第 index 个字符
    char firstCh;
    printf("输入第 %d 个字母:",index+1);
	scanf("%c",&firstCh);
	printf("%c\n",firstCh);

    int count=0;char temp[20];
    for(int i=0;i<7;i++){
        if(index==0){
            strcpy(temp,day[i].dayStr); // 取出星期i
        }else{
            strcpy(temp,tempDay[i].dayStr); // 二次比较,取出星期i
        }
        
        if(firstCh==temp[index]){ // 字符比较
			strcpy(tempDay[count].dayStr,temp); // 存储所有满足条件的星期i,二次比较的时候从这个数组中选取
            count++; // 满足条件的星期i的个数,大于1就继续二次输入
			// strcpy(tempDay[count].dayStr,""); // 将原数组中的末尾设置为结束
        }
    }
    fflush(stdin); // 清空输入缓冲区

	// tempDay记录打印
	for(int k=0;k<2;k++){
        printf("%s\n",tempDay[k].dayStr);
    }

    return count;
}

int main() {
    int count;
    count=compare(0);
    if(count==1){
        printf("对应:%s\n",tempDay[0].dayStr);
    }else if(count>1){
        count=compare(1);
        printf("对应:%s\n",tempDay[0].dayStr);
    }
}

运行结果:

输入第 1 个字母:m
对应:monday

输入第 1 个字母:w
对应:wednesday

输入第 1 个字母:f
对应:friday

输入第 1 个字母:t
tuesday,thursday
输入第 2 个字母:h
thursday
对应:thursday

输入第 1 个字母:t
tuesday,thursday
输入第 2 个字母:u
tuesday,thursday //
对应:tuesday

输入第 1 个字母:s
saturday,sunday
输入第 2 个字母:u
sunday
对应:sunday

输入第 1 个字母:s
saturday,sunday
输入第 2 个字母:a
saturday,sunday // 原因在于没有清缓存,数组缓存。但是并不影响,因为每次会把符合条件的放在前面
对应:saturday

注意——清空输入缓冲区fflush(stdin);

1、不能用枚举,要用结构体

分析:不能用枚举,因为枚举的每个元素对应的是0,1,2...数字
// enum week{monday,tuesday,wednesday,thursday,friday,saturday,sunday} day;
struct week{
    char dayStr[20];
}day[7]={{"monday"},{"tuesday"},{"wednesday"},{"thursday"},{"friday"},{"saturday"},{"sunday"}};

2、bug 解决

  • 问题:第二次scanf无效
  • 原因:第一次输入的回车,在第二次执行时被赋值给变量
  • 解决方法:清空输入缓冲区,清除掉回车fflush(stdin);

参考:https://blog.csdn.net/qq_26768741/article/details/50933598

【2020-10-23】

32、题目:删除指定字母

题目:删除一个字符串中的指定字母,如:字符串 “aca”,删除其中的 a 字母。

#include <stdio.h>
#include <string.h>

int main() {
    char str[200];
    printf("目标字符串:");gets(str);
    char ch;
    printf("删除字母:");ch=getchar();

    int count=0;
    for(int i=0;str[i];i++){
        if(ch!=str[i]){
            str[count++]=str[i];
        }
    }
    str[count]='\0'; // 结束符
    
    printf("%s\n",str);
}

运行结果:

目标字符串:aca
删除字母:a
结果:c

注意——gets()函数有参数,getchar()函数无参数
1.字符串:gets()函数有参数
char str[10];
gets(str);

2.字符:getchar()函数无参数
char ch=getchar();

33、题目:质数/素数

题目:判断一个数字是否为质数。

#include <stdio.h>

int main() {
    int num,flag=1;
    printf("输入数值:");scanf("%d",&num);

	int mid=(num%2==0)?(num/2):(num/2+1);
	for(int i=2;i<mid;i++){
		if(num%i==0){
			flag=0;
			break;
		}
	}
	if(flag){
	    printf("%d 是质数\n",num);
	}else{
	    printf("%d 不是质数\n",num);
	}
}

*35、题目:字符串反转 / 字符串逆序

题目:如将字符串 “www.runoob.com” 反转为 “moc.boonur.www”。

1、下标法:时间复杂度 o(n)
#include <stdio.h>
#include <string.h>

int main() {
    char str[]="www.runoob.com";
    // printf("输入字符串:");gets(str);

    int length=strlen(str);
    char tempStr[length];
    for(int i=0;i<length;i++){
		tempStr[i]=str[length-1-i];
	}
	strcpy(str,tempStr); // 字符串复制,参数2复制到参数1
	printf("反转后:%s\n",str);
}

运行结果:

反转后:moc.boonur.www

2、指针法:时间复杂度 o(1)
#include <stdio.h>
#include <string.h>

int main() {
    char str[]="www.runoob.com";

    int length=strlen(str);int changeAmount=length/2; // 交换次数
    char \*front,\*later;
    char temp; // 临时空间——注意,不能是 char \*temp; 因为temp是没有初始值的,所以使用\*temp时找不到数据
    front=str; // 首地址
    later=str+length-1; // 尾地址

    for(int i=0;i<changeAmount;i++){
        temp=\*later;
        \*later=\*front;
        \*front=temp;
        
        front++;
        later--;
	}
	
	printf("反转后:%s\n",str);
}

字符串操作:
  追加元素
  删除元素
  修改元素
  元素排序
  元素反转
1.空间复杂度o(0)——在原数组上操作
  删除元素
  追加元素
  修改元素
2.空间复杂度o()——开辟临时空间
  元素排序:插入排序/冒泡o(1),
  元素反转:o(n)

注意——开辟临时空间 temp 时,temp 的数据类型不能是指针

因为 temp 没有初始值,那么 *temp 无法找到对应的地址来存放临时数据

【2020-10-24】

*37、题目:排序

题目:对10个数进行排序。

#include <stdio.h>

int nums[10]={23,2,27,98,234,1,4,90,8,34};

// 插入排序
void insertSort(int arr[]){
    int temp;
    for(int i=0;arr[i];i++){
        for(int j=i+1;arr[j];j++){
            if(arr[j]<arr[i]){
                temp=arr[j];
                arr[j]=arr[i];
                arr[i]=temp;
            }
        }
    }
}

// 输入
void scanfArr(){
    printf("输入:");
    for(int i=0;i<10;i++){
        scanf("%d",&nums[i]);
    }
}

// 打印排序后的数组
void printArr(){
	printf("排序后:");
    for(int i=0;nums[i];i++){
	    printf("%d ",nums[i]);
	}
	printf("\n");
}

int main() {
	scanfArr();
	insertSort(nums);
	printArr();
}

运行结果:

输入:23 2 27 98 234 1 4 90 88 34
排序:1 2 4 23 27 34 88 90 98 234 

37.1 选择排序 o(n2)–找出最小,一次交换
// 选择排序
void selectSort(int arr[]){
    int temp,min;
    for(int i=0;arr[i];i++){
        min=i; // 最小值的下标
        for(int j=i+1;arr[j];j++){
            if(arr[j]<arr[min]){
                min=j; // 找到最小值下标
            }
        }
        if(min!=i){ // 最小值下标改变
	        temp=arr[min]; // 当前元素和最小元素交换,最小的放前面
	        arr[min]=arr[i];
	        arr[i]=temp;
        }
    }
}

37.2 插入排序 o(n2)–相邻比较,相邻交换,同步交换下标
// 插入排序
void insertSort(int arr[]){
    int temp,min;
    for(int i=1;arr[i];i++){
        min=i;
        for(int j=i-1;j>=0;j--){
            if(arr[min]<arr[j]){
                temp=arr[j]; // 遇到比自己小的就交换,同时自己的下标同步修改
                arr[j]=arr[min];
                arr[min]=temp;
                min=j;
            }
        }
    }
}

37.3 冒泡排序 o(n2)–相邻比较,相邻交换

不符合冒泡排序定义

// 冒泡排序(注释部分为优化)
void bubbleSort(int arr[]){
    int temp;
    // int isSort=1;
    for(int i=0;arr[i];i++){
    	// isSort=1;
        for(int j=i+1;arr[j];j++){
            if(arr[j]<arr[i]){
                temp=arr[j];
                arr[j]=arr[i];
                arr[i]=temp;
                // isSort=0;
            }
        }
        // if(isSort){
        // break; // 没有变动,已经有序,结束此后的外循环
        // }
    }
}

符合冒泡排序定义,两两比较相邻元素:相邻比较,相邻交换

// 冒泡排序(注释部分为优化)
void bubbleSort(int arr[],int n){
    int temp;
    // int isSort=1;
    for(int i=0;i<n;i++){
    	// isSort=1;
        for(int j=n-1;j>i;j--){
            if(arr[j-1]<arr[j]){
                temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;
                // isSort=0;
            }
        }
        // if(isSort){
        // break; // 没有变动,已经有序,结束此后的外循环
        // }
    }
}

37.4 希尔排序 o(n2*logn)–按步长gap分组,组内冒泡
// 希尔排序(插入排序的变种)
void shellSort(int arr[]){
    // 数组长度
    int length=0;
    for(int i=0;arr[i];i++){
        length++;
    }
    // 排序
    int temp;
    int gap=length/2;
    while(gap){
        for(int j=0;j<length/gap;j++){ // 每组个数
            for(int k=j+gap;arr[k];k=k+gap){ // 组内排序
                if(arr[k]<arr[j]){
                    temp=arr[j];
                    arr[j]=arr[k];
                    arr[k]=temp;
                }
            }
        }
        gap=gap/2;
    }
}

37.5 归并排序

思想
1、递归分割:两两分割
分割数组为小数组,直至小数组为单元素数组
2、递归合并:两两合并
相邻数组合并
合并时排序

38、题目:矩阵对角线元素之和

题目:求一个3*3矩阵对角线元素之和

#include <stdio.h>
#define RANK 3 // 阶数
int arr[RANK][RANK]={
    1,2,3,
    4,5,6,
    7,8,9
};

int main() {
    int sum=0;
    for(int i=0;i<RANK;i++){
        sum=sum+arr[i][i];
    }
    printf("对角线之和=%d\n",sum);
}

对角线之和=15

*39、题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
#include <stdio.h>
#define LENGTH 5

int main() {
    // int arr[LENGTH]={1,2,8,9};
    int arr[LENGTH]={9,8,2,1};
    int num=3;
    int flag=-1;
    // 1.查找插入位置
    for(int i=1;i<LENGTH;i++){
        if((num>arr[i-1]&&num<arr[i])||(num<arr[i-1]&&num>arr[i])){
            flag=i; // 标记插入位置
        }
    }
    if(flag>=0){
        // 2.元素右移,为插入留位置
        for(int j=LENGTH-1;j>=flag;j--){
            arr[j]=arr[j-1];
        }
        // 3.插入
        arr[flag]=num;
    }
	
	void printArr(int arr[]);
	printArr(arr);
}

void printArr(int arr[]){
    printf("插入后数组:");
    for(int i=0;i<LENGTH;i++){
        printf("%d ",arr[i]);
    }
    printf("\n");
}

插入后数组:1 2 3 8 9 

【2020-10-25】

40、题目:数组逆序打印
40.1 逆序输出(不改变数组顺序)

题目:将一个数组逆序输出。

/\*
题目:将一个数组逆序输出。
\*/
#include <stdio.h>
#define LENGTH 5
int arr[LENGTH]={9,8,2,1};

// 1.下标法 时间复杂度o(n)
void byIndex(){
    // 数组长度
    int length=0;
    for(int i=0;i<LENGTH;i++){
        length++;
    }
    
    for(int i=length-1;i>=0;i--){
        printf("%d ",arr[i]);
    }
}

// 2.指针法 时间复杂度o(n)
void byPoint(){
    // 数组长度
    int length=0;
    for(int i=0;i<LENGTH;i++){
        length++;
    }
    
    int \*front; // 首指针
    front=arr+length-1; // 尾地址赋值给首指针
    int \*i;
    for(i=front;i>=arr;i--){
        printf("%d ",\*i); // 输出
    }
}

// 数组打印
void printArr(){
    for(int i=0;i<LENGTH;i++){
        printf("%d ",arr[i]);
    }
}

int main() {
    printf("逆序打印(下标法):");
    byIndex();
    printf("\n逆序打印(指针法):");
    byPoint();
    
    printf("\n数组顺序(不变):");
    printArr();
}

运行结果:

逆序打印(下标法):0 1 2 8 9 
逆序打印(指针法):0 1 2 8 9 
数组顺序(不变):9 8 2 1 0 

40.2 数组逆序(改变数组顺序)
/\*
题目:将一个数组逆序。
\*/
#include <stdio.h>
#define LENGTH 5
int arr[LENGTH]={9,8,2,1};

// 数组打印
void printArr(){
    for(int i=0;i<LENGTH;i++){
        printf("%d ",arr[i]);
    }
}

// 1.下标法 时间复杂度o(n)
void byIndex(){
    int temp;
    int mid=(LENGTH-1)/2;
    for(int i=0;i<mid;i++){
        temp=arr[i];
        arr[i]=arr[LENGTH-1-i];
        arr[LENGTH-1-i]=temp;
    }
}

// 2.指针法-迭代法:交换首尾数据 时间复杂度o(n)
void byPoint(){
    int temp_1;int \*temp_2;
    int \*front,\*later;
    front=arr;
    later=arr+LENGTH-1;
    
    int mid=LENGTH/2; // 交换次数
    for(int i=1;i<=mid;i++){ // 前后交换数据
        temp_1=\*front;
        \*front=\*later;
        \*later=temp_1;
        front++;
        later--;
    }
}

int main() {
    printArr();
    
    printf("\n逆序(下标法):");
    byIndex();
    printArr();
    
    printf("\n逆序(指针法):");
    byPoint();
    printArr();
}

运行结果:

9 8 2 1 0 
逆序(下标法):0 1 2 8 9 
逆序(指针法):9 8 2 1 0 

注意——数组逆序操作,只能交换数据,不能交换地址??——因为地址是常量
// 2.指针法-迭代法:交换首尾指针 时间复杂度o(n)
void byPoint(){
    int temp_1;int \*temp_2;
    int \*front,\*later;
    front=arr;
    later=arr+LENGTH-1;
    
    int mid=LENGTH/2; // 交换次数
    // for(int i=1;i<=mid;i++){ // 前后交换数据--正确
    // temp\_1=\*front;
    // \*front=\*later;
    // \*later=temp\_1;
    // front++;
    // later--;
    // }
    for(int i=1;i<=mid;i++){ // 前后交换地址--无效
        if(i==1){
            temp_2=front;
            front=later;
            later=temp_2;
        }else{
            front=front-1;
            later=later+1;
        }
    }
}

41、for循环条件中定义的变量的作用范围
  • 循环条件中定义的变量 i 只在当前 for 循环中(作用域{})有效
  • 同一个函数内,多个 for 循环中可以分别定义 i 为变量——因为 i 的作用范围为当前 for 循环
#include <stdio.h>

int main() {
    for(int i=0;i<3;i++){
        int a=1;
        printf("%d ",a);
    }
    for(int j=0;j<3;j++){
        i=10;  // 报错:i 没有定义 → i 只在上面的for中(定义的{}中)有效
        printf("%d ",i);
    }
}

同一个函数内,多个 for 循环中可以分别定义 i 为变量——因为 i 的作用范围为当前 for 循环。如下:

#include <stdio.h>

int main() {
    for(int i=0;i<3;i++){
        int a=1;
        printf("a=%d\n",a);
    }
    for(int i=0;i<3;i++){
        int b=10;
        printf("b=%d\n",b);
    }
}

41、static定义静态变量的用法
  • 用法一:保持调用数据
    函数调用之后,static变量会保持调用结束的数据,下次调用时继续使用
  • 用法二:内置模块
    互不相干
#include <stdio.h>
int main(){
    int i,num;
    num=2;
    for(i=0;i<3;i++){
        printf("num 变量为 %d \n",num);
        num++;
        {
            static int num=1;
            printf("内置模块 num 变量为 %d\n",num);
            num++;
        }
    }
    return 0;
}

43、内置模块——可嵌入的独立作用域
  • 内置模块中的变量和内置模块外的变量互不相干
  • 内置模块中的变量作用域只在内部模块中
/\*
内置模块
\*/
#include <stdio.h>

int main(){
    int num=2;
    // static int num=2;
    for(int i=0;i<3;i++){
        printf("函数中:num=%d \n",num);num++;
        {
            int num=1;
            // static int num=1;
            printf("函数内置模块中:num=%d\n",num);num++; // 内置模块中的变量作用域只有内部模块
        }
    }
    printf("\nnum=%d\n",num); // 是函数中的num
}

函数中:num=2 
函数内置模块中:num=1
函数中:num=3 
函数内置模块中:num=1
函数中:num=4 
函数内置模块中:num=1

num=5

44、external的用法

【2020-10-26】

45、register的用法
  • 寄存器变量。存放在寄存器中,而非内存中
  • 不能用 & 来获取地址
  • 只能是单个的值(不能是数组),并且长度<=整型的长度
  • 只有auto变量和形参可以做寄存器变量
  • 寄存器只用于需要快速访问的变量,比如计数器
46、宏 #define

宏可以定义:

  • 全局变量
  • 表达式
  • 函数(注意,不能换行)
  • 比较规则(>、<、==)

1、定义函数

#include <stdio.h>
#define exchange(a,b) { int t;t=a;a=b;b=t;} //注意放在一行里

int main(){
    int x=10,y=20;
    exchange(x,y);
    printf("交换后:x=%d, y=%d\n",x,y);
}

运行结果:

交换后:x=20, y=10

2、定义规则

#include <stdio.h>
#define LAG >
#define SMA <
#define EQ ==

int main(){
    int i=1,j=2;
    if(i LAG j)
        printf("%d 大于 %d \n",i,j);
    else if(i EQ j)
        printf("%d 等于 %d \n",i,j);
    else if(i SMA j)
        printf("%d 小于 %d \n",i,j);
    else
        printf("没有值。\n");
}

运行结果:

1 小于 2 

49、#if、#ifdef、#ifndef
语句含义
#define宏定义
#ifdef如果已经存在宏定义
#ifndef如果没有该宏定义
#endif结束条件语句
#undef取消宏定义
#define宏定义
#include<stdio.h>
#define MAX
#define MAXIMUM(x,y)(x>y)?x:y
#define MINIMUM(x,y) (x>y)?y:x
int main(){
	// 1.如果已经定义了MAX
	#ifdef MAX
	    printf("更大的数字是 %d\n",MAXIMUM(a,b)); // 如果已经定义了MAX,执行这一条
	#else
	    printf("更小的数字是 %d\n",MINIMUM(a,b));
	#endif // 结束条件语句
	
	// 2.如果没有定义
	#ifndef MIN
	    printf("更小的数字是 %d\n",MINIMUM(a,b));// 如果没有定义MIN,执行这一条
	#else
	    printf("更大的数字是 %d\n",MAXIMUM(a,b));
	#endif
	
	// 3.取消宏定义
	#undef MAX
	#ifdef MAX
	    printf("更大的数字是 %d\n",MAXIMUM(a,b));
	#else
	    printf("更小的数字是 %d\n",MINIMUM(a,b));
	#endif
	
	// 4.定义宏
	#define MIN
	#ifndef MIN
	    printf("更小的数字是 %d\n",MINIMUM(a,b));
	#else
	    printf("更大的数字是 %d\n",MAXIMUM(a,b));
	#endif
}

运行结果:

更大的数字是 20
更小的数字是 10
更小的数字是 10
更大的数字是 20

51、按位与运算 &、按位或运算 |、按位异或运算 ^
54、题目:取一个整数 a 从右端开始的 4~7 位

答案:https://www.runoob.com/cprogramming/c-exercise-example54.html

/\*
题目:取一个整数 a 从右端开始的 4~7 位。
\*/
/\*
分析:十进制→二进制→移位
需要获取移出的位,方法:将移位后的数值和某一个数(1111B=7)做按位与(同1为1),即可得到4-7位
\*/
#include <stdio.h>

int main(){
    int num=36,result,temp,t=7;
    
    temp=num>>4;
    result=temp&t;
    printf("%d\n",result);
}

运行结果:

结果:2
2=0010B

53、按位取反~

0取反为-1
1取反为-2
-1取反为0
-2取反为1

#include <stdio.h>

int main(){
    int num=2,temp;
    
    temp=~num;
    printf("%d\n",temp);
    printf("%x\n",temp);
}

结果:-3
fffffffd


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
![img](https://img-blog.csdnimg.cn/img_convert/7995d2ee760d43fb13aee3a27c3b92ef.jpeg)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
是函数中的num
}

函数中:num=2 
函数内置模块中:num=1
函数中:num=3 
函数内置模块中:num=1
函数中:num=4 
函数内置模块中:num=1

num=5

44、external的用法

【2020-10-26】

45、register的用法
  • 寄存器变量。存放在寄存器中,而非内存中
  • 不能用 & 来获取地址
  • 只能是单个的值(不能是数组),并且长度<=整型的长度
  • 只有auto变量和形参可以做寄存器变量
  • 寄存器只用于需要快速访问的变量,比如计数器
46、宏 #define

宏可以定义:

  • 全局变量
  • 表达式
  • 函数(注意,不能换行)
  • 比较规则(>、<、==)

1、定义函数

#include <stdio.h>
#define exchange(a,b) { int t;t=a;a=b;b=t;} //注意放在一行里

int main(){
    int x=10,y=20;
    exchange(x,y);
    printf("交换后:x=%d, y=%d\n",x,y);
}

运行结果:

交换后:x=20, y=10

2、定义规则

#include <stdio.h>
#define LAG >
#define SMA <
#define EQ ==

int main(){
    int i=1,j=2;
    if(i LAG j)
        printf("%d 大于 %d \n",i,j);
    else if(i EQ j)
        printf("%d 等于 %d \n",i,j);
    else if(i SMA j)
        printf("%d 小于 %d \n",i,j);
    else
        printf("没有值。\n");
}

运行结果:

1 小于 2 

49、#if、#ifdef、#ifndef
语句含义
#define宏定义
#ifdef如果已经存在宏定义
#ifndef如果没有该宏定义
#endif结束条件语句
#undef取消宏定义
#define宏定义
#include<stdio.h>
#define MAX
#define MAXIMUM(x,y)(x>y)?x:y
#define MINIMUM(x,y) (x>y)?y:x
int main(){
	// 1.如果已经定义了MAX
	#ifdef MAX
	    printf("更大的数字是 %d\n",MAXIMUM(a,b)); // 如果已经定义了MAX,执行这一条
	#else
	    printf("更小的数字是 %d\n",MINIMUM(a,b));
	#endif // 结束条件语句
	
	// 2.如果没有定义
	#ifndef MIN
	    printf("更小的数字是 %d\n",MINIMUM(a,b));// 如果没有定义MIN,执行这一条
	#else
	    printf("更大的数字是 %d\n",MAXIMUM(a,b));
	#endif
	
	// 3.取消宏定义
	#undef MAX
	#ifdef MAX
	    printf("更大的数字是 %d\n",MAXIMUM(a,b));
	#else
	    printf("更小的数字是 %d\n",MINIMUM(a,b));
	#endif
	
	// 4.定义宏
	#define MIN
	#ifndef MIN
	    printf("更小的数字是 %d\n",MINIMUM(a,b));
	#else
	    printf("更大的数字是 %d\n",MAXIMUM(a,b));
	#endif
}

运行结果:

更大的数字是 20
更小的数字是 10
更小的数字是 10
更大的数字是 20

51、按位与运算 &、按位或运算 |、按位异或运算 ^
54、题目:取一个整数 a 从右端开始的 4~7 位

答案:https://www.runoob.com/cprogramming/c-exercise-example54.html

/\*
题目:取一个整数 a 从右端开始的 4~7 位。
\*/
/\*
分析:十进制→二进制→移位
需要获取移出的位,方法:将移位后的数值和某一个数(1111B=7)做按位与(同1为1),即可得到4-7位
\*/
#include <stdio.h>

int main(){
    int num=36,result,temp,t=7;
    
    temp=num>>4;
    result=temp&t;
    printf("%d\n",result);
}

运行结果:

结果:2
2=0010B

53、按位取反~

0取反为-1
1取反为-2
-1取反为0
-2取反为1

#include <stdio.h>

int main(){
    int num=2,temp;
    
    temp=~num;
    printf("%d\n",temp);
    printf("%x\n",temp);
}

结果:-3
fffffffd


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
[外链图片转存中...(img-juwHzqPe-1713124405622)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值