C语言基础2:“运算符”
运算符
#include<stdio.h>
int main()
{
/*
一.表达式
a + b
a / b
a % b //取余
(1)简单运算符:a、b、c、a+b
(2)复杂表达式:2*(a+b)/10+a*b
二.语句:以分号结束
4*(a+b)/10+a*b;
空语句:什么内容都没有,直接以分号结束;
语句块:以花括号{}括起来的区域就是语句块。
三.运算符
1.赋值运算符:“=” int a=10;从右向左赋值。
变量名 = 常量(变量/表达式)
左值:出现在运算符的左边 左值(常亮不能够作为左值)
变量名、(常量不行:例:左边10(常量)=右边50;显然50不能把值赋给10)
右值:出现在赋值语句的右边 右值
常量表达式、变量;
inta=500(常量表达式);
a=b
printf("a=%d\n",a);
a=500
注意区分初始化和赋值:
初始化:在声明(定义)一个变量的时候,为它赋一个初值
赋值:变量已经定义好了,只是改变变量的值。
自动类型转换(隐式类型转换)
float f = 45.6;//45.6默认是double类型,要是float类型,在45.6后面加一个后缀"f".
赋值的时候发生了隐式类型转换
第一种:较长的数据转换为较短的数据,发生截断,警告
float f = 45.6;//45.6默认是double类型 float占用4个字节,double占用8个字节
第二种:较小的数据转换为较大的数据,类型的提升 整型占4个字节,字符型占1字节
int a = 'a';//a=97,'a'是字符,是以ASCII码形式存储的
printf("a=%d\n",a);
赋值发生显示类型转换(强制类型转换)不会警告
(类型名)表达式
int result = (int)45.6f;
printf("result=%d\n", result);
2.算术运算符:
单目运算符(符号两边只要有一个操作数):+、-、++、--
++:自增 a++:a=a+1
前置++和前置--:表示先自增自减再赋值 由于增一和减一等价的操作中还包括赋值运算,而赋值运算的左值是不允许是表达式的,因此增一和减一的操作数只能是变量,不能是表达式。
int a=45,b=10,c=0;
c=++a;
a=a+1;
a=c;
printf("a=%d,c=%d\n",a,c);//a=46 c=46
后置++和后置--:表示先赋值(先把整个表达式赋值)后自增自减
int a=45,b=10,c=0;
c=a++;
c=a;
a=a+1;
printf("a=%d,c=%d\n",a,c);//a=46 c=45
--:自减 a--=a-1
*优先级: ++和--优先级高于+、-、*、/ 优先级相同,从左往右结合
int a=45,b=4,c=0;
c=--a(a=a-1=44) + a(这里的也变为了44)++;
printf("a=%d,c=%d\n"a,,c);//c=88 a=44
*结合性:
先看优先级再看结合性
双目运算符(表示符号两边要有两个操作数):+、-、*、/、%
除法“/”:如果操作数两边都是同一类型:那么结果也是同一种类型(+、-、*、/),即如果被除数和除数都是整数,那么它们相除所得的结果也是整数。而如果被除数或除数有一个是浮点数,或者两个都是浮点数,那么它们相除的结果也是浮点数。
int a=45,b=4,c=0;
c=a/b; // 45/4=11?
printf("a=%d,c=%d\n"a,,c);// 11
取模(求余数)“%”:两边的操作数只能是整数 余数的正负取决于被除数
int a=45,b=6;
int c=a%b;//余3
printf("c=%d\n",c);
3.关系运算符
用于判断两个操作数的大小关系(返回值 或 假值)
>、>=、<、<=、!=、==
c语言中:
真:非 0 为真:1,2,3,45,-1(小于0的数也是真);为真返回 1
假:0 为假;为假返回 0
int a=45,b=10,c=0;
c=a > b;/c=a!=b;
c=(‘=’表示赋值)12<=a<=50;//为真
c=(‘=’表示赋值)12<=a<=30; c=1<=30;(因为12<=a为真,即输出的结果为 1 ,1<=30,所以为真) //为真 优先级相同,从左往右结合 不能连着写
printf("c=%d\n",c);//输出返回 1 因此为真
c=a<b;
printf("c=%d\n",c);//a >b 所以为假 返回0
c语言提供的六种关系运算符
(1)/ 大于
(2)< 小于
(3)>= 大于等于
(4)<= 小于等于
(5)== 等于
(6)!= 不等于
> ,< ,<= ,>= 的优先级高于 == 和 !=
int HP = 100;
if (HP > 99) //在c语言中不能写成(20>HP>99),只能写成(HP>99 /HP+101>200)
{
printf("英雄的血量很足");
}
1.关系运算符的运算结果是一个逻辑值,逻辑值只有两种结果,'真'(1)和’假'(0).
int a=3,b=4,c=8,d;
printf("%d%d\n",a+3>b,-a-2*b>=c+1);
答案:1(真) 0(假)
printf("%d%d\n",a+1!=b<(先算小于,因为>的优先级高于 !=)c,a+b+c==2*a);
答案:1 1 0
printf("%d%d\n",c=a+b,c-1!=b>6(先算大于,因为>的优先级高于 !=);
答案:0 1 0
2.关系运算符都是双目运算符,要求有两个操作数的
3.关系表达式: 将常量 变量 函数等等通过关系运算符连接起来组成的表达式为关系表达式
4.逻辑运算符:
逻辑与:&& 并且 只有两个运算量(条件)同时真才为真,否则为假
逻辑或:|| 或者 只有当两个运算量都为假时才为假,否则为真,即只要有一个为真就为真
逻辑非:! 不等于 0 变 1,1 变 0 真的变假的,假的变真的
int a=4,b=5,c=6,d;
d=(a<4)&&(c<b);
printf("%d/n",d);//0(假)
e=(a<4)||(c>b);
printf("%d\n",e);// 1(真)
e=!(a<4)||(c>b);
printf("%d\n",e);// 0(假) 因为(a<4)||(c>b)为真,加上!就为假
短路现象:
例:int a=45,b=10,c=0;
c=(a=60)||(b=50);
printf("a=%d,b=%d,c=%d\n",a,b,c);//输出:60 4 1 理应为:60 50 1
短路现象
逻辑或,只要有一个为真就为真,可以不用去看第二个,不管第二个为不为真,反正表达式已经为真,它不会去算第二个表达式,即第二个赋值语句根本没有执行
5.括号运算符
有括号先算括号,括号能够提高优先级
int a=45,b=10,c=0;
122<=a<=30
拆分
12<=a
a<=30
c=(12<=a)&&(a<=30);//返回假 即0 (12<=a)成立,为真。(a<=30)为假,所以(12<=a)&&(a<=30)为假 1&&0
printf("c=%d\n",c);
6.三目运算符:
“ ?:”
例:
int a=45,b=4 c=0;
a < 10 ?//判断是否为真
printf("为真\n"):(否则)printf("为假\n"); //printf函数的返回值表示打印的字符数
7.位运算符
& :按位与 相对应的二进制位:都为 1 才为 1 ,否则为 0
| :按位或 相对应的二进制位:有 1 为 1 ,否则为 0
^ :按位异或 相对应的二进制位:相同为 0 ,不同为 1
~ :按位取反 相对应的二进制位:0 变 1 ,1 变 0
>> :右移
<< :左移
正数:三码为一。即原码、补码、反码都相同
负数:
符号位:正数符号位:0 负数符号位:1
原码:计算出的二进制 最直观的二进制表达方式
反码:负数:符号位不变,其余位按位取反
补码:负数:符号位不变,反码 +1
真正计算机计算是补码进行计算、计算结果在转成原码
例:
int a=5,b=6,c=0;
a的原码、反码、补码: 0101
-5(二进制位-10101)原码:1000 0000 0000 0000 0000 0000 0000 0101(32位)
-5反码:1111 1111 1111 1111 1111 1111 1111 1010
-5补码:1111 1111 1111 1111 1111 1111 1111 1011
c=a & b;
0101 补码
& 0100 补码 相对应的二进制位:都为 1 才为 1 ,否则为 0
......
0100 补码=》原码:4
printf("c=%d\n",c);//c=4
c=a|b;
0101 补码
| 0100 补码 相对应的二进制位:有 1 为 1 ,否则为 0
......
0101 补码=》原码:4
printf("c=%d\n",c);//c=5
c=-a&b;
-5(二进制位-10101)原码:1000 0000 0000 0000 0000 0000 0000 0101(32位)
-5反码:1111 1111 1111 1111 1111 1111 1111 1010
-5补码:1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111 1011 补码
& 0000 0000 0000 0000 0000 0000 0000 0000 0100(4的补码)
、、、、、、、、、、、、、、、、、、、、、、
0000 0000 0000 0000 0000 0000 0000 0000 0000 补码=》原码0 相对应的二进制位:都为 1 才为 1 ,否则为 0
printf("c=%d\n",c);// c=0
1111 1111 1111 1111 1111 1111 1111 1111 1011 补码
| 0000 0000 0000 0000 0000 0000 0000 0000 0100(4的补码)
、、、、、、、、、、、、、、、、、、、、、、
1111 1111 1111 1111 1111 1111 1111 1111 1111 补码=》原码 相对应的二进制位:有 1 为 1 ,否则为 0
printf("c=%d\n",c);// c=1
补码转为原码:除符号位不变,其它位取反,最后 +1
1000 0000 0000 0000 0000 0000 0000 0000 反码
1000 0000 0000 0000 0000 0000 0000 0001 原码
printf("c=%d\n",c);// c=-1
~ :按位取反 相对应的二进制位:0 变 1 ,1 变 0
a= ~ a;
0000 0000 0000 0000 0000 0000 0000 0101 a的补码
1111 1111 1111 1111 1111 1111 1111 1010 按位取反
.......................................
反码:1000 0000 0000 0000 0000 0000 0000 0101
原码: 1000 0000 0000 0000 0000 0000 0000 0110
printf("a=%d\n",a);// a=-6
左移右移运算符: 位运算 在二进制的基础上移动
右移:>>
规则:
正数:低位丢失,高位补零
原(10) :0000 0000 0000 0000 0000 0000 0000 1010
右移 :0000 0000 0000 0000 0000 0000 0000 0000
负数:低位丢失,高位补1
-1
原(10) : 1000 0000 0000 0000 0000 0000 0000 1010
右移(移动四位) :1111 0000 0000 0000 0000 0000 0000 0000
左移:<<
规则:高位丢失,低位补零,
高位 低位
原(10) :0000 0000 0000 0000 0000 0000 0000 1010
左移 :00 0000 0000 0000 0000 0000 0000 101000
例:
(1):
int a=10,b=0;
原码(10 正数):0000 0000 0000 0000 0000 0000 0000 1010
反码 :0000 0000 0000 0000 0000 0000 0000 1010
补码 :0000 0000 0000 0000 0000 0000 0000 1010
补码(左移两位):0000 0000 0000 0000 0000 0000 0010 1000 真正计算机计算是补码进行计算、计算结果在转成原码
原码 :0000 0000 0000 0000 0000 0000 0010 1000 (移动两位之后变成了40)
补码(右移两位):0000 0000 0000 0000 0000 0000 0000 0010
原码 :0000 0000 0000 0000 0000 0000 0000 0010 (移动两位之后变为了2)
b=a<<2; //b>>2;
printf("b=%d\n",b);
(2):
int a=-8,b=0;
原码(-8 负数):1000 0000 0000 0000 0000 0000 0000 1000
反码 :1111 1111 1111 1111 1111 1111 1111 0111
补码 :1111 1111 1111 1111 1111 1111 1111 1000
补码(左移三位):1111 1111 1111 1111 1111 1111 1100 0000
反码 : 1000 0000 0000 0000 0000 0000 0011 1111(符号位不变,其它按位取反)
原码 :1000 0000 0000 0000 0000 0000 0000 0000 (左移三位变为了-64)
补码(右移三位):1111 1111 1111 1111 1111 1111 1111 1111
反码 :1000 0000 0000 0000 0000 0000 0000 0000(符号位不变,其它按位取反)
原码 :1000 0000 0000 0000 0000 0000 0000 0001(反码加一) (右移三位变为了-1)
b=a>>2;
printf("b=%d\n,b);
8.逗号运算符
多个表达式之间使用逗号分隔,整个表达式的值是最后一个表达式的值。
逗号表达式的 优先级最低 ,低于赋值运算符,在不加括号的情况下,先进行赋值
例:
int a=45,b=10,c=0;
c=(a+b;,b+c,a+c);
c=55,10,45
printf("c=%d\n",c);//c=45(若不加括号,会先进行赋值,即c=55)
9.复合运算符
+=、-=、*=、/=、&=、|=、^=、~=
例:
int a=45,b=10,c=0;
a + =10;//a=a+10;
a - =10;//a=a-10;
a * =10;//a=a*10;
a / =10;//a=a/10;
a & =10;//a=a&10;
10. sizeof 运算符 不是一个函数
求一个类型或一个变量所占内存大小
int c=10;
sizeof(c);// 求变量可以不加括号,即直接写成:sizeof c; 加一个括号,提高它的优先级 括号的优先级是最高的
printf("sizeof c =%d\n",sizeof (c)); / printf("c=%d\n",sizeof (int);//(int):表示求一个类型,因为sizeof 与 int 都表示类型,所以加一个括号表示区别。
sizeof运算符只是求变量或者类型所占内存大小,即占几个字节,不会进行赋值
int c=10,d=0;
sizeof(c=c+1);//不会进行赋值,所以c 还等于 10
printf("c=%d]n",c);//c=10
*/
return 0;
}
新浪微博:@秀米XIUMI