操作符用来操作操作数以下是4个双目操作符(两个操作数)和1个单目操作符(一个操作数)
目录
1、算数操作符:
+(加) -(减) *(成) /(除) %(取余)
2、移动操作符:
(右移)>> << (左移)
3、位操作符:
& 按位与(相同为1,相异为0)
| 按位或(相异为1.相同也为1)
^ 按位异或(相同为0,相异为1)
4、符合赋值操作符:数字间的比较操作符
=(等于)
+=(……)
*=
/=
^=
|=
>>=
<<=
5、单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型)强制类型转换
5.1、sizeof - 在计数数组和字节时规律:
5.2、(~ )对一个数的二进制按位取反的取法:
(~)按(二进制)位取法,把二进制中数字,1变成0,0变成1
当整数变量a=0,转换为二进制是4字节,1个字节=8个比特位
用二进制表示 :00000000 00000000 00000000 00000000(源码)
用(~)取反后
用二进制表示 : 11111111 11111111 11111111 11111111(补码)
通过取反而将补码→转化为反码→转化为源码= -1。
公式:a=0 := ~ a= -1
整数在内存中储存的是补码:
一个整数的二进制表示有3种:
源码
反码
补码
整数 :-1 (负数表达形式)
10000000 00000000 00000000 00000001 (源码)
11111111 11111111 11111111 11111110 (反码)
11111111 11111111 11111111 11111111 (补码)
开始的1是符号位,后面的是有效位
由此可以看出来正整数和负整数的源码、反码、补码 相同 。
通过以上图片可以看出来正数是以0为开头,负数是以-1开头。
5.3、前置++、-- 和 后置++、--
--前置 ——先--,后使用
(在赋值时先自己减值,后把减掉的值赋值到变量中)
后置-- ——先使用,后--
(先使用操作符前的变量,然后通过操作符运算把后置++变量值赋值到存放变量的变量中)
++前置 ——先++,后使用
后置++ ——先使用,后++
int main()
{
int a = 10;
int x = ++a;
//先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。
int y = --a;
//先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;
return 0;
}
#include <stdio.h>
int main()
{
int a = 10;
int x = a++;
//先对a先使用,再增加,这样x的值是10;之后a变成11;
int y = a--;
//先对a先使用,再自减,这样y的值是11;之后a变成10;
return 0;
}
5.4、强制类型转换
在变量、常量前用()填入需要强制转换的数据类型;如下所示的一样3.14是浮点数,通过强制转化成一个(int)整数
int tert = (int)3.14; //这就是强制类型转换
6、逻辑操作符:
&&(与):
当两个表达式均为非0时,求值结果为1;其他情况(只要有至少一个表达式为0),求值结果为0
| |(或):
当两个表达式均为0时,求值结果为0;其他情况(只要有至少一个表达式为非0),求值结果为1
!(非):
如果原表达式为0,则求值后结果为1;如果原表达式结果为非0,则求值后结果为0
前两者是二元运算符,逻辑非是一元运算符
与(&&)、或(||)、非(!)。其中,与运算符表示两个条件都成立时才为真,或运算符表示两个条件中有一个成立时就为真,非运算符表示条件取反。这些逻辑运算符经常用于条件判断和流程控制。
7、三目表达符: : ?
条件操作符(conditional operator)是唯一的三元操作符,它允许将简单的if-else判断语句嵌入表达式中.条件操作符的语法格式为:
exp ? exp1 : exp2;
其中,exp是一个条件判断表达式.条件操作符首先计算exp的值,
如果exp的值为0,则条件为false;
如果exp非0,则条件为true;
无论如何,exp总是要被计算的.然后,
条件为true时计算exp1,否则计算exp2,
总结:
exp=1=TRUE,计算exp1。
exp=0=FAISE,计算exp2。
和逻辑与、逻辑非(&&和||)操作符一样,条件操作符保证了上述操作数的求解次序,expr1和expr2只有一个表达式被计算
8、逗号表达式 ,
逗号表达式,是从左向右依次计数的,整个表达式的结果是最后一个表达式的结果。如:
int main()
{
int a;
int b=3;
int c=5;
// a=5 c=1 b=3
int d=(a = b + 2, c = a - 4, b = c + 2);
printf("%d\n",d);
return 0;
}
9、下标引用、函数调用、结构成员的表达式
下标引用:[ ]
数组的下标是由0开头的,如tert[10]={1,2,3,4,5,6,7,8,9,10,}对应元素是0,1,2,3,4,5,6,7,8,9。
在需要使用数组tert[10]中的元素时,就可以使用 [ ] 来引用,如图所示:
函数调用:()
调用函数的时候,函数名后边的()就是函数调用操作符,如下所示:
printf ( " %d\n " ) ;
结构成员:->
10、操作符的属性
复杂表达式的求值有三个影响的因素
1、操作符的优先级
在C语言中,操作符的优先级决定了表达式中各个操作符的计算顺序。以下是C语言中常见操作符的优先级从高到低的顺序:
- ():括号,用于改变操作符的优先级。
- []:数组下标,用于访问数组元素。
- ->:结构体指针成员访问。
- .:结构体成员访问。
- ++、--:自增和自减。
- !、~:逻辑非和按位取反。
- *、/、%:乘法、除法和取模。
- +、-:加法和减法。
- <<、>>:左移和右移。
- <、<=、>、>=:小于、小于等于、大于、大于等于。
- ==、!=:等于和不等于。
- &:按位与。
- ^:按位异或。
- |:按位或。
- &&:逻辑与。
- ||:逻辑或。
- ?::条件运算符。
- =、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=:赋值和复合赋值运算符。
- ,:逗号运算符,用于分隔表达式
2、操作符的结合性
- 在C语言中,操作符的结合性指的是当一个表达式中有多个相同优先级的操作符时,它们的计算顺序是从左到右还是从右到左。
- 大部分操作符都是从左到右结合的,这意味着它们在表达式中按照从左到右的顺序进行计算
3、是否控制求值循序
- C语言中的操作符可以分为两类:具有固定求值顺序的操作符和没有固定求值顺序的操作符。
- 具有固定求值顺序的操作符包括逻辑与(&&)、逻辑或(||)、条件运算符(?:)和逗号运算符(,)。这些操作符具有短路求值的特性,即只有在必要的情况下才会对操作数进行求值。例如,对于逻辑与操作符(&&),如果左侧的操作数为假,则右侧的操作数不会被求值。
- 没有固定求值顺序的操作符包括算术运算符(+、-、*、/等)和位运算符(&、|、^等)。对于这些操作符,C语言标准没有规定它们的求值顺序,编译器可以按照自己的实现来确定求值顺序。因此,在表达式中使用这些操作符时,不能依赖于操作数的求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性、操作符优先级
11、如图所示,常见关键字
aotu :自动的;自动创建,自动摧毁的 - 自动变量的局部变量,原本要定义的,但在局部变量里局部变量本身就是自动创建的局部变量所以不需要在定义了,可以省略(在C语言新的语法里还是有其他用法的)
break:用来控制循环结构的,主要作用是停止循环(9条消息) break和continue的作用和区别是什么?(详细解答)_手可摘☆辰的博客-CSDN博客
char:字符类型
corst:长变量
dodle:双精度
extern:用来声明外部符号的;也就是说可以在同一工程内,不同文件之间声明符号(只需要声明类型和符号,不需要声明数值)
register:寄存器关键字,启到了建议的做用,具体的还用看编辑器;大量/频繁被使用的数据,想放在寄存器中,提高效率(现在的编辑器已经是很智能的了,会根据具体的需要来自行调用寄存器)
return:返回值
short:短整型
signed:有符号的
unsigned:无符号的
stagic:静态的
struct:结构体关键字
typedef:类型定义
union:联合体(公用体)
void:无/空
typedef:类型重定义或类型重命名(我推测用于,需要多数类型定义的场合)
static:静态的;修饰局部、全部变量和函数
补充内容:static
static与局部变量
如图所示:添加了static后,静态变量建立a的生命周期变长了,不会第一次循环后数值就销毁,数值会随着数值的++而++,直到循环结束。
由此可以得出结论:static修饰局部变量,改变了局部变量的生命周期(本质是改变了变量的储存类型)
static与全局变量
同一个工程内不同文件之间的数据调动声明必须得是(动态的=外部链接属性),如果使用了static导致变量成为了(静态的=内部链接属性)变量那么就会像上图所示一样报错;static修饰全局变量,使得这个全局变量只能在自己所在的原文件(,c)内部使用。
static与函数
如图所示:static修饰函数,使得函数只能在自己所在的原文件内部使用,不能在其他源文件内部使用
由此可以得出结论:本质上static是将函数的外部链接属性变成了内部链接属性(static修饰全局变量一样)
从以上三个举例可以看得出,局部变量、函数所在的栈区转存到静态区,而全局变量则是改动连接属性
注:内存基本划分的区域:
补充说明: