1、单目操作符
单目操作符有下面几种:
!、++、--、&(取地址)、*(指针)、+(正号)、-(负号)、~、sizeof、(类型)
其中就还有&和*操作符还没有学习过,这个我们在后面学习指针的时候会详细来讲的。
2、逗号表达式
逗号表达式就是用逗号隔开的表达式。如下所示:
exp1,exp2,exp3,.......expN
有N个表达式,然后每个表达式用逗号分隔开来。
其规律为:
每一个表达式都会进行运算,但是整个逗号表达式的结果是最后一个表达式的结果。
下面我们通过一个代码来感受一下:
看上面的逗号表达式:先进行a和b比大小,此时不会改变a,b的值,然后这个结果也不是整 个逗号表达式的结果所以也没有给c赋值,然后就是对下一个表达式运算,此时a的值就变 成了12但是也不会赋值给,然后第三个表达式a没有进行任何赋值操作而且也不是最后一 个表达式,所以还是没有对c赋值,然后最后一个表达式使得b的值为13且此时的值也就是 整个逗号表达式的值,所以此时c的值为13
逗号表达式的妙用:
如上,修改前的代码在使用循环前需要对a进行处理,然后才开始进行循环,然后在 循环体内在进行完业务出处理后又需要对a进行处理。这时我们可以在循环的判断条 件语句中使用逗号语句,然后将判断的那个语句放在逗号表达式的最后一个表达式, 然后对于a的处理的表达式放在前面,这样就可以不用在循环前对a进行操作了。而且 在循环后也还会对a处理才进行判断,也没有影响原来的逻辑。
3、下标访问呢操作符[ ]、函数调用操作符()
这两个操作符我们在前面学习数组和函数的时候已经非常熟悉了。
下标访问操作符[ ]:
其是一个双目操作符,其操作数,一个为数组名,一个为索引(下标)
下面为其使用例子:
函数调用操作符():
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数, 而且是必须有函数名这个操作数的,参数的操作数可以有也可以没有,这个看你函数需要实 现功能来决定。比如我们之前写的猜数字游戏和扫雷游戏,我们定义了个实现菜单功能的函 数,其操作数就只有函数名字了没有参数。
4、结构成员访问操作符
在这里我们先简单了解一下结构体后续还会专门学习结构体
1、结构体
c语言提供了内置类型,如:char、int、short、long、float、double等。但是实际上只有这 些内置类型还是不能满足我们的需求的,假设我要描述一个学生描述一本书,,这时候单一 的数据类型是不行的。
描述一个学生:名字、年龄、学号、身高、体重等。
描述一本书:作者、出版社、定价等。
c语言中为了解决这个问题,增加了结构体这种自己定义的数据类型,让使用者可以根据自 己的需求来定义合适的数据类型。
2、结构体的声明
使用关键字:struct 结构体名
上面为结构体的声明,成员列表则为我们需要的具体的数据了,变量列表就是可以在那边创 建结构体变量,也可以省略,但是注意:后面的分号不可以省略。下面我们定义一个学生的 结构体来看看
3、结构体变量的定义和初始化
定义:
结构体的定义有两种方法:
1、在创建结构体的时候在最后直接写出这个变量,注意后面的分号!!!
2、和定义结构体有一点类似,使用struct关键字然后加上一个名字,然后再加上这个变量的 名字。
初始化:
结构体的初始化和数组差不多,也是使用大括号。
第一个初始化就会按照结构体中的数据顺序的初始化,即第一个"zhangsan"就是name的,然 后20就是age的了,第二种就是指定初始化,这个就在要初始化的那个数据加.即可。
若结构体中的一个成员也是结构体的话:
这个时候在初始化中要对结构体中的这个结构体成员进行初始化,我们在大括号内再使用大 括号将这个结构体成员的初始化即可。
4、结构成员访问操作符
直接访问:
结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。如下所⽰:
使用方式:结构体变量.成员名
间接访问:
有的时候我们得到的不是一个结构体变量,而是得到了一个指向结构体的指针,这个时候我 们就使用间接访问的方式来访问结构体,即:(->)符号。这里我们就只做简单介绍,因为 还涉及到指针的知识。
5、操作符的属性:优先级,结合性
C语言的操作符有两个重要的属性:优先性和结合性,这两个属性决定了表达式求值的计算 顺序。
1、优先级
优先级指的是如果一个表达式包含多个运算符,那么那个运算符先执行呢。各种运算符的优先 级是不一样的。
如下所示:
3+4*5;
上面的表达式中既有加法运算又有乘法运算,由于乘法运算的优先级高于加法,所以表达式是 先计算4*5然后再计算加法。
运算符的优先级顺序很多下面为其具体情况:
• 圆括号( () )
• ⾃增运算符( ++ ),⾃减运算符( -- )
• 单⽬运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( < 、 > 等)
• 赋值运算符( = )
2、结合性
当两个运算符的优先级是一样的时候咋办呢,这个时候优先级就没有办法确定先计算谁了。
这个时候就得看结合性了,根据运算符是左结合,还是右结合,决定其执行顺序。其中大部分 运算符是左结合(从左到右执行),少数运算符是右结合(从右往左执行)例如:赋值运算符 =。
下面为运算符的优先级和结合性:
6、整型提升和算术转换
1、整型提升
C语言中整型算术运算总是至少以缺省(默认)整型数据的精度来进行的,为了获得这个精 度,表达式中的字符和整型操作数在使用之前转换为普通整型,这种转换为:整型提升。
整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字 节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型 的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度
通用CPU是难以直接实现两个8比特字节直接相加运算。所以,表达式中各种长度可能小于int 长度的整型值,都必须先转换为int或者unsigned int ,然后才能进入CPU去执行运算
如下面的运算:
这里的b和c都是char类型的数据,在进行后面的运算时候,,会先将其整型提升,提升为普 通整型int,然后在执行加法运算,在加法运算完成后 ,这个时候会有四个字节,要存入a中, 因为a也为char类型数据,所以结果要截断,从四个字节截断成1个字节,也就是将前面三个 字节去掉,然后在存储给a。那么整型提升是如何进行的呢?
整型提升的方法:
1、有符号整型提升是按照变量的数据类型的符号位来提升的,高位补符号位
2、无符号整型提升,高位补0
下面我们通过一个实例来理解:
2、算术转换
如果某个操作符的各个操作数属于不同的类型,那么我们得将其转换位同一种类型,否则操作 就无法进行。下面的层次体系为寻常算术转换
其等级由上往下降。
7、问题表达式解析
表达式1:
表达式2:
同上,操作符的优先级只能决定⾃减--的运算在+的运算的前⾯,但是我们并没有办法得知+操 作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。
表达式3:
上面的表达式在不同的编译环境下的结果是不同的。
表达式4:
上面的表达式虽然在大部分的编译器上结果是一样的。
但是对于fun()-fun()*fun();这个语句我们只能通过操作符的优先级得知:先算乘法再算减法
但是函数调用的先后顺序是没办法得知的。
表达式5:
建议:即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性 确定唯⼀的计算路径,那这个表达式就是存在潜在⻛险的,建议不要写出特别复杂的表达 式。 我们可以将其分割成几个表达式,这样对于代码的理解也更加容易,还有后期对于代 码的维护也更加容易。
标签:操作数,C语言,运算符,操作符,整型,应用,表达式,结构 From: https://blog.csdn.net/2302_81083101/article/details/143866648