C语言入门——操作符

目录

一、操作符

1、算术操作符

2、移位操作符

3、位操作符

4、赋值操作符

5、单目操作符

6、关系操作符

7、逻辑操作符

8、条件操作符

9、逗号操作符

10、下标引用、函数调用和结构成员

二、表达式求值

1、隐式类型转换

(1)整型提升

 (2)算术转换

 2、操作符的属性

三、练习:交换a和b的值


一、操作符

1、算术操作符

+    -      *      /     %

●除了%操作符只能作用于整数外,其他的几个操作符都可以作用于整数和浮点数。

●对于/操作符,如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。

%操作符的两个操作数必须为整数,返回的是整除之后的余数。

例:

int a=3/5;     //0
float a=6/5;   //1.00000
float a=6/5.0  //1.2
int a=7%3.0    //报错

2、移位操作符

>> 右移操作符

<< 左移操作符

●移动位数为正数

●左移:把二进制位向左移动,左边丢弃,右边补0

●右移:把二进制位向右移动,右边丢弃,左边补0

int a=2;
int b=a<<1;  //4

int c=10;
int d=c>>1;  //5

3、位操作符

& 按位与

|  按位或

^ 按位异或

●操作数必须是整数

4、赋值操作符

直接赋值:=

复合赋值:+=  -=  *=  /=  %=  >>=  <<=  &=  |=  ^=

●=赋值  ==判断

5、单目操作符

!              逻辑反操作

-                负值

+               正值

&               取地址

sizeof()     操作数的类型长度(单位为字节),是一个操作符不是函数

~               对一个数的二进制位按位取反

--               前置、后置--

++             前置、后置++

*                间接访问操作符(解引用操作符)

(类型)       强制类型转换

 例:

//sizeof():
char arr[10]={0};
int size=sizeof(arr);
int len=sizeof(arr)/sizeof(arr[0]);

6、关系操作符

>          大于

>=        大于等于

<          小于

<=        小于等于

!=         用来测试“不相等”

==        用来测试“相等”

7、逻辑操作符

&&    逻辑与

||       逻辑或

例:

int i=0,a=0,b=2,c=3,d=4;
i=a++ && ++b && d++;     //a=1,b=2,c=3,d=4,因为第一部分为0,后面的不计算

8、条件操作符

表达式?表达式1:表达式2

9、逗号操作符

表达式1,表达式2,表达式3,...,表达式N

●从左向右依次执行,整个表达式的结果是最后一个表达式的结果

10、下标引用、函数调用和结构成员

●[]    下标引用

[]有两个操作数,一个是数组名,一个是索引值

●.     函数调用,结构成员访问

.可以接受一个或多个操作数,第一个操作数是函数名,剩余的操作数就是传递给函数的参数

●->   结构成员访问

二、表达式求值

1、隐式类型转换

(1)整型提升

C的整形算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

例:

char a=3;
char b=127;
char c=a+b;  //此时c=-126,因为a和b都是char类型,没有达到一个int的大小。这里就会发生整型提升。

整型提升是按照变量的数据类型的符号位来提升的。

负数的整型提升:高位补1

char c1=-1;

变量c1的二进制位(补码)中只有8个比特位:11111111。因为char为有符号的char,所以整型提升的时候,高位补充符号位,即为1。

提升后的结果是:11111111111111111111111111111111

●正数的整型提升:高位补0

char c2=+1;

变量c2的二进制位(补码)中只有8个比特位:00000001。因为char为有符号的char,所以整型提升的时候,高位补充符号位,即为0。

提升后的结果是:00000000000000000000000000000001

●无符号整型提升:高位补0

 例:

//例1
int main()
{
    char a=0xb6;
    char b=0xb600;
    char c=0xb6000000;
    if(a==0xb6)
        printf("a");     //要进行整型提升,变成负数,不会输出
    if(b==0xb600)
        printf("b");     //要进行整型提升,变成负数,不会输出
    if(c==0xb6000000) 
        printf("c");     //不需要整型提升,输出
    return 0;
}
//例2
int main()
{
    char c=1;
    printf("%u\n",sizeof(c));    //1个字节
    printf("%u\n",sizeof(+c));   //发生整型提升,4个字节
    printf("%u\n",sizeof(-c));   //发生整型提升,4个字节 
    printf("%u\n",sizeof(!c));   //发生整型提升,4个字节
    return 0;
}

 (2)算术转换

如果某个操作符的各个操作符属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。

寻常算术转换:

long double>double>float>unsigned long int>long int >unsigned int>int

算术转换是根据操作数的类型在上述排名决定的。如果排名较低,就要转换为另外一个操作数的类型后执行运算。

 2、操作符的属性

复杂表达式的求值有三个影响的因素:操作符的优先级、操作符的结合性、是否控制求值顺序。

两个相邻的操作符先执行哪个取决于它们的优先级。如果两者的优先级相同,取决于它们的结合性。

操作符描述用法示例结果类型结合性是否控制求值顺序
( )聚组(表达式)与表达式相同N/A
( )函数调用rexp(rexp,...,rexp)rexpL-R
[]下标引用rexp[rexp]lexpL-R
.访问结构成员lexp.member_namelexpL-R
->访问结构指针成员rexp->menber_namelexpL-R
++后缀自增lexp++rexpL-R
--后缀自减lexp--rexpL-R
!逻辑反!lexprexpR-L
~按位取反~lexprexpR-L
+单目,表示正值+rexprexpR-L
-单目,表示负值-rexprexpR-L
++前缀自增++rexprexpR-L
--前缀自减--rexprexpR-L
*间接访问*rexplexpR-L
&取地址&rexprexpR-L
sizeof取其长度,以字节表示sizeof rexp sizeof(类型)rexpR-L
(类型)类型转换(类型)rexprexpR-L
*乘法rexp*rexprexpL-R
/除法rexp/rexprexpL-R
%整数取余rexp%rexprexpL-R
+加法rexp+rexprexpL-R
-减法rexp-rexprexpL-R
<<左移位rexp<<rexprexpL-R
>>右移位rexp>>rexprexpL-R
>大于rexp>rexprexpL-R
>=大于等于rexp>=rexprexpL-R
<小于rexp<rexprexpL-R
<=小于等于rexp<=rexprexpL-R
=等于rexp=rexprexpL-R
!=不等于rexp!=rexprexpL-R
&位与rexp&rexprexpL-R
^位异或rexp^rexprexpL-R
|位或rexp|rexprexpL-R
&&逻辑与rexp&&rexprexpL-R
||逻辑或rexp||rexprexpL-R
?:条件操作符rexp?rexp:rexprexpN/A
=赋值lexp=rexprexpR-L
+=以...加lexp+=rexprexpR-L
-=以...减lexp-=rexprexpR-L
*=以...乘lexp*=rexprexpR-L
/=以...除lexp/=rexprexpR-L
%=以...取模lexp%=rexprexpR-L
<<=以...左移lexp<<=rexprexpR-L
>>=以...右移lexp>>=rexprexpR-L
&=以...与lexp&=rexprexpR-L
^=以...异或lexp^=rexprexpR-L
|=以...或lexp|=rexprexpR-L
,逗号rexp,rexprexpL-R

●一些问题表达式

写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。
例1:

a*b+c*d+e*f

表达式的计算顺序可能是:

a*b
c*d
a*b+c*d
e*f
a*b+c*d+e*f

a*b
c*d
e*f
a*b+c*d
a*b+c*d+e*f

 例2:

c + --c

表达式的计算顺序可能为:

--c
c+--c

c+--c
--c

 例3:来源于《C和指针》

int main()
{
    int i=10;
    i=i-- - --i*(i=-3)*i++ + ++i;
    printf("i=%d\n",i);
    return 0;
}

 例4:

int fun()
{ 
    static int count=1;
    return ++count;
}
int main()
{
    int answer;
    answer=fun()-fun()*fun();
    printf("%d\n",answer);
    return 0;   
}

三、练习:交换a和b的值

//1:借助第三个变量
int main()
{
    int a=3;
    int b=5;
    int c=0;
    c=a;
    a=b;
    b=c;
    return 0;
}
//2:数值太大可能会溢出
int main()
{
    int a=3;
    int b=5;
    a=a+b;
    b=a-b;
    a=a-b;
    return 0;
}
//3:异或
int main()
{
    int a=3;
    int b=5;
    a=a^b;
    b=a^b;
    a=a^b;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

趣多多代言人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值