题记:本篇是学习了李明杰老师的C语言的“基本运算”教程之后撰写的,包括算术运算符、赋值运算、自增自减运算符、sizeof、关系运算符、逻辑运算符、三目运算符的介绍和基本使用。有些太基础的东西我在这里就不花太多篇幅介绍,着重点放在一些比较重要的地方,比如说++i和i++的区别,C语言区别与其他高级语言的条件“真”“假”判别等。
一、算术运算符
C语言作为一种历史悠久的一门优秀的编程语言,那么它必然是要与计算机打交道的,但是联想到计算机与数学,算法与数学相关的特性,我们就不难发现C语言与数学一定是有着非常紧密的联系。C语言有34中运算符,包括了常见的加减乘除运算。
1、加法运算 +
这是数学中很常见的运算符号了,1 + 2,结果就是3,这与数学上的通常运算一样。当然,+ 还能表示正号,也就是正数与负数的概念,例如:+5,+20。
2、减法运算 -
与加法运算符类似,减法运算符与数学上的概念是一样的,4 - 3 的结果就是1,同样的它也能表示负数,例如:-3, -10。
3、乘法运算 *
与通常数学意义上的“x"是一个意思,但要注意的是它的书写方式,是”*“而非”x“。
4、除法运算 /
a).符号的区别,数学中的除法运算符是÷,而在C语言中是/,也不是\,通常后两个容易混淆。
b).运算结果与数学上的除法有些区别,而且一定要特别注意,例如:
int a = 3;
int b = 2;
//我们输出 a/b, b/a的值
printf("a/b = %d, b/a = %d\n", a/b, b/a);
输出结果为:
a/b = 1, b/a = 0
分析:我们先要明白C语言中的一个规则,两个整形int相除结果必然是整型,在数学上3除以2的结果是1.5,但是由于前面的规则,所以就会将1.5的小数部分丢弃,转化成整形的1,故a/b的结果是1。同理,b/a在数学上的结果应该是.666无限循环,但是在C语言中将它转换成整形后就是0了。
但是如果是浮点型的值进行运算,就能得到与数学中相似的期待值,这个挺简单的,这里就不做演示了。
5、取余运算 %
在数学中表示的是余数,比如说8%2的值就是0,8%3的值就是2。
a).要特别注意的是取余的运算操作只能是具有整形类型的变量才能进行,如int,long等,而float、double等就不行。
b).另外一点需要注意的是如果取余运算符%两边中带有负号“-”,则余数的正负号取决于除数,而与被除数无关,例如:
#include <stdio.h>
int main (int argc, const char *argv[])
{
int a = -10;
int A = 10;
int b = -3;
int B = 3;
//我们来计算a%b, a%B, A%b, A%B的值
printf("a%%b = %d, a%%B = %d, A%%b = %d, A%%B = %d\n", a%b, a%B, A%b, A%B);
return 0;
}
编译运行之后得到结果:
a%b = -1, a%B = -1, A%b = 1, A%B = 1
分析及总结:由上面的结果都能证明“余数的正负号取决于除数,而与被除数无关”的总结,这里给大家一个技巧,C语言中取余运算,我们先将%两边的值都看做整数,这样取余就简单很多,最后将除数的正负号附加到所得的余数上。6、注意点
a).自动类型转换,自动将大类型转换为了小类型,会丢失精度
int a = 10.6; // a的实际值为10
int b = 10.5 + 1.7; // b的实际值为12
b).自动类型提升
int b = 10.5 + 10; // a的实际值为20
double b = 1.0 / 2; // 将右边的10提升为了double类型,解决除法的精度问题
c).强制类型转换
double a = (double)1 / 2; // a的值还是0.500000
double b = (double)(1 / 2); // b的值还是0.000000
d).运算顺序
表达式
结合性(结合方向):2+3+4
优先级:5+4*8-3
二、赋值运算
赋值运算要注意的就是:在C语言中,“=”代表的是赋值运算,而不是数学里面的普通意义的等于号!C语言中的等于号应该是“==”,下文再论述。
另外还有一个复合赋值,主要是跟一下几个符号联系在一起:+=、-=、*=、/=等,示例:
a += 3; // 等价于 a = a + 3;,所以该行执行完后a的值为5
a -= 1; // 等价于 a = a - 1;,所以该行执行完后a的值为4
a *= 2; //等价于 a = a * 2;,所以该行执行完后a的值为8
a /= 4; // 等价于 a = a / 4;,所以该行执行完后a的值为2
三、自增与自减 ++ --
++的意义等同于a = a + 1,--的意义等同于a = a - 1。但是++和--都有两种形式:前缀和后缀,下面分别叙述两个的不同
++:以a++和a--为例:
a++,它会先返回自己原来的值,然后再自增,而++a却是先自增,然后再返回
int a = 3;
int b = a++;<span style="white-space:pre"> // 先返回a的值,所以b的值是3,然后a再自增1,所以a的值是4
a = 3;<span style="white-space:pre"> // 此处a的值又重置为3
int c = ++a;<span style="white-space:pre"> // 此处先将a自增1,所以a的值是4,然后再将a赋值到c,故c的值也是4
--:与++类似,以a--和--a为例:
int a = 3;
int b = a--; // 先返回a的值,所以b的值是3,然后a再自减1,所以a的值是2
a = 3; // 此处a的值又重置为3
int c = --a; // 此处先将a自减1,所以a的值是2,然后再将a赋值到c,故c的值也是2
四、sizeof
它的作用是:用来计算一个变量或者一个常量、一种数据类型所占的内存字节数。
基本的使用方式是:
sizeof( 变量\常量 )
sizeof 变量\常量
sizeof( 数据类型 )
不能是sizeof 数据类型
五、关系运算符(比较运算符)
1、条件判断
a).默认情况下,我们在程序中写的每一句正确代码都会被执行。但很多时候,我们想在某个条件成立的情况下才执行某一段代码。b).对于微信的登录或者是注册,这种情况的话可以使用条件语句来完成,但是我们暂时不学习条件语句,先来看一些更基础的知识:如何判断一个条件成不成立。
2、真假
a).在C语言中,条件成立称为“真”,条件不成立称为“假”,因此,判断条件是否成立,就是判断条件的“真假”。
b).怎么判断真假呢?C语言规定,任何数值都有真假性,任何非0值都为“真”,只有0才为“假”。也就是说,108、-18、4.5、-10.5等都是“真”,0则是“假”。
3、关系比较
a).开发中经常要比较,比如斗地主游戏中牌的大小。利用关系运算符就可以比较两个值的大小。
b).关系运算符的运算结果只有2种:如果条件成立,结果就为1,也就是“真”;如果条件不成立,结果就为0,也就是“假”。
4、使用注意
a).关系运算符中==、!=的优先级相等,<、<=、>、>=的优先级相等,且前者的优先级低于后者:2==3>1
b).关系运算符的结合方向为“从左往右”: 4>3>2
c).关系运算符的优先级小于算术运算符:3+4>8-2
六、逻辑运算
1、逻辑与&&
2、逻辑或 ||
“条件A || 条件B”
b).运算结果
当条件A或条件B只要有一个成立时(也包括条件A和条件B都成立),结果就为1,也就是“真”;只有当条件A和条件B都不成立时,结果才为0,也就是“假”。
c).运算过程
总是先判断条件A是否成立
如果条件A成立,就不会再去判断条件B是否成立:因为条件A已经成立了,不管条件B如何,“条件A || 条件B”的结果肯定是1,也就是“真”
如果条件A不成立,接着再判断条件B是否成立:如果条件B成立,“条件A || 条件B”的结果就为1,即“真”,如果条件B不成立,结果就为0,即“假”
d).举例
逻辑或的结合方向是“自左至右”。比如表达式 (a<3) || (a>5)
若a的值是4:先判断a<3,不成立;再判断a>5,也不成立。因此结果为0
若a的值是2:先判断a<3,成立,停止判断。因此结果为1
因此,如果a的值在(-∞, 3)或者(5, +∞)范围内,结果就为1;否则,结果就为0
e).注意
C语言规定:任何非0值都为“真”,只有0才为“假”。因此逻辑或也适用于数值。比如 5 || 4的结果是1,为“真”;-6 || 0的结果是1,为“真”;0 || 0的结果是0,为“假”
3、逻辑非 !
“! 条件A”
b).运算结果
其实就是对条件A进行取反:若条件A成立,结果就为0,即“假”;若条件A不成立,结果就为1,即“真”。也就是说:真的变假,假的变真。
c).举例
逻辑非的结合方向是“自右至左”。比如表达式 ! (a>5)
若a的值是6:先判断a>5,成立,再取反之后的结果为0
若a的值是2:先判断a>3,不成立,再取反之后的结果为1
因此,如果a的值大于5,结果就为0;否则,结果就为1
d).注意
可以多次连续使用逻辑非运算符:!(4>2)结果为0,是“假”,!!(4>2)结果为1,是“真”,!!!(4>2)结果为0,是“假”
C语言规定:任何非0值都为“真”,只有0才为“假”。因此,对非0值进行逻辑非!运算的结果都是0,对0值进行逻辑非!运算的结果为1。!5、!6.7、!-9的结果都为0,!0的结果为1
e).优先级
逻辑运算符的优先级顺序为: 小括号() > 负号 - > ! > 算术运算符 > 关系运算符 > && > ||
表达式!(3>5) || (2<4) && (6<1) :先计算 !(3>5)、(2<4)、(6<1),结果为1,式子变为1 || 1 && 0,再计算1 && 0,式子变为1 || 0,最后的结果为1
表达式3+2<5||6>3 等价于 ((3+2) < 5) || (6>3),结果为1
表达式4>3 && !-5>2 等价于 (4>3) && ((!(-5)) > 2) ,结果为0
七、三目运算符 ? :
<表达式1>?<表达式2>:<表达式3>; "?"运算符的含义是: 先求表达式1的值, 如果为真, 则执行表达式2,并返回表达式2的结果 ; 如果表达式1的值为假, 则执行表达式3 ,并返回表达式3的结果。
示例:
#include <stdio.h>
int main (int argc, const char *argv[])
{
// 求两个数的最大值,并将其赋值到另个变量
int a = 3;
int b = 4;
int maxAB = (a > b) ? a : b; // 返回a和b的最大值,将其赋值给maxAB
// 求三个数的最大值,并将其赋值到另一个变量
int c = 3;
int d = 10;
int e = 20;
int maxCD = (c > d) ? c : d; // 返回c和d的最大值,将其赋值给maxCD
int maxCDE = (maxCD > e) ? maxCD : e; // 返回maxCD和e当中的最大值,也就是c、d、e中的最大值
return 0;
}