基础C语言(2)及练习题目

一.

 short 2字节16bit  -2^15~2^15-1   无符号时0,255
int 4  32  -2^31~2^31
float小数点后面可以精确到6-7位,后面的就无法确定
double  15-16位  +- 1.79*10^308
0.0(-0.0000001,0.0000001)这个范围

如果表达式是混合类型,那么窄字节会自动扩充为宽字节数据进行运算
short->int->long->long long->float->double
char->int

if(x = 1){
不管x为何值,if语句块都会执行
}

二.

关系运算符
== < > >= <= !=

逻辑运算符 0假1真  ‘\0’也是假  0的ascii码是’\0’  0.0 ,null 也是假
&&逻辑与   5&&5 = 1  ,  ‘\0’&&5 = 0  
||逻辑或
!逻辑非
逻辑运算符 连接 多个逻辑值(任意值) 关系表达式的结果是逻辑值
非0即1   例3.14为真为1
逻辑运算符的结果也是逻辑值 

0<=x && x<=10
0<= x <=10//注意:有没有&&有很大差别

表达[10]区间
!(0<=x && x<=10)
x<0 || x>10

写逻辑表达式:
1.	判断闰年
2.	判断平年
3.	判断三角型三条边
4.	判断水仙花数

	
	 x%4==0 && x%100!=0  || x%400==0
	
	 !(x%4==0 && x%100!=0  || x%400==0)
	
	 (a+b> c && a+c> b && c+b> a )== 1
	
	 (pow((num%10),3)+pow((num/10%10),3)+pow((num/100),3))==num

三.

int i=0,j=0;
int res = i++>0 && ++j>0;
结果res=0;
i = 1 j =0 
**逻辑运算符的短路特性:
0&&x 无论x的值是什么,都无法改变表达式的最终值,所以系统不会计算后面的x
当||连接的多个表达式,如果前面的结果为1时,后面的x_expr不会再计算**

**优先级问题**:
int i=0,j=0,k=0
res = ++i>0 || ++j>0  && ++k>0
i,j,k
0 1 1
相当于 res =++i>0 ||( ++j>0  && ++k>0)   
**&&的优先级高**

res =( ++i>0 || ++j>0)  && ++k>0  结果为1 0 1

!100 =0
**! 感叹号优先级高于关系运算符**
关系运算符高于&& ||

**大致优先级顺序
!> 算数运算符 > 关系运算符 > && > ||** 
**算数运算符 > 关系运算符 > 逻辑运算符 (选择题一般出法)**
3+x >5 先算(3+x)

位运算符:
& | ^ ~ >> << 
**位运算符只能作用于整数和字符(因为字符算int),按二进制位运算**
 1&1 =1
这里面的数代表二进制位的数值 1和0
十进制数:
	27&13 =9 (转为二进制按位与) 0001 1011    0000 1101   0000 1001
	-7&23=17  1 0(27个) 0000 0111-> 1111 1001  0001 0111    0001 0001 
	-7&-3=-7    1111 1001     0000 0011 ->1111 1101     1111 1001-> 0000 0111
推论:
**-1&num = num
-1:1111 1111
0&num =0**

十进制数:
	27|13   0001 1111 =31(同上面与运算相同,过程已省略)
	-7|23   1111 1111 =-1
	-7|-3   1111 1101 =-3

^按位异或:
不同为1,相同为0

十进制数:
	27^13 =22  
	-7^23 = -18  
	-7^-3 = 4

~按位取反:
~num = -(num+1)=-num-1
所以-num=~num+1


推论:
	**0|num= num
	-1|num= ~num =-num-1
	num^num=0**
	
如果num是个整数 –num的计算则(变负数 按位取反+1)

x = x^y
y = x^y     
x\^y^y –>x^\(y\^y)  先算当前式子的运算符
x= x^y

嵌入式开发经常使用位运算符

四.

>>  二进制位右移
1001 0101 1001 0101 1001 0101 1001 0101 >>4  
移出的舍弃,左边空缺的位置,signed数据左边补符号位,unsigned数据左边补0
循环右移 >> 32 相当于右移0位
>>33 右移33位,相当于>> 1,但是编译时会有警告

**每向右移动一位,相当于除以2,但不是全部成立
-1右移一位还是-1
!对于负的奇数,相当于除以2再减1**

<< 左移
移出的位舍弃,右边空出的位补0
每左移一位,相当于乘2
但是  21亿*2  这样会溢出 ,也有可能变成负数

int x= 2020,y=2049;
int res =(x&y) + ((x^y)>>1);

求res的结果   //为平均值  (x+y)/2=2034
(x&y) 求相同的部分
x^y 求不同的部分 ,然后除以2
所以 2020 +(2049-2020)/2   十进制求平均值

int year = 2020 int i =0 for(;year!=0;i++){
//每循环一次,二进制中的1少了一个
year= year&(year-1) }
求一个整数其二进制位1的个数

0101 0110  //把这个当做year
&0101 0101  //这个就是year-1
0101 0100  //这是循环一次的答案

五.

赋值运算符

	赋值过程中会涉及数据扩充和溢出问题
	宽给窄赋值,只能保存其低字节数据
	浮点数据给整数赋值,只保留整数部分
int x=3.6
x=3

int x=3
x *=3+2   是 3*5

三目运算符,就是说有三个操作数
?
x<y?++a:++b
只选择其中一个执行

sizeof:

	sizeof 是一个操作符,不是一个函数
	sizeof 是求一个类型或者一个变量或者一个数据的字节大小
	对于类型,()不能省略,但是对于变量或者数据,那么()可省略
*例如*
 printf(“%u\n”,sizeof(char))
 printf(“%u\n”,sizeof 3)   和  printf(“%u\n”,sizeof (3))  一样可行

printf(“%u\n”,sizeof('a’));    4字节

char c = ‘a’
printf(“%u\n”,sizeof\(c\))   1字节

int x =0
printf(“%u\n”,sizeof(++x))    4
这个时候x是不会变的
sizeof(x=100)
**sizeof()  不会计算括号里面的表达式**

char a =’0’
short b=1
double d=3.14
sizeof(a*b+d)     8  因为结果是doule类型是8字节

sizeof(3.14)默认是double
sizeof(3.14f)是float

sizeof(函数)   1
sizeof(函数())    返回类型的大小,并且不会调用函数

1u是表示这个数据是无符号

char c = 160    
int res = ~c>>3+1
先算取反,再算+,再算右移
1010 0000(160十进制转二进制)
c是char但是会变成int   1(24个1)1010 0000
0(24个0)0101 1111 >>4  
(这里4是因为先算算术运算,所有3+1右移4位)
0(24个0)0000 0101  = 5

unsigned char a=160   
1010 0000
int res = ~a>>3+1  -11
转为unsigned int 000…  1010 0000

**六.**
逗号,是最低的运算符
()优先级限定运算符
[] 下标访问运算符
& 取地址运算符
\* 取值运算符
\. 成员运算符
\->指针成员运算符

**~ (取反)优先级大于 算术 大于 移位**
&取址运算符,从控制台读取一个数写入所表示的内存中
scanf(“%d”,&age);  输入不要加\n

分支选择语句

	if 
	switch
条件循环

	for
	while
	do while
语句嵌套练习:
1.	输入三条边长,判断是否三角型,判断什么三角型
#include<stdio.h>
int main(){
int a,b,c;
scanf(%d%d%d”,&a,&b,&c);
if(a+b>c && a+c>b && b+c>a){
	if(a==b && b==c){
		printf(“是等边三角型”)}else if( a==b || b==c || a==c){
	printf(“是等腰三角型”)}else if(a*a + b*b== c*c || a*a+ c*c == b*b || b*b+ c*c == a*a ){
	print(“是直角三角型”);
	}else{
	print(“是普通三角形”);
		}
	}
return 0;
}
2.	输入一个月份,判断这个月份有多少天,如果是2月,再让用户输入年份来判断有多少天
#include<stdio.h>
int main(){
int month = 0;
int year = 0;
print(“请输入一个月份:”)
scanf(%d”,&month);
if(month>0 && month<=12){
	if(month == 2){
printf(“请输入年份”);
	scanf(%d”,&year);
	if(year%4==0  &&  year%100!=0 || year%400==0){
		printf(29天”)}else{
	printf(28天”)}
	} 
	}else if(month == 4 || month == 6 || month == 9 || month == 11){
		printf(“有30”);
	}else{
		printf(“有31”);
		}
	return 0;
}
或者
int small  = month == 4 || month == 6 || month == 9 || month == 11
day =31-small
3.	模拟收银过程
输入商品单价 和 商品数量
如果超过500元,打9折,超过100元不够500则减免10元
输入客户付款金额
如果 付款金额足额 则 提示:应付x元,实付y元,找零z元
不够时 提示:应付x元,实付y元,还需要支付z元
#include<stdio.h>
int main(){
	int price=0,num=0,pay=0,prices=0;
	printf("请输入商品单价和商品数量");
	scanf(%d%d”,&price,&nums);
	prices = price*num;
	if(prices>500){
		prices *= 0.9
	}else if(prices>100){
		prices -= 10;
	}
	printf(“请输入付款金额”)scanf(%d”,&pay);
	if(pay>=prices){
		printf(“应付%d元,实付%d元,找零%d元”,prices,pay,(pay-price));
	} else{
		printf(“应付%d元,实付%d元,还需要支付%d元”,prices,pay,( price-pay));
	}
	return 0;
}

Float类型 %g %f,%g不会输出无意义的0
double %lf

输入四个整数,用分支语句求最大值
#include<stdio.h>
int main(){
	int x1=0,x2=0,x3=0,x4=0;
	printf("请输入四个整数");
	scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
	int max=x1;
	if(x2>max){
		max=x2;
	}if(x3>max){
		max=x3;
	}if(x4>max){
		max=x4;
	}
	printf("最大值是%d\n",max);
	return 0;
}
求最大值用三目解决方案
int m =a>b?(a>c?(a>d?a:d):c>d?c:d)):(b>c?(b>d?b>d):(c>d?c:d)
输入三个整数,从小到大输出这三个整数
#include<stdio.h>
int main(){
	int a,b,c,t=0;
	printf("请输入三个整数");
	scanf("%d%d%d",&a,&b,&c);
	if(a>b){
		t=a;
		a=b;
		b=t;
	}if(a>c){
		t=a;
		a=c;
		c=t;
	}if(b>c){
		t=b;
		b=c;
		c=t;
	}
	printf("%d %d %d",a,b,c);
	return 0;
}
如果一个日期存在,则计算这个日期的下一天
	年   月   日
	日  31   30  29  28  剩下其它情况
nt main(){
	int year,mon,day;
	printf("请输入一个日期:");
	scanf("%d%d%d",&year,&mon,&day);
	int pd = 0;
	if(mon>0 && mon<= 12){
		if(mon==2){
			int leap = (year%4==0 && year%100!=0 || year%400==0);
			if(day>1 && day<=28+leap){
				pd = 1;
				}
		}else{
			int small = (mon==4 || mon==6 || mon==9 || mon==11);
			if(day>1 && day<=31-small){
				pd = 1;
				}  
			}
		if(pd==1){
			printf("有效日期\n");
			if(mon==4 || mon==6 || mon==9 || mon==11){
				if(day==30){
					mon += 1;
					day = 1;
				}else{
					day += 1;
				}
			}else if(mon==2){
				if(day==28){
					if(!(year%4==0 && year%100!=0 || year%400==0)){
						mon = 3;
						day = 1;
					}else{
						day += 1;
					}
				}else{
					if(day==29){
						mon = 3;
						day = 1;
					}else{
						day += 1;
					}
					}
				}
				else{
				if(day==31){
					if(mon==12){
						year += 1;
						mon = 1;
						day = 1;
					}else{
						mon += 1;
						day = 1;
					}
				}else{
					day += 1;
				}
			}
			}else{
			printf("无效日期\n");
		}	
		}else{
			printf("无效日期\n");
		}
		
		printf("有效日期的下一天为%d年%d月%d日",year,mon,day);
	return 0;
}
如果日期存在,计算该日期是当年的第几天
#include<stdio.h>
int main(){
	int year,mon,day;
	printf("请输入一个日期:");
	scanf("%d%d%d",&year,&mon,&day);
	int pd = 0;
	if(mon>0 && mon<= 12){
		if(mon==2){
			int leap = (year%4==0 && year%100!=0 || year%400==0);
			if(day>1 && day<=28+leap){
				pd = 1;
				}
		}else{
			int small = (mon==4 || mon==6 || mon==9 || mon==11);
			if(day>1 && day<=31-small){
				pd = 1;
				}  
			}
		if(pd==1){
			int i=0,mday=0,aday=0;
			int mon_d[12]={31,28,31,30,31,30,31,31,30,31,30,31};
			if(year%4==0 && year%100!=0 || year%400==0){
				mon_d[1]=29;
			}
			for(i=0;i<mon-1;i++){
				mday += mon_d[i];
			}
			aday = mday+day;
			printf("%d\n",aday);
		}else{
			printf("日期错误");
		}
	}else{
			printf("日期错误");
		}
	
	return 0;
}

输入一个月份,输出这个月份属于哪个季节

#include<stdio.h>
int main(){
	int mon=0;
	printf("请输入一个月份:");
	scanf("%d",&mon);
	if(mon>0 && mon<=12){
		if(mon==3 || mon==4 || mon==5){
			printf("春季\n");
		}else if(mon==6 || mon==7 || mon==8){
			printf("夏季\n");
		}else if(mon==9 || mon==10 || mon==11){
			printf("秋季\n");
		}else{
			printf("冬季\n");
		}
	}else{
		printf("错误月份\n");
	}
	return 0;
}
另外一种方法
#include<stdio.h>
int main(){
	int m = 0;
	printf("请输入季节:");
	scanf("%d",&m);
	if(m/3==1){
		printf("春季");
	}else if(m/3==2){
		printf("夏季");
	}else if(m/3==3){
		printf("秋季");
	}else{
		printf("冬季");
	}
	return 0;
}
企业发放的奖金根据利润提成。
	利润低于或等于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%提成,从键盘输入当月利润,求应发放奖金总数?
#include<stdio.h>
int main(){
	float money=0,price=0;
	printf("请输入利润值,单位为W\n");
	scanf("%f",&money);
	if(money<=10){
		price= 0.1*money;
	}else if(money<=20){
		price=10*0.1+(money-10)*0.075;
	}else if(money<=40){
		price=10*0.1+10*0.075+(money-20)*0.05;
	}else if(money<=60){
		price=10*0.1+10*0.075+20*0.05+(money-40)*0.03;
	}else if(money<=100){
		price=10*0.1+10*0.075+20*0.05+20*0.03+(money-60)*0.015;
	}else{
		price=10*0.1+10*0.075+20*0.05+20*0.3+40*0.015+(money-100)*0.01;
	}
	printf("奖金是%fW\n ",price);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值