【2020-10-10】

1、题目:有1、2、3、4四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

/*
题目:有1、2、3、4四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
*/
#include <stdio.h>int main(){int arr[]={1,2,3,4};// 创造三位数--三重循环int n=0,result[256];for(int i=1;i<5;i++){// i-百位,j-十位,k-个位for(int j=1;j<5;j++){for(int k=1;k<5;k++){if(k!=i&&k!=j&&j!=i){ // 避免重复数字result[n++]=100*i+10*j+k;result[n]='\0';}}}}// 打印for(int i=0;result[i];i++){printf("%d\n",result[i]);}
}

运行结果:

  123  124  132  134  142  143213  214  231  234  241  243312  314  321  324  341  342412  413  421  423  431  432

2、题目:企业发放的奖金根据利润提成。

利润(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,求应发放奖金总数?

/*
题目:企业发放的奖金根据利润提成。利润(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); // 兔子对数couplef1=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 10int 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 10int 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 10int 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≠bfor(c='x';c<='z';c++) {if(a!=c&&b!=c) {                      // 限定:b≠cif(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 20float 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 20int 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 20long 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 20int 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>0count++;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>10num=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); // 获取高位数字(末位)
变化次数 前→后 后→前
0 512 512
1 12 51
2 2 5

*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复制到参数1printf("反转后:%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 5int 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=1num=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);elseprintf("没有值。\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 MAXprintf("更大的数字是 %d\n",MAXIMUM(a,b)); // 如果已经定义了MAX,执行这一条#elseprintf("更小的数字是 %d\n",MINIMUM(a,b));#endif // 结束条件语句// 2.如果没有定义#ifndef MINprintf("更小的数字是 %d\n",MINIMUM(a,b));// 如果没有定义MIN,执行这一条#elseprintf("更大的数字是 %d\n",MAXIMUM(a,b));#endif// 3.取消宏定义#undef MAX#ifdef MAXprintf("更大的数字是 %d\n",MAXIMUM(a,b));#elseprintf("更小的数字是 %d\n",MINIMUM(a,b));#endif// 4.定义宏#define MIN#ifndef MINprintf("更小的数字是 %d\n",MINIMUM(a,b));#elseprintf("更大的数字是 %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
num=2=0000 0010B
取反:0000 0010B → 1111 1101B(补码)→ 1000 0011B(原码)=-3
所以,2取反为-3

**56、画图——画圆

题目:画图,学用circle画圆形

/*
题目:画圆。
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>// 圆:R*R=x*x+y*y
void circle(){double y,m;int x;for(y=10;y>=-10;y--){ //圆的半径为10m=2.5*sqrt(100-y*y); //计算行y对应的列坐标m,2.5为屏幕纵横比调节系数,//屏幕的行距大于列距,不调节会是椭圆for(x=1;x<30-m;x++){printf(" "); //图形左侧空白控制}printf("*"); //圆的左侧for(;x<30+m;x++){printf(" ");}printf(" * \n"); //圆的右侧}
}void quxian(){double y;int x, m;for (y = 1; y >= -1;y-=0.1)  //y为列方向,值从1到-1,步长为0.1{m = acos(y) * 10;    //计算出y对应的弧度m,乘10为图像扩大倍数for (x = 1; x < m;x++){printf(" ");}printf("*");         //控制打印左侧的*号for (; x < 62 - m;x++){printf(" ");}printf("*\n");       //控制打印同一行中对称的右侧的*号}
}int main(){circle();quxian();
}
#include <stdio.h>
#include <math.h>
#include <stdlib.h>// 圆:R*R=x*x+y*y
void circle(){double y,m;int x;for(y=5;y>=-5;y--){ //圆的半径为5m=2.5*sqrt(25-y*y); //计算行y对应的列坐标m,2.5为屏幕纵横比调节系数--屏幕的行距大于列距,不调节会是椭圆for(x=1;x<15-m;x++){printf(" "); //图形左侧空白控制}printf("*"); //圆的左侧for(;x<15+m;x++){printf(" ");}printf(" * \n"); //圆的右侧}
}
int main(){circle();
}
              * * *                * *                     * *                        * *                          * *                          * *                          * *                        * *                     * *                * * *

57、画图——画直线

58、画图——画长方形

*61、题目:杨辉三角形

题目:打印出杨辉三角形(要求打印出10行)。
二元数组
找好规律

/*
题目:打印出杨辉三角形(要求打印出10行)。
*/
/*
二元数组
*/
#include <stdio.h>int main(){int row=10;int arr[row][row];for(int i=0;i<row;i++){arr[i][0]=1;arr[i][i]=1;}for(int i=2;i<row;i++){for(int j=1;j<i;j++){arr[i][j]=arr[i-1][j-1]+arr[i-1][j]; // 重点}}for(int i=0;i<row;i++){for(int j=0;j<=i;j++){printf("%3d ",arr[i][j]);}printf("\n");}
}

运行结果:

  1 1   1 1   2   1 1   3   3   1 1   4   6   4   1 1   5  10  10   5   1 1   6  15  20  15   6   1 1   7  21  35  35  21   7   1 1   8  28  56  70  56  28   8   1 1   9  36  84 126 126  84  36   9   1

【2020-10-28】

*66、实现 swap() 函数

通过函数调用进行数据交换时,交换形参并不能实现实参的交换,幼通过交换地址来实现实参交换

/*
题目:输入3个数a,b,c,按大小顺序输出。
*/
#include <stdio.h>void swap(int m,int n){int temp;temp=n;n=m;m=temp;printf("change:m=%d,n=%d\n",m,n);
}int main(){int a=10,b=11;if(a<b){swap(a,b);}printf("a=%d,b=%d",a,b);
}
change:m=11,n=10
a=10,b=11

通过地址:交换成功

#include <stdio.h>void swap(int *m,int *n){int temp;temp=*n;*n=*m;*m=temp;printf("change:m=%d,n=%d\n",*m,*n);
}int main(){int a=10,b=11;int *p1,*p2;p1=&a;p2=&b;if(a<b){swap(p1,p2);}printf("a=%d,b=%d",a,b);
}
change:m=11,n=10
a=11,b=10

*?*67、题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。

/*
题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
*/
#include <stdio.h>
#define LENGTH 5void printArr(int arr[]){for(int j=0;arr[j];j++){printf("%d ",arr[j]);}printf("\n");
}int main(){int arr[LENGTH]={1,3,5,7,9};printArr(arr);int min=arr[0],max=arr[0];int minFlag=0,maxFlag=0,temp,temp2;for(int i=0;arr[i];i++){if(min>arr[i]){min=arr[i];minFlag=i;}if(max<arr[i]){max=arr[i];maxFlag=i;}}printf("maxFlag=%d,minFlag=%d\n",maxFlag,minFlag);if(minFlag==0&&maxFlag==LENGTH-1){temp=arr[0];arr[0]=arr[LENGTH-1];arr[LENGTH-1]=temp;}else{ // 1、2不能交换顺序// 1temp2=arr[LENGTH-1];arr[LENGTH-1]=arr[minFlag];arr[minFlag]=temp2;// 2temp=arr[0];arr[0]=arr[maxFlag];arr[maxFlag]=temp;arr[LENGTH]='\0'; // 需要设置结束符,否则会越界?// 又没问题了}printArr(arr);
}
1 3 5 7 9
maxFlag=4,minFlag=0
9 3 5 7 1

疑问:数组打印越界问题

解答:
只适用于字符串数组,不能是字符数组,也不能是其他数组。
编译器不检查数组下标的合法性。

使用 array[i] 做控制条件,出现问题

#include <stdio.h>
int main(){int array[]={1,2,3};for(int i=0;array[i];i++){printf("下标:%d",i);printf("数据:%d\n",array[i]);}
}
下标:0数据:1
下标:1数据:2
下标:2数据:3
下标:3数据:1703792
下标:4数据:4199129
下标:5数据:1
下标:6数据:34411544
下标:7数据:34411680
下标:8数据:4198896
下标:9数据:4198896
下标:10数据:2297856

【2020-11-4】

**68、题目:有 n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的 m 个数。

下标方式:元素备份

时间复杂度:o(n)
空间复杂度:o(n)

/*
题目:有 n 个整数,使其前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m 个数。
*/
/*
类似于循环移位
*/
#include <stdio.h>
#define LENGTH 7
#define MOVE 4// 1.时间复杂度o(n),空间复杂度o(n)——建立备份
void moveArr(int arr[],int length,int move){int temp[MOVE],index=0;// 1.备份for(int i=length-move;i<length;i++){temp[index++]=arr[i];}printf("temp数组:");for(int q=0;q<MOVE;q++){printf("%d ",temp[q]);}// 2.移动for(int j=length-move;j>=0;j--){arr[j+move]=arr[j];}// 3.备份填充for(int k=0;k<move;k++){arr[move-k-1]=temp[k];}// 结果printf("\n结果:");for(int p=0;p<length;p++){printf("%d ",arr[p]);}
}int main(){int arr[LENGTH]={1,2,3,4,5,6,7};moveArr(arr,LENGTH,MOVE);
}
temp数组:4 5 6 7
结果:7 6 5 4 1 2 3
指针方式:元素滚动

时间复杂度:o(n2)
空间复杂度:o(n)

思路:
1.每轮滚动移出一个元素(存放在尾地址的下一个地址中)
2.每轮滚动结束,将移出的元素放到首地址中
多次滚动即可实现实现分析:
整个过程数组 array 的首地址是不变的
通过*array=last;改变首地址存放的的元素数据
#include <stdio.h>
#include <stdlib.h>// 滚动数组
void move(int array[],int n,int offset){int *p,*arr_end,last;arr_end=array+n; // 数组最后一个元素的下一个位置,用于地址滚动(临时空间,o(1))while(offset){ // 滚动直到偏移量为0last=*(arr_end-1); // 绝对位置/地址保持不变for(p=arr_end;p!=array;p--){*p=*(p-1); // 逐个向右滚动一位→一轮之后,数组元素整体向右移动一个位置,数组首地址保持不变// printf("%d  ",*p);}*array=last; // 移出的元素存放到首地址中offset--;printf("\nlast=%d,*array=%d\n",last,*array);}/*分析:整个过程array指向的首地址是不变的*array=last;改变了首地址的元素数据,而不是改变array的指向地址思路:1.每轮滚动移出一个元素(存放在arr_end指向的地址中)2.每轮滚动结束,将移出的元素重新放到首地址中*/
}
int main(){int arr[7]={1,2,3,4,5,6,7};int n=7,offset=3; // offset:移动次数move(arr,n,offset);for(int i=0;i<n;++i) printf("%4d",arr[i]);printf("\n");
}
7  6  5  4  3  2  1   // 倒序
*array=7
6  5  4  3  2  1  7
*array=6
5  4  3  2  1  7  6   // 倒序。正序为:6 7 1 2 3 4 5
*array=55   6   7   1   2   3   4

69、题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

/*
题目:有n个人围成一圈,顺序排号。
从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
*/
#include <stdio.h>
#define ACCOUNT 10int main(){// 初始编号int sign[ACCOUNT],count;for(int i=1;i<=ACCOUNT;i++){sign[i-1]=i;}for(int j=1;j<=ACCOUNT;j++){if(j%3==0){sign[j-1]=0; // 0:退出圈子printf("%d 退出圈子\n",j);}}printf("留下的人:\n");for(int k=0;k<ACCOUNT;k++){if(sign[k]){printf("原 %d 号\n",sign[k]);}}
}
3 退出圈子
6 退出圈子
9 退出圈子
留下的人:
原 1 号
原 2 号
原 4 号
原 5 号
原 7 号
原 8 号
原 10 号

**69、题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,直到剩余一个人,问最后留下的是原来第几号的那位。

不循环,每次从头开始

/*
题目:有n个人围成一圈,顺序排号。
从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
*/
#include <stdio.h>
#define ACCOUNT 10int main(){// 初始编号int sign[ACCOUNT];for(int i=1;i<=ACCOUNT;i++){sign[i-1]=i;}// 循环报数int remainNum,roundTime=1;do{remainNum=0;printf("第 %d 轮\n",roundTime);int count=1; // 报数// 退出printf("退出:");for(int j=0;j<ACCOUNT;j++){if(sign[j]){if(count%3==0){sign[j]=0;printf("%d ",j+1);}count++;}}// 剩余printf("\n剩余:");for(int k=0;k<ACCOUNT;k++){if(sign[k]){remainNum++;printf("%d ",sign[k]);}}printf("\n");roundTime++;printf("剩余人数:%d\n",remainNum);}while(remainNum>2);
}
第 1 轮
退出:3 6 9
剩余:1 2 4 5 7 8 10
剩余人数:7第 2 轮
退出:4 8
剩余:1 2 5 7 10
剩余人数:5第 3 轮
退出:5
剩余:1 2 7 10
剩余人数:4第 4 轮
退出:7
剩余:1 2 10
剩余人数:3第 5 轮
退出:10
剩余:1 2
剩余人数:2
循环,按圆继续报数
#include <stdio.h>
#define ACCOUNT 10int main(){// 初始编号int sign[ACCOUNT];for(int i=1;i<=ACCOUNT;i++){sign[i-1]=i;}// 循环报数int remainNum,roundTime=1,lastOut=0;int count=1; // 报数  // 重要do{remainNum=0;printf("第 %d 轮\n",roundTime);printf("lastOut=%d\n",lastOut);// 退出printf("退出:");for(int j=lastOut;j<ACCOUNT;j++){if(sign[j]){if(count%3==0){sign[j]=0;printf("%d ",j+1);}count++;lastOut=(j==(ACCOUNT-1))?0:(j+1); // 重要【语句位置】}}// 剩余printf("\n剩余:");for(int k=0;k<ACCOUNT;k++){if(sign[k]){remainNum++;printf("%d ",sign[k]);}}printf("\n");roundTime++;printf("剩余人数:%d\n\n",remainNum);}while(remainNum>1);
}
第 1 轮
退出:3 6 9
剩余:1 2 4 5 7 8 10
剩余人数:7第 2 轮
退出:2 7
剩余:1 4 5 8 10
剩余人数:5第 3 轮
退出:1 8
剩余:4 5 10
剩余人数:3第 4 轮
退出:5
剩余:4 10
剩余人数:2第 5 轮
退出:10
剩余:4
剩余人数:1

【2020-11-6】

70、题目:统计字符串长度【数组指针做函数返回值】

/*
题目:写一个函数,求一个字符串的长度,在 main 函数中输入字符串,并输出其长度。
*/
#include <stdio.h>
#include <string.h>// 1.输入字符串
char * inputStr(){char str[256]; // 声明字符串数组printf("输入字符串:");gets(str);return str;
}// 2.统计长度
int getLength(char string[]){int length=0;for(int i=0;string[i];i++){ // 循环条件:string[i]和string[i]!='\0'一样length++;}return length;
}int main(){char *inputString; int lengthString;inputString=inputStr(); // 输入lengthString=getLength(inputString); // 统计printf("字符串长度:%d\n",lengthString);
}
输入字符串:made in china
字符串长度:13

71、题目:结构体。编写input()和output()函数输入,输出5个学生的数据记录。

/*
题目:编写input()和output()函数输入,输出5个学生的数据记录。
*/
#include <stdio.h>
#include <string.h>
#define NUMBER 5
// 学生信息
struct STUDENT{char name[20];char sex[2];// char sex;int age;
}students[NUMBER];// 输入
void inputStu(){for(int i=0;i<NUMBER;i++){printf("第 %d 个学生信息\n",i+1);printf("姓名:");scanf("%s",students[i].name);printf("性别:");scanf("%s",students[i].sex);printf("年龄:");scanf("%d",&students[i].age);}
}// 输出
void ouputStu(){for(int i=0;i<NUMBER;i++){printf("第 %d 个学生信息\n",i+1);printf("姓名:%s\n",students[i].name);printf("性别:%s\n",students[i].sex);printf("年龄:%d\n",students[i].age);}
}// 指定输出
void pointOutput(int age){for(int i=0;i<NUMBER;i++){if(students[i].age==age){printf("输出信息:%d %s\n",students[i].age,students[i].name);}}
}int main(){printf("\n********** 信息输入 **********\n");inputStu();printf("\n********** 信息输出 **********\n");ouputStu();
}
********** 信息输入 **********
第 1 个学生信息
姓名:first
性别:女
年龄:20
第 2 个学生信息
姓名:second
性别:女
年龄:21
第 3 个学生信息
姓名:third
性别:女
年龄:22
第 4 个学生信息
姓名:four
性别:男
年龄:20
第 5 个学生信息
姓名:five
性别:男
年龄:21********** 信息输出 **********
第 1 个学生信息
姓名:first
性别:女
年龄:20
第 2 个学生信息
姓名:second
性别:女
年龄:21
第 3 个学生信息
姓名:third
性别:女
年龄:22
第 4 个学生信息
姓名:four
性别:男
年龄:20
第 5 个学生信息
姓名:five
性别:男
年龄:21
关于性别的数据类型选取

1、使用char sex[2];字符串:可以输入 男、女;不需要清输入缓冲区的缓存

// 学生信息
struct STUDENT{char name[20];char sex[2];int age;
}students[NUMBER];// 输入
printf("第 %d 个学生信息\n",i+1);
printf("姓名:");scanf("%s",students[i].name);
printf("性别:");scanf("%c",&students[i].sex);

2、使用char sex;字符:只能输入一个字符 m、f;需要清输入缓冲区的缓存

// 学生信息
struct STUDENT{char name[20];char sex;int age;
}students[NUMBER];// 输入
printf("第 %d 个学生信息\n",i+1);
printf("姓名:");scanf("%s",students[i].name);
fflush(stdin); // 清缓存
printf("性别:");scanf("%c",&students[i].sex);

***72、题目:链表——创建链表

题目:创建一个链表。

/*
题目:创建链表
*/
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
// 结构体
typedef struct LNode{ // 包含:data数据、next指针int data;struct LNode *next; // 结构体嵌套
}LNode,*LinkList;// 创建
LinkList CreateList(int n){LinkList L,p,q;L=(LNode*)malloc(sizeof(LNode)); // malloc:分配所需的内存空间。该函数返回一个指针,指向已分配大小的内存。如果请求失败,则返回 NULL。if(!L) return 0; // 内存分配失败L->next=NULL; // 初始化头指针:头指针指向分配的内存地址,next指针指向nullq=L; // 初始化尾指针:头指针指向的地址--表头地址// 重点for(int i=1;i<=n;i++){printf("请输入第%d个元素的值:",i);// 重点p=(LinkList)malloc(sizeof(LNode)); // 新增结点scanf("%d",&(p->data)); // p->data=%d; // 新增结点赋值p->next=NULL;q->next=p; // 将新增结点连接到链表中q=p; // 移动尾指针}return L; // 创建成功,返回链表表头指针
}
/*
由以下可知,表头指针并没有存放数据,而是仅仅指向第一个数据L->next=NULL;q=L;q->next=p;
*/// 输出
void print(LinkList h){LinkList p=h->next; // 从表头指针的next开始输出while(p!=NULL){printf("%d ",p->data);p=p->next;}
}int main(){LinkList Head=NULL;int n; // 长度printf("输入链表长度:");scanf("%d",&n);printf("\n创建链表\n");Head=CreateList(n);printf("\n打印链表:");print(Head);}
输入链表长度:3创建链表
请输入第1个元素的值:1
请输入第2个元素的值:2
请输入第3个元素的值:3打印链表:1 2 3

【2020-11-8】

***73、题目:链表——反向输出一个链表

三种方法:
1、不改变链表:递归
2、改变链表:使用双表头,反转链表
3、改变链表:使用双指针,双向链表(左右指针)

// 反向打印链表
void outputLinklist(LinkList headNext){LinkList h=headNext;// 重要if(h){if(h->next){outputLinklist(h->next);}printf("%d ",h->data);}
}int main(){/*……*/printf("\n反向输出\n");outputLinklist(Head->next);
}
// 创建链表
链表长度:3
结点值:1
结点值:2
结点值:3反向输出
3 2 1

***74、题目:链表——连接两个链表

主要代码

while(h11){if(!(h11->next)){h11->next=h22;}else{h11=h11->next;}
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>typedef struct node{int data;struct node *next; // 结构体类型的指针
}node,*LinkList;// 创建链表
LinkList createLinklist(int length){LinkList head,trail,temp;// 1.初始化链表head=(node *)malloc(sizeof(node)); // 初始化首指针,申请空间——大小为一个结构体的大小// 因为head是linklist类型,所以强制转换为结构体node类型的指针类型if(!head){printf("链表初始化失败");return 0;}else{head->next=NULL;trail=head; // 初始化尾指针}// 2.新增结点for(int i=1;i<=length;i++){temp=(node*)malloc(sizeof(node));printf("结点值:");scanf("%d",&(temp->data)); // 新结点数值temp->next=NULL; // 新结点next指针值trail->next=temp;trail=temp;}// 3.返回值return head; // 返回链表首地址/首指针
}// 连接链表
void mergeLinklist(LinkList h1,LinkList h2){LinkList h11=h1->next,h22=h2->next;while(h11){if(!(h11->next)){h11->next=h22;}else{h11=h11->next;}}// 输出合并后的链表void printLinklist(LinkList head);printLinklist(h1);
}// 输出链表
void printLinklist(LinkList head){LinkList p=head->next;while(p!=NULL){printf("%d ",p->data);p=p->next;}
}int main(){int number;// 创建链表LinkList h1,h2;printf("第一个链表长度:");scanf("%d",&number);h1=createLinklist(number);printf("第二个链表长度:");scanf("%d",&number);h2=createLinklist(number);// 连接链表printf("合并链表:");if(h1||h2){mergeLinklist(h1,h2);}
}
第一个链表长度:3
结点值:1
结点值:2
结点值:3
第二个链表长度:2
结点值:4
结点值:5合并链表:1 2 3 4 5

*75、题目:整数反转后输出

1、倒序输出(不改变值)

#include<stdio.h>void invertOutput(int number){while((number/10)||(number%10)){printf("%d",number%10);number=number/10;}
}int main(){int num;printf("输入:");scanf("%d",&num);// 反转invertOutput(num);
}
输入:12345
54321

2、反转值(改变值)

int invert(int number){int result=0,temp;// 重要while((number/10)||(number%10)){temp=number%10; // 每次获取末尾数值result=result*10+temp*10; // 反转数据number=number/10; // 循环控制条件}result=result/10;// printf("\nresult=%d",result);return result;
}
输入:12345
result=54321

【2020-11-11】

76、题目:指针函数

题目:利用指针函数实现
当输入n为偶数时,调用函数求和1/2+1/4+…+1/n
当输入n为奇数时,调用函数求和1/1+1/3+…+1/n

指针函数:带指针的函数
函数指针:指向函数的指针变量

1、非指针函数

#include<stdio.h>float getSum(int number){float sum=0;int flag=(number%2)?1:2; // 1-奇数,2-偶数for(int i=1;i<=number;i++){if(flag==1&&(2*i-1)<=number){sum=sum+1.0/(2*i-1); // 1.0 重要,浮点数}else if(flag==2&&2*i<=number){sum=sum+1.0/(2*i); // 1.0 重要,浮点数}else{break;}}return sum;
}int main(){int num=11;printf("\n结果:%f\n",getSum(num));
}
结果:1.878211

2、指针函数:返回值为指针的函数。定义函数指针变量,通过指针变量调用函数:float (*pfunc)(int);

int main(){int num=11;float result;float (*pfunc)(int); // 指针函数。函数参数为int numpfunc=getSum; // 函数指针。函数地址赋给指针变量result=(*pfunc)(num); // 通过指针调用函数printf("\n结果:%f\n",result);
}

77、题目:指向指针的指针

#include<stdio.h>
#include<stdlib.h>
int main(){const char *s[]={"man","woman","girl","boy","sister"}; // * 不可去掉const char **q;for(int k=0;k<5;k++){q=&s[k]; // 取地址--重点printf("%s ",*q);// printf("%s ",s[k]);// printf("%s ",*s);// printf("%0x ",s);}
}
/*
*s=man
s=首地址
s[k]=各元素
&s[k]=各元素地址
*/
man woman girl boy sister

78、题目:字符串排序

/*
题目:字符串排序
*/
#include <stdio.h>
#include <string.h>int main(){char str1[]="ccc",str2[]="bbb",str3[]="aaa";// 排序char temp[256];if(strcmp(str1,str2)>0){strcpy(temp,str2);strcpy(str2,str1);strcpy(str1,temp);}if(strcmp(str1,str3)>0){strcpy(temp,str3);strcpy(str3,str1);strcpy(str1,temp);}if(strcmp(str2,str3)>0){strcpy(temp,str3);strcpy(str3,str2);strcpy(str2,temp);}// 输出printf("排序后:%s,%s,%s\n",str1,str2,str3);
}
排序后:aaa,bbb,ccc
错误方式

报错:cannot convert from 'char *' to 'char[256]'

char *p; // error:cannot convert from 'char *' to 'char [256]'
if(strcmp(str1,str2)>0){p=str2;str2=str1;str1=p;
}

?80、猴子分桃

题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只 猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?

【疑问】:最后桃子的状态是什么?

/* 题目:猴子分桃 */
// 假设最后一个猴子分完剩四个桃子
#include <stdio.h>

int divicePeach(int monkeyNum){
int peachSum=0;
if(monkeyNum==1){
peachSum=monkeyNum*5+1;
}else{
peachSum=peachSum+divicePeach(monkeyNum-1)*5+1;
}
return peachSum; }

int main(){
int monkeyNum=5;
printf(“结果:%d\n”,divicePeach(monkeyNum));
}
// 结果:3906

2020-11-14

81、题目:809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果

#include <stdio.h>int main(){int t1,t2;for(int i=10;i<100;i++){if((809*i<10000&&809*i>=1000)&&(8*i<100&&8*i>=10)&&(9*i<1000&&9*i>=100)){t1=809*i;t2=800*i+9*i;if(t1==t2){printf("两位数:%d,  809*%d=%d\n",i,i,t1);}}}
}
两位数:12,  809*12=9708

*82、题目:进制转换

1、字符串方法

/*
题目:八进制转十进制算法
*/
#include <stdio.h>// 进制转换
int revert(char arr[]){int i=0,temp,result=0;while(arr[i]!='\0'){result=result*8+arr[i]-'0'; // 需要减去'0',因为arr中是字符0-9i++;}return result;
}int main(){char t1[]="100";printf("%d\n",revert(t1));
}

2、十进制方法

83、题目:排列组合

题目:求0—7所能组成的奇数个数。

/*
题目:求0—7所能组成的奇数个数。(只求个数,不求组合)
*/
/*
分析:最高位不为0(有七种),最低位有四种
一位数:4
两位数:7*4
三位数:7*8*4
四位数:7*8^2*4
五位数:7*8^3*4
六位数:7*8^4*4
七位数:7*8^5*4
八位数:7*8^6*4
*/
#include <stdio.h>int combination(int n){int typeNum=0,temp=1;if(n==1){typeNum=4;}else if(n==2){typeNum=7*4;}else{for(int i=1;i<=n-2;i++){temp=temp*8;}typeNum=7*4*temp;}return typeNum;
}int main(){printf("5位数组合个数:%d\n",combination(5));
}
5位数组合个数:14336

84、题目:一个偶数总能表示为两个素数之和

/*
题目:一个偶数总能表示为两个素数之和。
*/
#include <stdio.h>int isPrime(int n){int flag=1; // 是素数int mid=(n%2)?(n/2+1):(n/2);for(int i=2;i<mid;i++){if(n%i==0){flag=0; // 不是素数break;}}return flag;
}void judgement(int evenNum){int mid=evenNum/2,isPrimeRes1,isPrimeRes2;// int flag=0; // 让程序更具有逻辑性,没有实际作用for(int i=1;i<=mid;i++){isPrimeRes1=isPrime(i);isPrimeRes2=isPrime(evenNum-i);if(isPrimeRes1&&isPrimeRes2){ // i是素数,evenNum-i是素数printf("%d=%d+%d\n",evenNum,i,evenNum-i);// flag=1;break;}}// if(!flag){//     printf("%d不能表示成两个素数之和\n");// }
}int main(){judgement(10);
}
10=3+7

85、题目:判断一个素数能被几个9组成的数整除。

/*
题目:判断一个素数能被几个9组成的数整除。
*/
#include <stdio.h>int isPrime(int n){int flag=1; // 是素数int mid=(n%2)?(n/2+1):(n/2);for(int i=2;i<mid;i++){if(n%i==0){flag=0; // 不是素数break;}}return flag;
}void judgement(int num){int result=9,count=1;if(isPrime(num)){while(result<999999){if(result%num==0){break;}result=result*10+result;count++;}}// return count;printf("%d能被%d个9组成的数整除\n",num,count);
}int main(){judgement(13);
}
13能被6个9组成的数整除

86、字符串连接

/*
分析:字符串连接有以下两种情况
1.连接后改变原字符串,合并成一个字符串,覆盖str1。要求:str1足够大可以容下两个字符串
2.连接后不改变原字符串,合并成一个新字符串
*/
#include <stdio.h>// 方法1.str2追加到str1中
char* mergeToStr(char str1[],char str2[]){char *p1,*p2,*p;p=str1;p1=str1;p2=str2;while(*p1){p1++;}while(*p2){*p1=*p2;p2++;p1++;}return p;
}// 方法2.新字符串
char newStr[256]; // 需为全局变量,不能是局部变量
char* merge(char str1[],char str2[]){char *p1,*p2;int length=0;p1=str1;p2=str2;while(*p1){newStr[length++]=*p1;p1++;}while(*p2){newStr[length++]=*p2;p2++;}newStr[length]='\0';return newStr;
}int main(){char string1[20]="nation",string2[]="lover";char *result;// 方法1result=mergeToStr(string1,string2);printf("结果:%s\n",result);// 方法2result=merge(string1,string2);printf("结果:%s\n",result);
}
结果:nationlover

87、* 对结构体变量的修改只在本函数内有效

/*
题目:结构体变量传递。
*/
#include<stdio.h>struct student{int x;char c;
}a;void f(struct student b){b.x=20;b.c='y';printf("x=%d, c=%c\n",b.x,b.c); // 修改只在本函数内起作用
}int xx=a.x; // xx=0(是系统初始化值)→进一步说明,对函数体成员的修改只在函数内起作用int main(){a.x=3;a.c='a';f(a); // 不起作用printf("%d, %c\n",a.x,a.c); // 只保留本函数内的修改printf("xx=%d",xx);
}
x=20, c=y
3, a
xx=0

ing-89、题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用除以10的余数代替该数字;再将第一位和第四位交换,第二位和第三位交换。


91、时间函数

1、

#include <stdio.h>
#include <time.h>int main (){time_t rawtime;struct tm * timeinfo;time ( &rawtime );timeinfo = localtime ( &rawtime );printf ( "当前本地时间为: %s", asctime (timeinfo) );
}
当前本地时间为: Sat Nov 14 13:43:26 2020 // 有8小时时差

2、time()

#include <stdio.h>
#include <time.h>int main(){time_t start,end;start=time(NULL);for(int i=0;i<3000;i++){ // 起间隔作用printf("间隔中……\n");}end=time(NULL);printf("时间间隔为 %6.3f\n",difftime(end,start));// 输出执行时间
}
时间间隔为 2.000

3、clock()

#include <stdio.h>
#include <time.h>int main(){long i=10000000L;clock_t start,finish;double TheTimes;printf("做%ld次空循环需要的时间为",i);start=clock();while(i--);finish=clock();TheTimes=(double)(finish-start)/CLOCKS_PER_SEC;printf("%f秒。\n",TheTimes);
}
做10000000次空循环需要的时间为0.025000秒。

96、KMP算法

题目:计算字符串中子串出现的次数


97、文件操作

题目:从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个#为止


98、文件操作

题目:从键盘输入一个字符串,将小写字母全部转换成大写字母,然后输出到一个磁盘文件"test"中保存。 输入的字符串以!结束。


99、文件操作

题目:有两个磁盘文件A和B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中。

程序分析:你需要先创建 A.txt 与 B.txt。


100、文件操作+结构体:学生信息和成绩计算

题目:有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,况原有的数据和计算出的平均分数存放在磁盘文件"stud"中。


C语言--经典100题相关推荐

  1. c语言 swap交换函数_C语言经典100题(14)

    1 上期答案揭晓 首先给大家看看上一篇文章C语言经典100题(13)中第三部分编程题的答案: #includeint main(){ int i,x,y,z; for(i=100;i<1000; ...

  2. c语言三个数从小到大排序/输出_C语言经典100题(6)

    1 上期答案揭晓 首先给大家看看上一篇文章C语言经典100题(5)中第三部分编程题的答案: #include int main(){ int x,y,z,t; printf("\n请输入三个 ...

  3. 完数c++语言程序_C语言经典100题(19)

    1 上期答案揭晓 首先给大家看看上一篇文章C语言经典100题(18)中第三部分编程题的答案: #includeint main(){ int s=0,a,n,t; printf("请输入 a ...

  4. c++ 经典代码_C语言经典100题(31)

    1 上期答案揭晓 首先给大家看看上一篇文章C语言经典100题(30)中第三部分编程题的答案: #include int main( ){ long ge,shi,qian,wan,x; printf( ...

  5. C语言经典100题——用选择法排序

    <什么是选择法> 选择排序法是一种不稳定的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大) ...

  6. C语言经典100题——用筛选法求100之内的素数

    <1>什么是筛选法 所谓筛选法是指"埃拉托色尼筛法",埃拉托色尼是古希腊的著名数学家.它采用的方法是,在一张纸上写上1~1000的全部整数,然后逐个判断他们是否为素数, ...

  7. 【C语言经典100题】求a+aa+aaa+....的值

    文章目录 题目 一.分析 二.代码 总结 题目

  8. C语言经典100题——求一个二维数组的鞍点

    <1>题目描述 找一个二维数组中的鞍点,即该位置上的元素在该行上最大.在该列上最小.也可能没有鞍点 1 2 3 4 5 6 7 8 9 //3为该二维数组中鞍点 <2>思路分析 ...

  9. 【C语言经典100题】(古典问题)兔子问题

    文章目录 题目 一.分析 二.代码 总结 题目

最新文章

  1. 【LeetCode从零单排】No20.ValidParentheses
  2. .net访问PostgreSQL数据库发生“找不到函数名”的问题追踪
  3. 【笛卡尔树】【树状数组】Beautiful Pair(P4755)
  4. rocketmq 消息指定_SpringBoot 整合 RocketMQ 如何实现消息生产消费?
  5. 实现自适应位置--footer紧贴浏览器底部
  6. COJ 1079 树上的查询 (离线LCA)
  7. agc016B - Colorful Hats(智商题)
  8. VB ListView控件各种操作详解
  9. 常用网络特殊符号大全(含彩色表情符号)
  10. 安卓加密软件_教你用手机NFC模拟加密门禁卡
  11. 装系统:主分区、扩展分区、逻辑分区,引导(启动)分区、系统分区、活动分区
  12. 【前端兼容性】常见的浏览器兼容问题及解决方案
  13. Git 笔记 - 程序员都要掌握的 Git
  14. img元素实现图片裁切放大
  15. ASP.NET MVC Liu_Cabbage 个人博客
  16. Debian查看系统版本信息
  17. 分销商城是怎么运营?
  18. 三维动画渲染用什么软件好?
  19. 中国农科院基因组所汪鸿儒课题组诚邀加入
  20. 微信小程序开始时间,结束时间

热门文章

  1. 简易的java程序,银行管理系统
  2. 证券基金行业那些智能XX——智能客服
  3. 联想yoga14s和小新pro14哪个好
  4. 解读照明设备欧洲能效认证新版Erp法规要求
  5. 仿网易新闻评论“盖楼”效果实现
  6. Terraria及tModloader开服教程
  7. Android手机数据恢复——终结篇
  8. i.MX6ULL嵌入式Linux开发4-根文件系统构建
  9. 在 Kubernetes 实施混沌工程—— Chaos Mesh® 原理分析与控制面开发
  10. FLUKE LinkIQ-100 CH/福禄克LIQ-100 CH可以出测试报告