vlambda博客
学习文章列表

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;

}



C语言基础2:“运算符”



新浪微博:@秀米XIUMI