C语言之操作符

目录

操作符分类

算数操作符

移位操作符

符号说明

移位规则

​编辑

位操作符

赋值操作符

单目操作符

比较操作符

逻辑操作符

条件操作符

逗号表达式

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

下标引用操作符:"[]"

函数调用操作符:"()"

结构成员访问操作符

表达式求值

隐式类型转换

算数转换

操作符的属性

操作符一览表

操作符分类

  • 算数操作符
  • 移位操作符
  • 位操作符
  • 赋值操作符
  • 单目操作符
  • 关系操作符
  • 逻辑操作符
  • 条件操作符
  • 逗号表达式
  • 下标引用,函数调用和结构成员

算数操作符

符号说明:

 +   --->   分别用于整数及浮点数的加法

 -   --->   分别用于整数及浮点数的减法

 *   --->   分别用于整数及浮点数的乘法

 /   --->   分别用于整数及浮点数的除法

%   --->   用于返回两个整数相除的余数

  • 除了%操作符之外,其他几个操作符可以作用于整数和浮点数。
  • 对于/操作符如果两个操作数均为整数,执行整数除法,而只要有浮点数执行就是浮点数除法(操作结果类型与式子中最大类型保持一致)。
  • %操作符的两个操作数必须为整数,返回的是整除之后的余数
  • 对于操作数如果是整数则编译器默认其为整形,如果是浮点数,则编译器默认其为双精度
int main() {
	float a = 9 / 2;
	printf("%f", a );
	return 0;
}

最终得到的结果为4.0000,因为算数两边的数均为整形,最终结果为整形,只不过最终用浮点类型进行了接收。 


移位操作符

符号:<<   >>  <<<   >>>

符号说明

左移运算符:用于将整数左移指定位数

右移运算符:用于将整数右移指定位数

<<   --->   算数左移运算符

>>    --->   算数右移运算符

<<<  --->   逻辑左移运算符

>>>  --->   逻辑右移运算符

移位规则

(左移运算符):不论算术移位还是逻辑移位,均将左边的数舍弃,右边空缺位补0(左边丢弃,右边补0)

(右移运算符):当进行逻辑移位时,右边位丢弃,左边空缺位补0(右边丢弃,左边补0) ;当进行算术移位时,右边位丢弃,左边位补原数的符号位(右边丢弃,左边补符号位 )。

关于符号位:0为正,1为负; 

#include <stdio.h>
void main() {
	int a = 2;
	//将a的二进制位左移一位
	int b=a << 1;
	printf("%d\n", b);
}

整数在内存中存储的是二进制的补码,所以移位是针对补码进行移位,之后再转为源码

正数的源码、反码、补码均相同

-1的源码反码与补码

警告:对于移位运算符,不要移动负数位,这是标准未定义的。


位操作符

按位:按二进制位

&:同为1则为1

|:有1则为1 

^:在或的前提下相异则为1(相同为0,相异为1)

异或的使用

#include <stdio.h>
void main() {
	//通过异或进行两个数的交换,本质:借助第三量
	int a = 2;
	int b = 6;
	printf("a=%d b=%d\n", a, b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
}

一个数和本身异或为0,一个数和0异或为本身


赋值操作符

赋值操作符作用:用于将表达式的值赋给变量

#include <stdio.h>
void main() {
	int a=2, b=0;
	a += 100;
	printf("%d\n", a);
	b = b + 100;
	printf("%d\n", b);
	//由此观之a+=100等价于a=a+100;
}

单目操作符

理解:只有一个操作数的操作符

int a = 10;
	printf("%d", sizeof a);
	printf("%d", sizeof (int));
//sizeof后面可以接变量与类型,当后面接变量的时侯后面的()可省略(证明sizeof是操作符,不是函数),但是当后面接类型的时候,后面应加()
int arr[10] = { 0 };
printf("%d", sizeof arr);
//结果为40,计算数组的总大小,单位字节
printf("%d", sizeof arr[0]);
//计算第一个类型的大小——为4
#include <stdio.h>
void main() {
	short s = 5;
	int a = 10;
	//sizeof算大小的时候以s为准——sizeof括号中放的表达式是不参与运算的
	printf("%d\n", sizeof(s = a + 2));
	printf("%d\n", s);
	//最后打印的结果为2,5
}

sizeof和数组

1:40                                                2:4/8

3:10                                                4:4/8

注意:数组传参,传过去的是数组首元素的地址

前置++与后置++

  • 前置++(++a):先+1,后参与运算
  • 后置++(a++):先参与运算,再+1

关于&与*

#include <stdio.h>
void main() {
	int a = 10;
	printf("%d\n", &a);
	int* pa = &a;
	*pa = 20;//解引用
	printf("%d\n", a);
}

强制类型转换(类型)

#include <stdio.h>
void main() {
	int a = (int)3.14;//将double类型强制转换成int
	printf("%d\n", a);
}

比较操作符

作用:用于表达式的比较,并返回一个真值或假值

注意:

  • =表示赋值,==表示判断左右是否相等
  • 比较两个字符串是否相等不能用==(==号比较引用的数据类型比较的是两个元素的地址值是否相等)

逻辑操作符

作用:用于判断数据表达式的值返回真值或假值

&&(逻辑与)——同真则真,有假则假

||(逻辑或) ——有真则真,同假则假

注意短路

a&&b——a为假则表达式直接为假短路b

a||b——a为真则表达式直接为真短路b

#include <stdio.h>
void main() {
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
	//最后结果为1,2,3,4
}

条件操作符

三目操作符:需要三个操作数

exp为(表达式)

exp1 ? exp2 :exp3

表达式1成立,则整个表达式的结果为表达式2,否则为表达式3.


逗号表达式

定义:逗号隔开的一段表达式

特点:从左向右依次计算,整个逗号表达式的结果是最后一个逗号表达式的结果。

exp1,exp2,exp3,……expn

#include <stdio.h>
void main() {
	int a = 3, b = 5, c = 0, d = (c = 5, a = c + 3, b = a - 4,c+=5);
	printf("%d\n", d);
	//最终结果d=10;
}

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

  • []:下标引用
  • ():函数调用
  • .:结构体中用来访问成员变量
  • ->:指针指向结构体成员变量的调用

下标引用操作符:"[]"

操作数:一个数组名+一个索引值

函数调用操作符:"()"

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

结构成员访问操作符

  • .:结构体.成员名
  • ->:结构体指针->成员名
struct Stu{
	char name[20];
	int age;
	double score;
};
void main(){
	struct Stu s = { "lili",25,85.5 };
	printf("1:%s %d %lf\n", s.name, s.age, s.score);
	struct Stu* pa = &s;
	printf("2:%s %d %lf\n", (*pa).name, (*pa).age, (*pa).score);
	printf("3:%s %d %lf\n", pa->name, pa->age, pa->score);
}

表达式求值

表达式求值的顺序一般由操作符的优先级和结合性决定的

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型

隐式类型转换

C语言的整形算数运算总是至少以缺省整形类型的精度来进行的

整形提升:为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转化为普通整形,这种转换称为整形提升

#include <stdio.h>
void main() {
	char a = 127;
	char b = 3;
	printf("%d\n", sizeof(a+b));//4——整形提升
	printf("%d\n", sizeof(a));//1
}

整形提升的意义

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

 

无符号的整形提升——高位补0

#include <stdio.h>
void main() {
	unsigned char c = -1;
	printf("%d\n", c);
	//最后结果为255
}

过程:

整形提升

-1原码:10000000000000000000000000000001

-1反码:11111111111111111111111111111110

-1补码:11111111111111111111111111111111

因为用char接收,所以进行截断从低位开始截断一字节

-1补码:11111111

之后打印——整形提升——无符号位整形提升高位补0

-1补码:00000000000000000000000011111111

因为这是补码,打印的是原码然而一看其为正整数原码补码相同因此将二进制的转化为10进制255,打印出255;

算数转换

如果某个操作符的各个操作数属于不同类型,那么除非一个操作数类型转化为另外一个操作数类型,否则操作无法进行。下面的层次体系称为寻常算数转换

排序由高到低

 如果某个操作数类型在上面这个列表中排名较低,那么首先要转换成另外一个操作数类型后执行运算


操作符的属性

复杂表达式的求值有3个影响因素

  • 操作符的优先级
  • 操作符的结合性
  • 是否控制求值顺序

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

#include <stdio.h>
void main() {
	int a = 12;
	int b = 3;
	int c = a + b * 7;//优先级决定计算顺序
	int d = a + b + 7;//优先级失效,结合性决定计算顺序
	printf("%d\n", c);
	printf("%d\n", d);
}

操作符一览表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值