操作符详解

目录

操作符的分类

 1 算术操作符

1.1 + 和 -

1.2 *

1.3 /

1.4 %

2 移位操作符

2.1 <<左移操作符

2.2 >>右移操作符

3 位操作符

4 赋值操作符

4.1 连续赋值

4.2  复合赋值符

5 单目操作符

5.1 ++和--

5.1.1 前置++

 5.1.2 后置++

5.1.3 前置-- 

 5.1.4 后置--

 5.2 +和-

 5.3 & * ~

5.4 (类型)

5.5 sizeof     ! 

6 关系操作符

7 逻辑操作符

 7.1 逻辑取反运算符 !

7.2 逻辑与运算符 &&

7.3 逻辑或运算符 ||

7.4 短路

 8 条件操作符

9 逗号表达式

10 下标引用  

11 函数调用操作符

12 结构体成员的访问

12.1 结构体成员的直接访问

12.2 结构体成员的间接访问


操作符的分类

算术操作符:+、-、*、/、%

移位操作符:<<     >>

位操作符:&    |     ^    ~

赋值操作符:=、+=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=

单目操作符:++、--、+、-、&、*、~、(类型)、sizeof、!

关系操作符:>、>=、<、<=、==、!=

逻辑操作符:&&、||、!

条件操作符:?:

逗号表达式:,

下标引用:[  ]

函数调用:( )

结构体成员访问:.     ->

 1 算术操作符

算数操作符:写代码时涉及计算的一系列操作符。

1.1 + 和 -

加法:+  减法:-

#include<stdio.h>
int main()
{
    int x = 3 + 5;
    int y = 6 - 2;
    printf("%d\n",x);
    printf("%d\n",y);
    return 0;

}

+和-是有两个操作数的,上述代码中+的操作数3、5,-的操作数6、2,这种有两个操作数的操作符也称为双目操作符。同理有单目操作符。

1.2 *

操作符*用来完成乘法。

#include<stdio.h>
int main()
{
    int num = 3;
    printf("%d\n",num*num);//输出9
    return 0;
}

1.3 /

运算符/用来完成除法。

#include<stdio.h>
int main()
{
	float x = 6/4;
	int y = 6/4;
	printf("%f\n",x);//输出1.000000 
	printf("%d\n",y);//输出1 
	
	float z = 6.0/4;
	printf("%f\n",z);//输出1.500000 
	return 0;
 } 

除号两端如果是整数,执行的是整数除法,得到的结果也是整数。

如上示例中x的类型是float(浮点数),但是6/4的结果是1.0,而不是1.5。原因就是除号两端都是整数,执行了整数除法,只返回整数部分,丢弃小数部分。如果想要得到浮点数的结果,两个运算数中必须至少有一个浮点数,如示例中z,6.0/4执行浮点数除法,可得出1.5。

1.4 %

运算符%表示求模(余)运算,即返回两个整数相除的余值。%只能用于整数,不能用于浮点数。

#include<stdio.h>
int main()
{
	int x = 6%4;
	printf("%d\n",x);//输出2
	
	printf("%d\n",12%-5);//输出2 
	printf("%d\n",-12%5);//输出-2 
	printf("%d\n",-12%-5);//输出-2 
	return 0;
 } 

由上述示例最后三个可以看出,负数求模规则:结果的正负号由第一个运算数的正负号决定。

2 移位操作符

<<左移操作符

>>右移操作符

移位操作符移的是存储在内存中的二进制位(不能是八进制等),且操作数只能是整数。

2.1 <<左移操作符

移位规则:左边抛弃、右边补0

#include<stdio.h>
int main()
{
	int num = 10;
	int n = num<<1;
	printf("n = %d\n",n);//n=20
	printf("num = %d\n",num);//num=10
	return 0;
 } 

num=10,10的2进制是1010,int占4个字节,每个字节8个二进制位,且数值在内存中以补码形式储存,正数补码和原码相同,所以num在内存中的二进制是:

                       00000000000000000000000000001010     num的2进制表示

                       00000000000000000000000000010100      num<<1的结果

左边丢掉一位,右边补0。但num本身值不变,num<<1即num向左移一位,将其结果赋值给n,可得出移动后的值。

2.2 >>右移操作符

移位规则(两种):

1.逻辑右移:左边用0补充,右边丢弃

2.算术右移:左边用原来值的符号位补充,右边丢弃

这两种规则的运用取决于编译器,常用算数右移。

#include<stdio.h>
int main()
{
	int num = 10;
	int n = num>>1;
	printf("n = %d\n",n);//n=5
	printf("num = %d\n",num);//num=10
	return 0;
 } 

由上述示例可以看出,左移一位有乘二效果,右移一位有除2效果。

移位操作符不能移动负数位,这个标准未定义。

num>>-1错误

3 位操作符

位操作符(操作数必须是整数):

1 &        按位与      规则:有0就为0,全为1才为1

2 |          按位或      规则:有1就为1,全0才为0

3 ^         按位异或   规则:相同为0,相异为1

4 ~         按位取反   规则:原0变1,原1变0   (&  |  ^ 也是双目操作符)

#include<stdio.h>
int main()
{
	int num1 = 6;
	int num2 = -7;
	printf("%d\n",num1&num2);//0
	printf("%d\n",num1|num2);//-1
	printf("%d\n",num1^num2);//-1
	printf("%d\n",~0);//-1
	return 0;
 } 

例1:不能创建临时变量(第三个变量),实现两个整数的交换。

#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int temp = 0;//一般交换两个数据,创建temp 
	temp = a;
	a = b;
	b = temp;
	printf("a=%d b=%d\n",a,b);//a=20 b=10
	
	//0^3  =   3        3^3=    0     因此a^a=0 0^a=a 且满足交换律 
	//000 ->  011       011 -> 000
	//011               011
	
	int x = 5;//不创建临时变量 
	int y = 8;
	x = x^y;//x=5^8
	y = x^y;//y=(x^y)^y=x^y^y=x^0=x=5
	x = x^y;//x=(x^y)^x=x^y^x=0^y=y=8
	printf("x=%d y=%d\n",x,y);//x=8 y=5
	
	return 0; 
 } 

4 赋值操作符

在变量创建时,给一个初始值称为初始化,在变量创建好后,再给一个值,称为赋值。

1 int a = 10;//初始化

2 a = 200;//赋值,这里=是赋值操作符

4.1 连续赋值

1 int a = 3;

2 int b = 4;

3 int c = 0;

4 c=b=a+3;//连续赋值,从右向左依次赋值 c=6

4.2  复合赋值符

1 int a = 10;

2 a+=3;//a=a+3

3 a-=3;//a=a-3

 这样的复合赋值符有很多,方便了我们编写代码。

5 单目操作符

单目操作符:只有一个操作数。

5.1 ++和--

++是自增的操作符,--是自减的操作符,都分为前置++/--和后置++/--

5.1.1 前置++

1 int a = 10;

2 int b = ++a;//++的操作数是a,放在a前面,为前置++;a先++,再赋值给b

3 printf("a=%d b=%d\n",a,b);//a=11 b=11  a自身也要++,++后再赋给b

 5.1.2 后置++

1 int a = 10;

2 int b = a++;

printf("a=%d b=%d\n",a,b);//a=11 b=10  a自身++,++前赋值给b

5.1.3 前置-- 

1 int a = 10;

2 int b = --a;

3 printf("a=%d b=%d\n",a,b);//a=9 b=9

 5.1.4 后置--

1 int a = 10;

2 int b = a--;

3 printf("a=%d b=%d\n",a,b);//a=9 b=10

 5.2 +和-

 这里+表示正号,-表示负号,是单目操作符。

1 int a = 10;//即a= +10; 正号一般完全可以省略

2 int b = -a;//b= -10

 5.3 & * ~

操作符&为取地址操作符,此时为单目操作符。 &在位操作符中是表示按位与,为双目操作符。

1 int a = 10;

2 printf("%p\n",&a);//输出0x006FFD70

 假设a在内存中占的四个字节地址为0x006FFD70、0x006FFD71、0x006FFD72、0x006FFD73,&a后输出0x006FFD70,取出的是a所占四个字节中较小字节的地址。

操作符*为解引用操作符。

1 int a = 10;

2 int* pa=&a;

3 *pa=0;//*pa就是a 

*和&都在指针中使用。 

~在位操作符中有解释。

5.4 (类型)

(类型) 表示强制类型转换。

1 int a = 3.14;

//a是int类型,3.14是double类型,两边类型不同,编译器会报警告

2 int a = (int) 3.14;

//即将3.14强制转化成int类型,转化后只取整数,这样强制转换可以消除警告。

5.5 sizeof     ! 

sizeof是关键字,也是操作符,用来计算sizeof的操作符数的类型长度,单位是字节。

1 int a = 10;

2 printf("%zd\n",sizeof(int));输出4

 !是逻辑操作符,也是单目操作符。

6 关系操作符

用于比较的表达式中运用的操作符为关系操作符。 

 > 大于  >=大于等于

 < 小于  <=小于等于

==相等  !=不相等

多个关系运算符不宜连用 。如:18<=age<=30应改写成age>=18 && age<=30。

7 逻辑操作符

 7.1 逻辑取反运算符 !

   a   !a
非0   0
   0    1

 一个变量叫flag,如果flag为真,!flag就是假;如果flag为假,!flag就是真。

7.2 逻辑与运算符 &&

&&是与运算符,也表示并且,如:age>=18&&age<=30。

        a        b         a&&b
     非0     非0            1
     非0        0            0
        0      非0            0
        0        0            0

a&&b,两边表达式同真才为真,只要有一个是假的,则整个表达式为假。

7.3 逻辑或运算符 ||

        a        b         a||b
     非0     非0            1
     非0        0            1
        0      非0            1
        0        0            0

a||b,两边表达式只要有一个是真,那么整个表达式就是真,两边都为假的时候才为假。

7.4 短路

逻辑运算符特点:先对左侧的表达式求值,再对右侧表达式求值。

若左侧满足条件,就不再对右侧表达式求值。这种情况称为短路。

1 if(month>=3&&month<=5)//若month不满足>=3的条件,左侧为0,右侧表达式无需执行,整个表达式结果为0.

2 if(month==12||month==7)//若month满足左侧,右侧无需执行,整个表达式结果为1.

短路求值:仅根据左侧操作结果就能知道整个表达式的结果,不再对右操作数进行计算的运算。

#include<stdio.h>
int main()
{
	int i = 0,a1 = 0,b1 = 2,c1 = 3,d1 = 4;
	i = a1++&&++b1&&d1++;//a1=0,右侧无需计算,无需执行,b1c1d1的值不改变 i=0 
	printf("i=%d a1=%d b1=%d c1=%d d1=%d\n",i,a1,b1,c1,d1);//0 1 2 3 4
	
	int m = 0,a2 = 1,b2 = 2,c2 = 3,d2 = 4;
	m = a2++&&++b2&&d2++;//a2=1,b2=3,d2=4,m=1 都执行了 
	printf("m=%d a2=%d b2=%d c2=%d d2=%d\n",m,a2,b2,c2,d2);//1 2 3 3 5
	
	int n = 0,a3 = 0,b3 = 2,c3 = 3,d3 = 4;
	n = a3++||++b3||d3++;//a3=0,b3=3,d3无需计算 n=1
	printf("n=%d a3=%d b3=%d c3=%d d3=%d\n",n,a3,b3,c3,d3);//1 1 3 3 4 d3不变 
	
	int p = 0,a4 = 1,b4 = 2,c4 = 3,d4 = 4;
	p = a4++||++b4||d4++;//a4=1其他无需计算执行,p=1 
	printf("p=%d a4=%d b4=%d c4=%d d4=%d\n",p,a4,b4,c4,d4);//1 2 2 3 4
	
	return 0; 
 } 

 8 条件操作符

条件操作符也叫三目操作符。

1 exp1?exp2:exp3 

如果exp1为真,exp2计算,其结果为表达式结果;如果exp1为假,exp3计算,其结果为表达式结果。

#include<stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d",&a,&b);//输入 3 2 
	int m = a>b?a:b;
	printf("%d\n",m);//输出3 
	return 0;
 } 

9 逗号表达式

逗号表达式,用逗号隔开的多个表达式,从左向右依次执行,最后一个表达式的结果是整个表达式的结果。

1 int a = 1;

2 int b =2;

3 int c=(a>b,a=b+10,b=a+1);//a>b为0,a=2+10=12,b=13   c=13、

4

5 if(a=b+2,c=b/2,d>0)//d>0为判断条件

10 下标引用  

操作符:[  ]  双目操作符

操作数:一个数组名+一个索引值(下标) 

1 int arr[5];//创建数组

2 arr[3]=4;//实用下标引用操作数

3 [ ]的操作数是arr和3

11 函数调用操作符

 操作符:()

一个或多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

 Add(3,5)//操作数是Add  3  5

printf("hello\n")

12 结构体成员的访问

12.1 结构体成员的直接访问

结构体变量名.成员名  如:p.x  p.y 直接通过.来访问。

#include<stdio.h>
struct Point
{
	int x;
	int y;
 } ;
 
 int main()
 {
 	struct Point p1 = {1,2};
	printf("%d %d\n",p1.x,p1.y);//1 2
 	return 0;
 }

12.2 结构体成员的间接访问

结构体变量名->成员名 如:p->x  p->y  通过指向结构体的指针访问结构体成员。

#include<stdio.h>
struct Point
{
	int x;
	int y;
 } ;
 
 int main()
 {
 	struct Point p1 = {1,2};
 	struct Point *ptr = &p1;
	printf("%d %d\n",ptr->x,ptr->y);//1 2
 	return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值