目录
✨前言💦
操作符➕➖
1.算数操作符🔢
2.移位操作符⬅️
3.位操作符🔝
4.赋值操作符💹
5.单目操作符🌛
6.关系操作符💑
7.逻辑操作符🎰
8.条件操作符🆗
9.逗号操作符💭
10.下标引用、函数调用和结构成员🔛
✨前言💦
实在是抱歉,最近因为自己偷懒,拖更了两周。前几天上线无意间看到一位老铁对我之前发布文章的肯定,我深受感动,决定从此不再拖更,认真写好每一篇博客。目前任务就是先把初识系列写完。上次最后讲到了数组,接下来就该操作符了。
操作符➕➖
C语言包含了非常丰富地操作符,所以有人说:C语言是非常灵活的。甚至可以直接操作内存的数据——直接操作二进制位!C语言中都有哪些操作符呢?
1.算数操作符🔢
+ - * / %
前边的 + - * 都比较简单,这里主要说一下 / 和 %。
先说一下 / 运算符:
a / b a 除以 b 所得到的商(整数之间运算的时候需要舍弃小数点之后的值)
括号里的内容怎么理解呢?比如我们来求一下 9 / 2 的值:
诶?编译器出故障了吗?为什么是 4 不是 4.5 呢?
这就是因为咱进行的是整数间的运算,所以结果舍弃掉了小数点之后的部分。那我们要怎样才能算出来 4.5 呢?这就需要 / 两边至少要有一个小数值。就像这样:
接下来讲 % 运算符:
a % b a 除以 b 所得到的余数(a 和 b 都必须是整数)
% 就是我们口中的取模操作符,是用来求余数的, % 只能作用于整数,% 只能作用于整数,% 只能作用于整数,重要的事情说三遍,给大家举个简单的小例子,比如求 7 % 2,再比如求 2 % 4:
如果看到这里大家对取模操作符有了那么一点了解的话,大家可以再想一想如何编写一个程序用取模操作符来判断一个数是否为偶数呢?(先想一想再往下看)
代码来啦:
2.移位操作符⬅️
>> <<
移位运算符可以通过讲位向左或向右移动来变换整数的二进制表示。C语言提供了两个位移运算符:<<运算符 和 >>运算符。因为是初识系列,所以今天只拿左移操作符给大家举个栗子,让大家了解一下移位操作符。比如求一下 3 << 1 的值。
<<运算符 a << b 将 a 左移 b 位,右面空出的位用 0 补充
这里先画出流程图帮大家理解:
这里因为 3 是整形,占 4 个字节,所以是 32 个比特位,将 3 的二进制位向左移动一个比特位后,第一个 0 被移除,后边接着补上一个 0 ,就得到了 3 << 1 的比特位,换算成 10 进制就是 6,下面我们编写程序验证下结果是否跟我们想的一样:
果然没有问题,既然如此,点到为止~
3.位操作符🔝
& | ^
咱首先来了解下逻辑与、逻辑或和逻辑异或:
进行这些逻辑运算的运算符如下:
按位与运算符 a & b 按(二进制)位计算 a 和 b 的逻辑与
按位或运算符 a | b 按(二进制)位计算 a 和 b 的逻辑或
按位异或运算符 a ^ b 按(二进制)位计算 a 和 b 的逻辑异或
那接下来就举个例子方便大家理解吧,就比如求一下 3 & 5 的值
按照上边两者都为 1 结果才为 1 的原则,3 & 5后的得到的值是 1 ,编写代码验证一下咱的结果:
果然没有问题,那大家现在是不是可以自己算出来 3 | 5 、3 ^ 5 的值了呢?算完可以对着下面验证一下:
是否跟大家思考出来的结果一样呢?是不是非常简单呀,既然如此,点到为止,咱接着往下探索
4.赋值操作符💹
= += -= *= /= &= ^= |= >>= <<=
这里边第一个是赋值操作符,后边的准确来说应该叫复合赋值操作符,这一部分就很好理解了,给大家写几行代码方便大家理解
那么后边的 -= 、*= 、/= 、&= .......当然是一样的效果啦。
5.单目操作符🌛
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
++ 前置、后置++
-- 前置、后置--
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
讲到这之前,我们用到的操作符符都需要两个操作数,这样的操作符成为双目操作符,在C语言中,还有只需要一个操作数的单目操作符,以及需要三个操作数的三目操作符(等下会讲到)。
先说 !, 带大家做一个小实践吧,做之前再提一下之前说到的一个小知识点:C语言中 0 表示假,非 0 表示真。看这样一串代码:
#include <stdio.h>
int main()
{
int a = 10;
printf("%d\n", !a);
int b = 0;
printf("%f\n", !b);
return 0;
}
a 的值为 10,非 0 为真,但是要打印 !a,那不就是为假了,所以打印结果应该为 0 ;b 的值为 0;0 为假,但是要打印 !b ,那就是为真了,但是非 0 为真,非 0 的数那么多,到底要打印谁呢?这里就不得不提一下了,C语言已经规定了,0 为假的时候,!0 打印出来的结果就是 1 。既然是规定,咱就得遵从啊,好了,打印出来看一下结果:
下面的 + - 就没什么难度了,不要告诉我你不李姐,我不信,直接上码:
下边的 & ---取地址操作符放在下次指针内容里给大家介绍,咱直接来讲 sizeof ,这里大家千万不要把它当成一个函数了啊,sizeof 是一个单目操作符,看过我之前文章的小伙伴应该很熟悉这个操作符,第一章里我用它算了七种数据类型的大小。这里就要给大家详细说下它的作用了:sizeof 计算的是变量或者类型所创建变量占据内存的大小(单位是字节)。咱这里直接用一下,比如用 int 创建一个变量 a 求一下 a 占据内存大小,再用 char 创建一个字符 ' w ' 求一下 ‘ w ' 占据内存大小。
没毛病~要是有小伙伴对各种类型大小不了解的话,可以点这里(各种类型大小计算 )看一下第一章的内容。或者 sizeof 都给了嘛,可以自己动手算出来了。当然 sizeof 内容还有很多,不过我们现在学到这就可以啦,后续初识系列讲完后会给大家详细介绍的。
在接下来就到了 ~ ——按位(二进制位)取反。这个操作符比较麻烦,接下来我给大家演示下对 -1 按位取反,看不懂没有关系,大家了解一下,后面会出文章仔细讲解的。-1 是负整数,负整数的二进制有原码、反码、补码,内存中存储的是二进制的补码:
由上图可以看出对 - 1 进行按位取反得到的结果是 0 ,我们写代码验证一下:
然后就该讲 ++ 和 -- 了, ++ 分前置 ++ 和后置 ++ ,前置 ++ 就是先 ++ 再使用,后置 ++ 就是先使用再 ++ ,-- 也是如此,用语言描述又点抽象,我们用代码来帮助大家理解:
有了上面这些图和注释大家应该很容易理解了吧,然后下面的解引用操作符我们放到指针那一节讲。我们直接来讲下面的 (类型)——强制类型转换操作符。这个很容易理解,直接举个例子大家就明白了,比如咱将一个浮点数 3.14 放到整形 int 里边会发生什么呢?
可以看到,报了一个警告,从 double 到 int 可能丢失数据 。那这里我们怎么办呢?很简单,给 3.14 加上一个强制类型转换操作符——( int )就可以解决了: 这下就没有警告了。 那强制类型转换就说到这里,我们继续下边内容。
6.关系操作符💑
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
这一部分没什么难度,唯一要注意的就是判断相等时要用 == 不要用成 = 。初学者很容易在这里踩坑。
7.逻辑操作符🎰
&& 逻辑与
|| 逻辑或
逻辑与通俗地讲就是并且的意思,逻辑或通俗地讲就是或者的意思。
exp1 && exp2 :如果 exp1 和 exp2 都是真的,那么整个表达式的值也是真的,如果两个表达式中任何一个表达式的值为假,那么整个表达式的值便为假。
exp1 || exp2:如果 exp1 和 exp2 其中一个表达式(或者 exp1 和 exp2两个表达式)是真的,那么整个表达式的值就是真的,如果两个表达式的值都为假,那么整个表达式的值便为假。
例如下面这个例子:
8.条件操作符🆗
exp1 ? exp2 : exp3
条件操操作符接受三个操作数,它的用法就是 exp1 ? exp2 :exp3
首先计算的时 exp1,如果它的值为真,那么整个表达式的值就是 exp2 的值,exp3 不会进行求值。但是,如果 exp1 的值是假,那么整个条件语句的值就是 exp3 的值,exp2 不会进行求值。
如果小伙伴觉得只看文字理解条件操作符工作过程比较困难的话,我们不妨试一试以代码的形式对它进行展示:
a > 5 ? b - 6 : c / 2
此代码可以读作“ a 是不是大于 5 ?如果是,就执行 b - 6 ,否则执行 c / 2 ”。
什么时候要用到条件操作符呢?比如我们想简化 if 语句的时候:
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
int max = 0;
scanf("%d %d", &a, &b);
if (a > b)
max = a;
else
max = b;
printf("max = %d\n", max);
return 0;
}
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
int max = 0;
scanf("%d %d", &a, &b);
max = (a > b ? a : b);
printf("max = %d\n", max);
return 0;
}
测试一下上述代码运行结果完全相同。但上边的表达式要书写更多的 max = 。当然,这没什么大不了,在这种场合下使用条件操作符并无优势可言。但是,大家可以看下面两段代码:
if ( a > b )
b[ 2 * c + d( e / 5 ) ] = 3;
else
b[ 2 * c + d( e / 5 ) ] = -3;
在这里长长的下标表达式要写两次,很令人讨厌, 如果使用条件操作符,看上去就清楚得多:
b[ 2 * c + d(e / 5) ] = ( a > b ? 3 : -3 );
在这个例子里使用条件操作优势就很明显了,一旦大家习惯了条件操作符,大家就会像理解 if 语句那样轻松看懂这类语句的。
9.逗号操作符💭
exp1 , exp2 , exp3 , … expn
逗号操作符用于将两个或多个表达式分隔开来。这些表达式自左向右逐个进行求值,整个逗号表达式的值就是最后那个表达式的值。请看下面的代码:
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 10;
int d = (a + 2, b = a - 3, c = b + 4);
printf("d = %d\n", d);
return 0;
}
我们简单分析一下,首先括号里的 a + 2 毫无意义,然后 b = a - 3 就是将 a - 3 的值也就是 0 赋给 b ,再接着 c = b + 4 即将 b + 4 的值也就是 0 + 4赋给 c ,那么逗号表达式中最后一个表达式的值就是 4 ,因此整个逗号表达式的结果就是 4 ,让我们来验证一下:
10.下标引用、函数调用和结构成员🔛
[ ] ( ) . ->
首先介绍下标引用操作符 —— [ ] ,下标引用操作符接受两个操作数:一个数组名和一个索引值。比如 arr[5] 就代表名为 arr 的数组中下标为 5 的元素,它的一个操作数是数组名 arr ,另一个操作数便是索引值 5 ,请看下边的代码:
#include <stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("%d\n", arr[5]);
return 0;
}
我们要打印 arr 数组中下标为 5 的元素,所以我们用用 arr[5] 表示,arr 数组中下标为 5 的元素是 6 ,那我们打印结果就是 6 。
接着讲一下函数调用操作符 —— ( ) ,函数调用操作符接受一个或多个操作数。它的第一个操作数希望调用的函数名,剩余的操作数就是传递给函数的参数。比如拿上次讲函数章节用到的代码举例:
#include <stdio.h>
int Add(int x, int y)//定义函数
{
int z = x + y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
scanf("%d %d", &num1, &num2);//输入
sum = Add(num1, num2);//用函数(Add)求和
printf("sum = %d\n", sum);
return 0;
}
其中的 Add(num1, num2) 便用到了函数调用操作符,它的参数为 Add,num1 和 num2 。把函数调用以操作符的方式实现,意味着“表达式”可以代替“常量”作为函数名,事实也确实如此。
. 和 -> 操作符用于访问一个结构体的成员。如果 s 是个结构体变量,那么 s.a 就访问 s 中名叫 a 的成员。如果有一个指向结构体的指针而不是结构本身,且欲访问它的成员,就需要用 -> 操作符而不是 . 操作符。这两个操作符只是提前给大家提一下,大家不理解没有关系,后面讲到指针和结构体的时候会给大家介绍这些内容的,到时候大家一定可以看明白。
💖关于初识操作符的内容就到此结束啦,感谢大家的阅读~希望文章内用能对初学C语言的小伙伴有所帮助,如果阅读过程中发现有错误地方还恳请大家帮忙斧正。再一次谢谢大家支持!!!本期内容到此结束,下期见~