(一).基础概念
一般而言,运算符需要一个或多个运算对象才能完成运算生成一个值。
只需要一个运算对象的运算符(如负号和sizeof)称为一元运算符,需要两个运算对象的运算符(如加法运算符和乘法运算符)称为二元运算符
(二).运算符
1.赋值运算符:=
(1).C使用可修改的左值标记那些可赋值的实体。
(2).赋值表达式语句的目的时把值储存到内存位置上。用于储存值的数据存储区域统称为数据对象。
(3).使用变量名是标识对象的一种方法。
(4).左值(lvalue)是C语言的术语,用于标识特定数据对象的名称或表达式。因此,对象指的是实际的数据存储,而左值是用于标志或定位存储位置的标签。
左值:对于早期C语言
1.它指定一个对象,所以引用内存中的地址;
2.它可用在赋值运算符的左侧,左值中的1源自left
3.const标识符满足上面的第一项,但是不满足第二项。
可修改的左值:用于标志可修改的对象。
赋值运算符的左侧应该是可修改的左值。(对象定位值)
(5).右值(rvalue):能赋值给可修改左值的量,且本身不是左值。右值中的r源自right
右值可以是常量、变量或其他可求值的表达式
2.在学习名称时,被称为"项"(如,赋值运算符左侧的项)的就是运算对象。
运算对象是运算符操作的对象。
3.加法运算符:+
加法运算符用于加法运算,使其两侧的值相加。
4.减法运算符:-
减法运算符用于加法运算,使其左侧的数减去右侧的数
5.+和-运算符都被称为二元运算符,即这些运算符需要两个运算对象才能完成操作。
6.符号运算符:-和+
(1).减号还可用于表明或改变一个值的代数符号。例如:rocky = -12; smokey = -rocky;以这种方式使用的负号被称为一元运算符。
(2).一元运算符只需要一个运算对象。
(3)C90新增一元运算符+,它不会改变运算对象的值或符号,只能这样使用:dozen = +12;
7.乘法运算符:*
符号*表示乘法
8.除法运算符:/
(1).符号/表示除法。/左侧的值是被除数,右侧的值是除数。
(2).C99规定使用趋零截断。
9.求模运算符:%
求模运算符用于整数运算。求模运算符给出其左侧整数除以右侧整数的余数。求模运算符只能用于整数,不能用于浮点数。
10.递增运算符:++
(1).将其运算对象递增1
(2).该运算以两种方式出现:1.++出现在其作用的变量前面,这是前缀模式; a_post = a++; 使用a的值之后,递增a
2.++出现在其作用给的变量后面,这是后缀模式。 b_pre = ++b; 使用b的值之前,递增b
递减运算符:--
将其运算对象递减1
优先级:递增运算符和递减运算符都有很高的结合优先级,只有圆括号的优先级比它们高。
11.sizeof运算符和size_t类型:
(1).sizeof运算符以字节为单位返回运算对象的大小。运算对象可以是具体的数据对象(如,变量名)或类型。如果运算对象是类型则必须用圆括号将其括起来
(2).sizeof返回size_t类型的值(无符号整数类型)。
(3).C有一个typeof机制,允许程序员为现有类型创建别名: typeof double real; real deal;
(4).%zd 转换说明用于printf()显示size_t类型的值。如果系统不支持可使用%u或%lu。
(三).运算符优先级:
() 从左往右
+ - (一元) 从右往左
* / 从左往右
+ - (二元) 从左往右
= 从右往左
(四).总结:
1.赋值运算符:
= 将其右侧的值赋给左侧的变量
2.算术运算符:
+ 将其左侧的值与右侧的值相加
- 将其左侧的值减去右侧的值
- 作为一元运算符,改变其右侧值的符号
* 将其左侧的值乘以右侧的值
/ 将其左侧的值除以右侧的值,如果两数都是整数,计算结果将被截断
% 当其左侧的值除以右侧的值时,取其余数(只能应用于整数)
++ 对其右侧的值加1(前缀模式),或对其左侧的值加1(后缀模式)
-- 对其右侧的值减1(前缀模式),或对其左侧的值减1(后缀模式)
3.其他运算符:
(1).sizeof 获得其右侧运算对象的大小(以字节为单位),运算对象可以时一个被圆括号括起来的类型说明符,如sizeof(float),或者是一个具体的变量名、数组名等,如sizeof foo
(2).(类型名) 强制类型转换运算符将其右侧的值转换成圆括号中指定的类型,如(float)9把整数9转换成浮点是9.0
(一).基本概念
1.大部分语句都以分号结尾。最常用的语句是表达式语句。
2.用花括号括起来的一条或多条语句构成了复合语句(或称为块(block))。
3.while语句是一种迭式语句,只要测试条件为真,就重复执行循环体中的语句。
4.最简单的语句是空语句。
5.函数表达式语句会引起函数调用。
(一).基本概念:
1.表达式由运算符和运对象组成。
(1).运算对象可以是常量、变量或二者的组合。一些表达式由子表达式组成(子表达式即较小的表达式)
(2).每个表达式都有一个值
2.在C语言中,每个表达式都有一个值,包括赋值表达式和比较表达式。
(二).优先级
运算符优先级规则决定了表达式中各项的求值顺序:
(1).当两个运算符共享一个运算对象时,先进行优先级高的运算。
(2).如果运算符的优先级相等,由结合律(从左往右或从右往左)决定求值顺序
1.函数表达式语句会引起函数调用。
2.带参数的函数
定义带一个参数的函数时,便在函数定义中声明了一个变量,或称为形式参数。然后,在函数调用中传入的值会被赋给这个变量。这样,在函数中就可以使用该值了。
3.变量名是函数私有的,即在函数中定义的函数名不会和别处的相同名称发生冲突
4.原型即使函数的声明,描述了函数的返回值和参数,pound(int n)函数的原型说明了两点:
(1).该函数没有返回值(函数名前面有void关键字)
(2).该函数有一个int类型的参数
(一).升级和降级:
1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int;从较小类型转换成较大类型,这些转换被称为升级
2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别
3.类型的级别从高至低依次是long double、 double、 float、 unsigned long long、 long long、 unsigned long、 long、 unsigned int、 int。例外的情况是,当long和int的大小相同时,unsigned int 比 long级别高。short和char类型已经被升级到int或unsigned int
4.在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。这个过程可能导致类型升级或降级。所谓降级,是指把一种类型转换成更低级别的
5.当作为函数参数传递时,char和short被转换成int,float被转换成double
(二).待赋值的值与目标类型不匹配时,规则如下:
1.目标类型是无符号整型,且待赋的值是整数时,额外的位将被忽略。例如,如果目标类型是8位unsigned char,待赋的值是原始值求模256
2.如果目标类型是一个有符号整型,且待赋的值是整数,结果因实现而异
3.如果目标类型是一个整型,且待赋的值是浮点数,该行为是未定义的
1.当char 和 short 类型出现在表达式里或作为函数的参数(函数原型除外)时,都会被升级为int类型;
2.float类型在函数参数中时,会被升级为double类型。
3.在k&R C(不是ANSI C)下,表达式中的float也会被升级为double类型。
4.当把一种类型的值赋给另一种类型的变量时,值将被转换成与变量的类型相同。
5.当把较大类型转换成较小类型时(如,long转换成short,或double转换成float),可能会丢失数据。
6.在混合类型的运算中,较小类型会被转换成较大类型
1.副作用是对数据对象或文件的修改。例如:states = 50; 它的副作用是将变量的值设置为50.类似调用printf()函数时,它显示的信息其实是副作用。
2.序列点是程序执行的点,在该点上,所有的副作用都在进入下一步之前发生。在C语言中,语句中的分号标记了一个序列点。意思是,在一个语句中,赋值运算符、递增运算符和递减运算符对运算对象做的改变必须在程序执行下一条语句之前完成。
(1).一个完整表达式的结束也是一个序列点。
(2).完整表达式:这个表达式不是另一个更大表达式的子表达式。例如,表达式语句中的表达式和while循环中的作为测试条件的表达式,都是完整表达式
1.C通过运算符提供多种操作。每个运算符的特性包括运算对象的数量、优先级和结合律。
2.当两个运算符共享一个运算对象时,优先级和结合律决定了先进行哪项运算。
3.每个C表达式都有一个值。如果不了解运算符的优先级和结合律,写出的表达式可能不合法或者表达式的值与预期不符。
4.虽然C允许编写混合数值类型的表达式,但是算术运算要求运算对象都是相同的类型。因此,C会进行自动类型转换。尽管如此,不要养成依赖自动类型转换的习惯,应该显式选择合适的类型或使用强制类型转换。这样,就不用担心出现不必要的自动类型转换。
原文:https://www.cnblogs.com/JingChuan-Duan/p/13128496.html