C语言总结 操作符与表达式

这篇博客详细介绍了C语言中的操作符,包括取模的定义和不同情况下的处理,特别是负数取模的规则。还讨论了移位操作符、位运算的交换律和结合律,并解释了取地址、sizeof、指针解引用和强制类型转换等概念。最后提到了逗号表达式、下标引用、函数调用和结构成员。

你好哇,我是单字鹏。欢迎进入我的C语言总结。

本篇博客来梳理总结C语言中的操作符的作用及其它的优先级。

操作符分类:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
算术操作符  +    -   *   /   %
其中的+    -   *   / 都可以作用与整形和浮点型, %只能作用与整形
+    -   *   / 既有整形与浮点型时 会进行算术提升整形提升为浮点型,在接受结果时类型是整形接受整形部分,是浮点型就接受全部。
对于 / 操作符如果两个操作数都为整数,执行整数除法,只保留商 去除余数。而只要有浮点数执行的就是浮点数除法,得到小数。
 % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

 

% 取模的具体介绍

取模的定义:

如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r , q 为整数,且0 ≤ |r|< |d|。其中,q 被称为商,r 被称为余数。

不同的计算机语言的取模的方式是不同的,比python就跟C语言不同。但是取模的两个数都是整数那结果都是相同的,不同的是负数的取模方式

C语言的取模方式本质是取余。 

什么是取余 ?就是两数相除去商 留余数。

而C语言的取商方式是向0取整 剩下的就是余数

 

C语言负数的取模

C语言的取商的方式是向0 取整,取模套用公式给就可以知道了

负数 / 负数 (负数/负数商得正数) 

 

 

 整数/负数

 

 

 

总结取模看除法的商是以哪种方式 C语言的是向0取整

还有向正无穷大取整整 和负无穷大取整整,四舍五入取整

移位操作符  

<< 左移操作符
>> 右移操作符    
注:移位操作符的操作数只能是整数。
什么是位移操作符,移的是那个位?
前面我们总结了C语言中数据是以那种方式保存在内存中。数据最终都是要以二进制的方式保存在内存中。位移操作符改变的就是这些二进制位
<< 左移操作符
移位规则:
左边抛弃、右边补0

需要注意的是 a<<1只改变的是a数据的临时拷贝,对于a里面的数据是没有改变的。

要改变a里面的数据要在拷贝给a

 

 

右移操作符
移位规则:
首先右移运算分两种:
1. 逻辑移位
左边用0填充,右边丢弃
2. 算术移位
左边用原该值的符号位填充,右边丢弃

 前面在数据的保存中说到signed 修饰的整形有符号位 unsigned 修饰的类型没有符号位

unsigned修饰的类型的位运算符有符号位吗?

总结 unsigned修饰的整形是没有符号位的 所以直接补0。

 而且在移动的位数不能是负数,这是没有规定的。

位操作符
& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。
 整形的数据是以二进制补码的形式保存在内存中的就只有1和0 。有时候为了效率和实现多种选项功能就可以改变 这些比特位来记录不同的选项。
& 叫按位与  它可以比较数据的二进制位 的1或者0。
它的改变规则是 相同的比特位都是1 才是1 。其他都为0.
 

 

| 按位或   它的比较规则是只要为1就为1,双0才为0.
 

 

^ 按位异或  它的比较规则是 相同为0 相异为1。

1、交换律 c=a^b    a=c^b   b=c^a  这样操作过后 a与b的值就交换了 

2、结合律(即(a^b)^c == a^(b^c))

3、对于任何数x,都有x^x=0,x^0=x

 4、自反性 A ^ B ^ B = A ^  0 = A

赋值操作符 = 
=在C语言中是是赋值的意思。把数据经过运算之后赋值给其他变量。或者是把一个变量的值拷贝给其他的变量。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main()
{
	char a = 0;//变量的初始化 就是赋值
	int b = 10;
	b = a + b;//运算之后的值赋值给b
	a = b = a + b;//连续的赋值
	return 0;
}
复合赋值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
这些运算符都可以写成复合的效果
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main()
{
	int a = 10;
	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;
	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;

	return 0;
}

单目操作符
!           逻辑反操作
-           负值
+           正值
&           取地址
sizeof      操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--          前置、后置--
++          前置、后置++
*           间接访问操作符(解引用操作符)
(类型)       强制类型转换

什么叫单目操作符?
只有一个操作数或者只有一个操作的变量与之结合。
比如 -10 单独的这样现实就是负10 而a-10这个-是双目运算符有两个操作数 表示a减10
! 逻辑取反  在C语言中只有是0 才为假 其他都为真 ,负数也为真。
!0 就表示把假变成真。!与除了0之外的数都为假
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main()
{
	if (0)
	{
		printf("0为真吗?\n");
	}
	else
	{
		printf("0不为真\n");

	}

	if (!0)
	{
		printf("!0为真\n");
	}

	if (1)
	{
		printf("1为真\n");

	}
	else
	{
		printf("1不为真\n");

	}
	if (!1)
	{
		printf("!1为真\n");

	}
	else
	{
		printf("!1不为真\n");

	}
	if (-1)
	{
		printf("-1为真\n");

	}
	else
	{
		printf("-1不为真\n");

	}
	if (0.1)
	{
		printf("0.1为真\n");

	}
	else
	{
		printf("0.1不为真\n");

	}
	return 0;
}

 

 

&           取地址 它可以把变量在内存中的地址取出来

 sizeof      操作数的类型长度(以字节为单位) 它是用来求变量或者数据的内存大小的。单位字节

使用方式有 sizeof(类型)  sizeof(变量)  sizeof 变量     sizeof(表达式)

 sizeof 和 数组

sizof(数组名) 者求的是整个数组的大小。

 

~           对一个数的二进制按位取反  把数据的二进制位1变成0 0变成1
-1的二进制位都为1  0 的二进制位都为0

 

--          前置、后置--
++          前置、后置++
它是把变量的值加1后再赋值回变量。
前置++/--  

 

后置++/-- 它跟前置++/--一样都是变量自增1,但是如果表达式还有其他的运算时,他是先把a的先返回再自增。

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

它的作用是在指针变量需要访问它指向的变量时使用,就可以改变变量的内容。

(类型)       强制类型转换 

 把一个变量的类型暂时的变成其他的类型 。对变量的本省的类型是没有改变的。

关系操作符
> 大于     只有是大于才为真
>= 大于等于 大于才或者等于就为真
< 小于
<= 小于等于
!=   用于测试不相等” 相等才为假
==      用于测试相等”其他都为假

 它们双目运算符 有两个操作数(变量或者是常量),得到得结果只有真或

需要注意的是 ==不能是= 

逻辑操作符
&&     逻辑与
||          逻辑或
是一个双目运算符 它的操作数 既可以是变量,常量也可以是表达式。
&&逻辑与 它左右的表达式只有都为真整个表达式才为真,只要一个为假整个表达式都为假
&&的短路原则,&&的表达式是从左向右开始计算,只要有一个是假后面的表达式就不会在进行计算。
||逻辑或 它左右的表达式只有都为假整个表达式才为假,只要一个为真整个表达式都为真
||的短路原则,||的表达式是从左向右开始计算,只要有一个是真后面的表达式就不会在进行计算。

 

条件操作符
exp1 ? exp2 : exp3

 

逗号表达式

exp1, exp2, exp3, …expN
表示表达式从左向右开始计算,最后一个的表达式为逗号表达式的最终结果。

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

1.[ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
它的本质是 数组名是首元素的地址
数组名[10]等价于 数组名+10 就是地址+10。
2. ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
3. 访问一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名
表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
在C语言中以英文的;结尾的一串字符就是一个表达式,它的求值顺序是从左向右开始计算。
单独的一个;也是一个表达式 但是编译器可能直接省略了
表达式在求值得过程中有可能会运算符冲突 就可以使用()来强调它里面的表达式要先计算。
操作符的属性
复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
什么是结合性?
比如- 它可以表示 减法也可以是表示负数,就看它在表达式的那个位置决定的,-表示减法的时候它的结合性 就是左边的表达式结合右边的表达式进行计算,-表示为负时 他就结合右边的变量或者常量进行计算。
优先级表

表达式的错误示范
i-- - --i * ( i = -3 ) * i++ + ++i
这是一个非常错误的表达式,它没法计算它的优先级,在不同的编译器有不同的结果。
所以在写表达式时要有确定唯一的求值顺序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值