本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,文章的主题内容均来自该课程,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙
C 语言通过提供大量的运算符来支持我们对数据进行处理,例如将一个值存放到变量中,使用的是赋值运算符(=);对字符串中的某个字符进行索引,使用方括号([])作为下标运算符实现。本篇博文将主要介绍算术运算符、关系运算符和逻辑运算符这三种运算符。
算术运算符就是做加减乘除运算的运算符了,常见的运算符有如下这些
其中有三点需要注意:
(1) 整数间的除法采用的是取整的方式,而不是四舍五入的方式,如 5/3 = 1
(2) 浮点数间的除法则能获得一个相对逼近结果的值,如5.0/3.0 = 1.666667
(3) 求余运算符要求 % 两边的操作数都要是整数,其结果也是整数。
在上面的表格中有的运算符是双目运算符,有的运算符是单目运算符,那什么是 “目” 呢?如下图所示
其中的加号就是运算符,被运算符作用的运算对象称之为操作数,比如 1 + 2,那么 1 和 2 就是被加法运算符(+)作用的两个操作数。我们说一个运算符是双目运算符还是单目运算符,就是看它有多少个操作数。所以很明显,除了正负号运算符,剩下的都是单目运算符。
用运算符和括号将操作数连接起来的式子,我们称之为表达式。比如说1+2
,'a' + 'b'
,1 + 2 + -1 - 9%5
,这些都是表达式。
对于较为复杂的表达式我们应该考虑运算符的优先级和结合性,大部分的运算符和我们的认识一致,比如先乘除后加减,有括号的先算括号内的。但是也会有一些较为特殊的运算符需要我们注意下计算的顺序,这里我们给出一个参考,可以快速查看运算符号的优先级。顺便在这里我也安利下我常用的方法,很简单!就是遇到不确定的优先级直接用括号把想优先计算的括起来~
当一个运算符的几个操作数类型不同时,编译器需要将它们转换为共同的某种数据类型,才能进行运算。通常情况下,编译器会将占内存比较小的操作数,先转换为与占内存较大的操作数的相同类型,然后再进行运算。这样做的目的就是为了确保计算的精确度。
除了编译器帮你自动转换不同类型的操作数之外,C 语言还允许你强制转换操作数的数据类型。做法就是在操作数的前边用小括号将目标数据类型括起来。
第一个程序是关于运算优先级的示例
#include
#include
int main()
{
int i, j, k;
i = 1 + 2;
j = 1 + 2 * 3;
k = i + j + -1 + pow(2, 3); // 3 + 7 + (-1) + 8
printf("i = %d\n", i);
printf("j = %d\n", j);
printf("k = %d\n", k);
return 0;
}
实验结果为
i = 3
j = 7
k = 17
其中需要注意的是 -1
中的负号优先级很高,在 C 语言中排在第二优先级而我们常用的乘除排在第三优先级,加减排在第四优先级。
第二个程序是关于类型转换的示例
#include
int main()
{
printf("整型输出:%d\n", -5 / 2);
printf("整型输出:%d\n", 1 + 2.8);
printf("整型输出:%d\n", 1 + (int)2.8);
printf("整型输出:%d\n", (int)(1 +2.8));
printf("浮点型输出:%f\n", 1 + 2.0);
return 0;
}
实验结果如下图所示
从输出的第一行可以看到,整数的取整是向它的绝对值方向取整,-2.5 会取整为 -2,而 2.5 会取整为 2。
gcc 对第二个 printf
中的内容进行了警告,大概意思是说我们将一个 double 类型的变量以 int 型进行打印输出,可以看到输出的结果明显是不对的。
如果想输出 1 + 2.8 的整型形式的结果,可以先通过 (int) 2.8
强制将其转变为整型再进行相加,也可以将相加的结果直接强制转变为整型。
如下图所示,可以使用关系运算符来比较两个数的大小关系
其中同一个大括号中的关系运算符的优先级相同,上面的优先级要高于下面的优先级。用关系运算符将两边的变量、数据或表达式连接起来,称之为关系表达式,如下所示打印出每一个关系表达式的值
#include
int main()
{
int a = 5, b = 3;
printf("%d\n", 1 < 2);
printf("%d\n", a > b);
printf("%d\n", a <= 1 + b);
printf("%d\n", 'a' + 'b' <= 'c');
printf("%d\n", "ab" < "cd");
printf("%d\n", (a=3) > (b=5));
return 0;
}
当关系表达式成立的时候会返回数字 1 ,当关系表达式成立的时候会返回数字 0 。其中整型的变量和整型的常量之间进行关系运算是很好理解的,但是字符型变量是如何进行比较的呢?很简单通过字符型变量所对应的 ASCII 码。
但是倒数第二个中的字符串是如何比较大小的呢?符串比较就是从两个字符串第一个位置开始比较对应位置上的字符的ASCII码值,直到分出大小或者达到某个字符串的结尾,先到达结尾的字符串小。例如: “AC”<“B” 因为A的ASCII码值比B小,那么后面的就不在比较了 “ACA”<“ACAX” 前面三个"ACA"都相同,最后一个前面的字符串已到末尾,所以小。 [ 3 ] ^{[3]} [3]
因此实验结果如下所示
1
1
0
0
1
0
C语言总共提供了三种逻辑运算符,如下图所示
首先要注意它们之间的优先级,因为逻辑非是一种单目运算符,而剩下的两种是双目运算符,多以逻辑非的优先级最高。用逻辑运算符将两边的变量、数据或表达式连接起来,称之为逻辑表达式,如下为打印出每一个关系表达式的值
#include
int main()
{
int a = 5, b = 3;
printf("%d\n", 3 > 1 && 1 < 2);
printf("%d\n", 3 + 1 || 2 == 0);
printf("%d\n", !(a + b));
printf("%d\n", !0 + 1 < 1 || !(3 + 4));
printf("%d\n", 'a' - 'b' && 'c');
return 0;
}
通过之前文章我们知道关系运算符的优先级要高于逻辑运算符,所以第一个 printf
中的内容显然为真;在第二个 printf
中 ||
左侧的是 3+1
,实际上在 C 语言中任意非零数字都可以算作是真,所以该语句名明显应该输出 1 ;剩下的几个例子很好理解可以自行推导一下。
上面的代码执行的结果如下所示
1
1
0
0
1
短路求值又称最小化求值,是一种逻辑运算符的求值策略。只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值。C语言对于逻辑与和逻辑或采用短路求值的方式。
所以在上面给讲述的字符串的比较方法就是遵从了这个原则。另一方面,比如说在 3 > 1 && 1 < 2
只根据前半部分是没有办法判断该表达式的取值的,所以还有根据后面的运算数求值;但是对于 3 == 1 && 1 < 2
来讲,根据第一个运算数字就可以判断该逻辑表达式为假,所以后面的比较运算就不会发生。
又比如下面这个例子
#include
int main()
{
int a = 3, b = 3;
(a = 0) && (b = 5);
printf("a = %d, b = %d\n", a, b);
(a = 1) || (b = 5);
printf("a = %d, b = %d\n", a, b);
return 0;
}
它的运行结果为
a = 0, b = 3
a = 1, b = 3
这是因为执行到 a=0
的时候已经可以得到 (a = 0) && (b = 5);
所以后面的 b = 5
就不会被执行因此输出 a = 0, b = 3
;下面的同样当执行到 a = 1
就已经的到了 (a = 1) || (b = 5)
的值,所以仍然不会执行 b = 5
,打印输出 a = 1, b = 3
。所以在采用逻辑运算表达式的时候一定要考虑清楚在逻辑运算符的左右应该分别放什么。
[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P9
[2] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P10
[3] 百度知道 《C语言中比较字符串大小的判断标准是什么?》