2.1 整数的四则运算
本题要求编写程序,计算两个正整数的和差积商并输出,题目保证输入和输出全部在整形范围内
输入格式
输入在一行中给出两个正整数A和B
输出格式
在4行中按照格式“A运算符B=结果”顺序输出和、差、积、商。
输入样例:
3 2
输出样例:
3+2=5
3-2=1
3*2=6
3/2=1
#include<stdio.h> int main() { int a,b; scanf("%d %d",&a,&b); printf("%d+%d=%d\n",a,b,a+b); printf("%d-%d=%d\n",a,b,a-b); printf("%d*%d=%d\n",a,b,a*b); printf("%d/%d=%d\n",a,b,a/b); return 0; }
2.2.2 表达式:运算符优先级
结合关系:单目和赋值自右向左,其他自左向右
一、关系运算符
- 优先级低于算数运算符
printf("%d\n",7>=3+4);
- 优先级高于赋值运算符
int r=a>0;
二、关系运算符中==和!=低于其他的
printf("%d\n",5>3==6>4);
三、连续的关系运算从左到右进行
printf("%d\n",6>5>4);
3.1.5 if语句
一、定义
一个基本的if语句由一个关键字if开头,跟上一个在括号里的表示条件的逻辑表达式,然后是一对大括号“{}”之间的若干条语句
如果表示条件的逻辑表达式的结果不是零,那么就执行后面跟着的这对大括号中的语句,否则就跳过这些语句不执行,而继续下面的其他语句
- 大括号里只有一句时,可以省略大括号
- 无大括号时,else总是和最近的if匹配
- 在if或者else后始终加“{}”
二、级联的if-else if
级联:流程图中一级一级连着,判断成功就从右边画一道线从出口出去
三、if语句常见错误
- 忘了大括号
- if后面的分号
if() ;
- 错误使用==和=
- 使人困惑的else
3.2.3 应该做到的
- if 和else之后必须加上大括号形成语句块
- 大括号内的语句缩进一个tab的位置
3.1 成绩转换
本题要求编写程序将一个百分制成绩转换为五分制成绩,转换规则:
- 大于等于90分为A;
- 小于90且大于80为B;
- 小于80且大于70为C;
- 小于70且大于60为D;
- 小于60为E。
输入格式:
输入在一行中给出一个整数的百分之成绩。
输出格式:
在一行中输出对应的五分制成绩。
输入样例:
90
输出样例:
A
#include<stdio.h> int main() { int grade; printf("input ur grade:"); scanf("%d",&grade); grade/=10; switch (grade){ case(10): case (9): printf("A\n"); break; case(8): printf("B\n"); break; case(7): printf("C\n"); break; case(6): printf("D\n"); break; default: printf("E\n"); } return 0; }
#include<stdio.h> int main() { int grade; int output;//char也可 printf("input ur grade:"); scanf("%d",&grade); if(grade>=90){ output='A'; } else if(grade>=80){//因为从高往下判断,不需要再添加上限,即无需写成80<=score<90 output='B'; } else if(grade>=70){ output='C'; } else if(grade>=60){ output='D'; } else{ output='F'; } printf("ur 5 point grade is:\n%c\n",output); return 0; }
#include<stdio.h> int main() { int score; int output;//char也可 printf("input ur grade:"); scanf("%d",&score); if(score>=90){ printf("A\n"); }else if(score>=80){//因为从高往下判断,不需要再添加上限,即无需写成80<=score<90 printf("B\n"); }else if(score>=70){ printf("C\n"); }else if(score>=60){ printf("D\n"); }else{ printf("E\n"); } return 0; }
4.1.1 循环
1、输入一个正整数,屏幕显示该正整数的位数
1 #include<stdio.h> 2 int main() 3 { 4 int x; 5 int n=0; 6 printf("请输入数字:"); 7 scanf("%d",&x); 8 while(x>0){ 9 n++; 10 x/=10; 11 } 12 printf("您输入的位数是%d\n",n); 13 return 0; 14 }
验证
- 测试程序常使用边界数据,如有效范围两端的数据、特殊的倍数等
- 个位数
- 10
- 0
- 负数
在程序适当的地方插入pirntf来输出变量的内容
如在循环体中加入
printf("x=%d,n=%d\n",x,n);
printf("hr1\n");//here
5 三种循环
Tips for loops
- 如果有固定次数用for
- 如果必须执行一次用do-while
- 其他情况用while
break vs continue
break:跳出循环
continue:跳出循环这一轮剩下的语句进入下一轮
#include<stdio.h> int main() { int x; scanf("%d",&x); //x=15; int i; int isPrime=1; for(i=2;i<x;i++){ if(x%i==0){ isPrime=0; break; } } if(isPrime==1){ printf("true\n"); }else { printf("false\n"); } return 0; }
#include<stdio.h> int main() { int x; int cnt=0; //for(x=2;cnt<50;x++){ x=2; while(cnt<50){ int i; int isPrime=1; for(i=2;i<x;i++){ if(x%i==0){ isPrime=0; break; } } if(isPrime==1){ cnt++; printf("%d\t",x); if(cnt%5==0){ printf("\n"); } } x++; } return 0; }
三重循环
1 #include<stdio.h> 2 int main() 3 { 4 int one,two,five; 5 int x; 6 scanf("%d",&x); 7 for(one=1;one<=x*10;one++){ 8 for(two=1;two<=x*10/2;two++){ 9 for(five=1;five<=x*10/5;five++){ 10 if(one*1+two*2+five*5==x*10){ 11 printf("%d\t%d\t%d\n",one,two,five); 12 } 13 } 14 } 15 } 16 }
break和continue
- 只对它所在的那层循环做
接力break//if(exit==1)
1 #include<stdio.h> 2 int main() 3 { 4 int one,two,five; 5 int x; 6 int exit=0; 7 scanf("%d",&x); 8 for(one=1;one<=x*10;one++){ 9 for(two=1;two<=x*10/2;two++){ 10 for(five=1;five<=x*10/5;five++){ 11 if(one*1+two*2+five*5==x*10){ 12 printf("%d\t%d\t%d\n",one,two,five); 13 exit=1; 14 break; 15 } 16 } 17 if(exit)break; 18 } 19 if(exit)break; 20 } 21 }
#include<stdio.h> int main() { int one,two,five; int x; scanf("%d",&x); for(one=1;one<=x*10;one++){ for(two=1;two<=x*10/2;two++){ for(five=1;five<=x*10/5;five++){ if(one*1+two*2+five*5==x*10){ printf("%d\t%d\t%d\n",one,two,five); goto out; } } } } out: return 0; }
5.3.1
1)
1 #include<stdio.h> 2 int main() 3 { 4 int n; 5 int i; 6 double sum=0.0; 7 scanf("%d",&n); 8 for(i=1;i<=n;i++){ 9 sum+=1.0/i; 10 } 11 printf("f(%d)=%f\n",n,sum); 12 }
2)
在循环的第一轮是1,第二轮是-1,即实现+···-···的效果
#include<stdio.h> int main() { int n; int i; double sum=0.0; int sign=1; scanf("%d",&n); for(i=1;i<=n;i++){ sum+=sign*1.0/i; sign=-sign; } printf("f(%d)=%f\n",n,sum); }
#include<stdio.h> int main() { int n; int i; double sum=0.0; double sign=1.0; //int sign=1; scanf("%d",&n); for(i=1;i<=n;i++){ sum+=sign/i; sign=-sign; } printf("f(%d)=%f\n",n,sum); }
正序分解正整数
步骤1
逆序输出
1 #include<stdio.h> 2 int main() 3 { 4 int x=12345; 5 do{ 6 int d=x%10; 7 printf("%d",d); 8 if(x>9){//1后无空格 9 printf(" "); 10 } 11 x/=10; 12 }while(x>0); 13 printf("\n"); 14 }
step2
逆序
1 #include<stdio.h> 2 int main() 3 { 4 int x=12345; 5 int t=0; 6 do{ 7 int d=x%10; 8 t=t*10+d; 9 x/=10; 10 }while(x>0); 11 printf("x=%d,t=%d\n",t); 12 x=t; 13 do{ 14 int d=x%10; 15 printf("%d",d); 16 if(x>9){ 17 printf(" "); 18 } 19 x/=10; 20 }while(x>0); 21 printf("\n"); 22 }
缺点:如700,经此逆序为7。
#include<stdio.h> int main() { int x=12345; int mask=1; int t=x; while(t>9){ t/=10; mask*=10; } printf("mask=%d\n",mask); //int mask=10000; do{int d=x/mask;//d=1 x%=mask; mask/=10;//mask=1000 //printf("%d\t%d\t%d\t\n",d,x,mask); printf("%d",d); if(mask){ printf(" ",d); } }while(mask); printf("\n"); } /*12345/10000=1; 2345=12345%10000 2345/1000=2; 345/100=3; 45/10=4; 5/1=5;*/
求最大公约数
1、穷举法
#include<stdio.h> int main() { int a=12,b=24,min; if(a<b){ min=a; }else{ min=b; } int ret=0; int i; for(i=1;i<=min;i++){ if(a%i==0){ if(b%i==0){ ret=i; } } } printf("%d",ret); }
2、辗转相除法
列变量表
1 #include<stdio.h> 2 int main() 3 { 4 int a,b; 5 int t; 6 //scanf("%d %d",&a,&b); 7 a=12;b=18; 8 while(b!=0){ 9 t=a%b; 10 a=b; 11 b=t; 12 //printf("%d %d %d\n",t,a,b); 13 } 14 printf("gcd=%d\n",a); 15 }
4.0 求符合给定条件的整数集
给定不超过6的正整数A,考虑从A开始的连续4个数字,请输出所有由它们组成的无重复数字的3位数。
输入格式:
输入在一行中给出A
输出格式:
输出满足条件的3位数,要求从小到大,每行6个整数。整数间以空格分隔,但行末不能有多余空格。
输入样例:
2//2345的组合
输出样例:
234 235 243 245 253 254
324 325 342 345 352 354
423 425 432 435 452 453
523 524 532 534 542 543
#include<stdio.h> int main() { int a=2; //scanf("%d",a); int i,j,k; int cnt=0;//计数器 i=a; while(i<=a+3){ j=a; while(j<=a+3){ k=a; while(k<=a+3){ if(i!=j){ if(i!=k){ if(j!=k){ cnt++; printf("%d%d%d ",i,j,k); if(cnt%6==0){ printf("\n"); }else{ printf(" "); } } } } k++; } j++; } i++; } return 0; }
#include<stdio.h> int main() { int a=2; //scanf("%d",a); int i,j,k; int cnt=0;//计数器 i=a; while(i<=a+3){ j=a; while(j<=a+3){ k=a; while(k<=a+3){ if(i!=j&&i!=k&&j!=k){ cnt++; printf("%d%d%d ",i,j,k); if(cnt%6==0){ printf("\n"); }else{ printf(" "); } } k++; } j++; } i++; } return 0; }
#include<stdio.h> int main() { int a=2; //scanf("%d",a); int i,j,k; int cnt=0;//计数器 i=a; for(i=a;i<=a+3;i++){ for(j=a;j<=a+3;j++){ for(k=a;k<=a+3;k++){ if(i!=j&&i!=k&&j!=k){ cnt++; printf("%d%d%d ",i,j,k); if(cnt%6==0){ printf("\n"); }else{ printf(" "); } } } } } return 0; }
4.1 水仙花数
水仙花数是指一个N位正整数(N>=3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33,本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3<=N<=7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
输出样例:
153
370
371
#include<stdio.h> int main() { int n; n=3; int first=1; int i=1; while(i<n){ first*=10; i++; } //printf("first=%d\n",first); //遍历100-999 i=first; while(i<first*10){ int t=i; int sum=0; do{ int d=t%10; t/=10; int p=1;//表达幂次的结果 int j=0;//计数变量 while(j<n){ p*=d; j++; } sum+=p; }while(t>0); if(sum==i){ printf("%d\n",i); } i++; } }
4.2 打印九九乘法表
#include<stdio.h> int main() { int n; n=9;; int i,j; i=1; while(i<=n){ j=1; while(j<=i){ printf("%d*%d=%d",j,i,i*j); if(i*j<10){ printf(" "); }else{ printf(" "); } j++; } printf("\n"); i++; } return 0; }
4-3 统计素数并求和
本题要求统计给定整数M和N区间内的素数的个数并对它们求和。
输入格式:
输入在一行中给出2个正整数M和N(1<=M<=N<=500)。
输出格式:
在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以空格分隔。
输入样例:
10 31
输出样例:
7 143
#include<stdio.h> int main() { int m,n; int i; int cnt=0; int sum=0; scanf("%d %d",&m,&n); if(m==1){ m=2;//剔除1 } for(i=m;i<=n;i++){ int isPrime=1; int k; for(k=2;k<i-1;k++){ if(i%k==0){ isPrime=0; break; } } //判断i是否是素数 if(isPrime){ cnt++; sum+=i; } } printf("%d %d",cnt,sum); return 0; }
5.0 求序列前N项和
本题要求编写程序,计算序列2/1+3/2+5/3+8/5+...的前N项之和。注意该序列从第2项起,每一项的分子是前一项分子与分母的和,分母是前一项的分子。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中输出部分和的值,精确到小数点后2位。题目保证计算结果不超过双精度范围。
输入样例:
20
输出样例:
32.66
#include<stdio.h> int main() { int n; double dividend,divisor; double sum=0.0; int i; double t; scanf("%d",&n); dividend=2; divisor=1; for(i=1;i<=n;i++){ sum+=dividend/divisor; t=dividend;//暂存前一项分子 dividend=dividend+divisor; divisor=t; } printf("%.2f\n",sum); return 0; }
5.1 约分最简分式
编写一个程序,要求用户输入一个分数,然后将其约分为最简分式。最简分式是指分子和分母不具有可以约分的成分了。如6/12可以被约分为1/2。当分子大于分母时,不需要表达为整数又分母的形式,即11/8还是11/8;而当分子分母相等时,仍然表达为1/1的分数形式。
输入格式:
输入在一行中给出一个分数,分子和分母中间以斜杠”/“分隔,如12/34表示34分之12。分子和分母都是正整数(不包含0,如果不清楚正整数定义的话)。
提示,在scanf的格式字符串中加入”/",让scanf来处理这个斜杠。
输出格式:
在一行中输出这个分数对应的最简分式,格式与输入的相同,即采用“分子/分母”的形式表示分数。如5/6表示6分之5。
输入样例:
60/120
输出样例:
1/2
算出最大公约数gcd,大家再除以gcd就算出来了。
#include<stdio.h> int main() { int dividend,divisor; scanf("%d/%d",÷nd,&divisor); int a=dividend; int b=divisor; int t; //a=12;b=18; while(b>0){ t=a%b; a=b; b=t; //printf("%d %d %d\n",t,a,b); } //printf("gcd=%d\n",a); printf("%d/%d\n",dividend/a,divisor/a); return 0; }
5.2 念数字
输入一个整数,输出每个数字对应的拼音,当整数为负数时,先输出“fu”字,十个数字对应的拼音如下:
0:ling
1:yi
2:er
3:san
4:si
5:wu
6:liu
7:qi
8:ba
9:9
输入格式:
输入在1行中给出一个整数,如:1234。
提示:整数包括负数,零和正数。
输出格式:
在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如yi er san si。
输入样例:
-600
输出样例:
fu liu ling ling
#include<stdio.h> int main() { int x; scanf("%d",&x); //加负号 if(x<0){ printf("fu "); x=-x; } //t存放x值;t最高位=t%mask int mask=1; int t=x; while(t>9){ t/=10; mask*=10; } //printf("%d\n",mask); do{ int d=x/mask;//最高位 switch(d){ case 0:printf("ling");break; case 1:printf("yi");break; case 2:printf("er");break; case 3:printf("san");break; case 4:printf("si");break; case 5:printf("wu");break; case 6:printf("liu");break; case 7:printf("qi");break; case 8:printf("ba");break; case 9:printf("jiu");break; } if(mask>0)printf(" "); x%=mask;//去掉最高位 mask/=10;//mask相应除以10 }while(mask>0); printf("\n"); return 0; }
5.3 求a的连续和
输入两个整数a和n,a的范围是[0,9],n的范围是[1,8],求数列之和S=a+aa+aaa+...+aaa...a(n个a)。如a为2、n为8时输出的是2+22+222+...+22222222的和。
输入格式:
输入在一行中给出两个整数,先后表示a和n。
输出格式:
在一行中输出要求的数列之和。
输入样例:
2 4
输出样例:
2468
#include<stdio.h> int main() { int a,n; scanf("%d %d",&a,&n); int sum=0; int i; int t; //2 2*10+2 (2*10+2)*10+2 for(i=0;i<n;i++){ t=t*10+a; sum+=t; } printf("%d\n",sum ); return 0; }
输出
%d | %ld | %f | |
整数 | 长整数 | 浮点数 |
字节数
sizeof
char:1
short:2
int:4
double:8
long:8
long double:16
数的范围:
6.1.4
对于1个字节(8位),可以表达的是:
00000000-11111111
其中
00000000->0
11111111~10000000->-1~-128
00000001~01111111->1-127
unsigned表示高位为1的数不把他看作补码,看成纯二进制,正数部分范围扩大
0开始的数字字面量是8进制
0x开始的数字字面量是16进制
8进制如何转换为10进制位权
%d输出十进制,%o输出8进制,%x输出16进制
整数建议选择int
%f输出,%e输出科学记数法
double可以表达15位,但如果不指定要输出多少位小数,可能输出0.000000
%.16f
带小数点如果后面没有f,就默认是double。
判断两个浮点数是否相等
fabs(f1-f2)<1e-8
所以做计算时,用整数做计算,小数点的误差会累积。
如1.23元,用123分表示
什么第二周的十进制数用BCD数表示进行计算6.1.8?
没有特殊需要,浮点数用double
可在printf和scanf中用%c来做单个字符的输入和输出
字符类型
1)
以%c的形式去读它
#include<stdio.h> int main() { char c; scanf("%c",&c); printf("c=%d\n",c); printf("c='%c'\n",c); }
2)
以%d的形式去读它
#include<stdio.h> int main() { int i; char c; c=i; scanf("%d",&i); printf("c=%d\n",c); printf("c='%c'\n",c); }
不带空格的scanf
int i; char c; scanf("%d %c",&i,&c); printf("i=%d,c=%d,c='%c'",i,c,c);
不带空格的
scanf("%d%c",&i,&c); printf("i=%d,c=%d,c='%c'",i,c,c);
即%d后如果有空格,还要把12后面的空格一起读掉。
char c='A'; c++; printf("%c\n",c);
- 一个字符加一个数字得到ASCII码表中那个数字之后的字符
- 两个字符的减,得到它们在表中的距离
大小写转换
- 字母在ASCII表中是顺序排列的
- 大写字母和小写字母是分开排列的,并不在一起
- 'a'-'A'可以得到两段之间的距离,于是
- a+'a'-'A'可以把一个大写字母变成小写字母,而
- a+'A'-'a'可以把一个小写字母变成大写字母
举例
1)
printf("%d\n",'Z'-'A');
2)
printf("%d\n",'a'-'A');
\b回退一格
printf("123\bA\n456");
\t到下一个表格位(类似Tab键,到键盘上固定位置)
printf("123\t456\n"); printf("12\t456\n");
回车换行源自打字机,回车将滚筒纸回到最右边(伴随打字,纸张向左),换行,往上卷
\n换行
\r回车
shell帮我们把\n翻译为要做回车和换行两个动作
自动类型转换
- 当运算符的两边出现不一致的类型时,会自动转换成较大的类型
- 大的意思是能表达的数范围更大
- char->short->int->long->long long
- int->float->double
- 对于printf,任何小于int的类型会被转换成int;float会被转换成double(此条解释用printf时,用%f足以输出double)
- 但是scanf不会,要输入short,需要%hd
对scanf
你要short,你要%hd
你要int,你需要%d
你要longlong,你需要%ld
注意:不能以整数形式输入char,必须先输入一个整数,再交给char的类型。(见上方不带空格的scanf)
强制类型转换
要把一个量强制转换成另一个类型(通常是较小的类型),需要:
(类型)值
比如
(int)10.2:把10.2这个double转换为int
(short)32:把32这个int转换为short
注意这时候的安全性,小的变量不总能表达大的变量
(short)32768
强制类型转换的优先级高于四则运算
输出大于平均数的数(数组)
#include<stdio.h> int main() { int x; double sum=0; int cnt=0; int number[100]; scanf("%d",&x); while(x!=-1){ number[cnt]=x; sum+=x; cnt++; scanf("%d",&x); } if (cnt>0){ printf("%f\n",sum/cnt); int i; for(i=1;i<cnt;i++){ if(number[i]>sum/cnt){ printf("%d\n",number[i]); } } } return 0; }
统计数的个数
#include<stdio.h> int main() { const int number=10; int x; int count[number]={0}; int i; //输入0-9的数字 scanf("%d",&x); while(x!=-1){ if(x>=0&&x<=9){ count[x]++; //计数 } scanf("%d",&x); } //遍历数组输出 for (i=0;i<number;i++){ printf("%d:%d\n",i,count[i]); } return 0; }
输出素数表(数组)
#include<stdio.h> int main() { const int maxNumber=25; int isPrime[maxNumber]; int i; int x; for(i=0;i<maxNumber;i++){ isPrime[i]=1; } for(x=2;x<maxNumber;x++){ if(isPrime[x]){ for(i=2;i*x<maxNumber;i++){ isPrime[i*x]=0; } } } for(i=2;i<maxNumber;i++){ if(isPrime[i]){ printf("%d\t",i); } } printf("\n"); return 0; }