C语言初阶——4.操作符详解

        之前的那两个游戏已经写完了,那下面继续我们C语言相关知识的学习,接下来这篇介绍的就是C语言中的一些操作符,这些操作符虽然“不起眼”,但是却有大用途,学好它们才是我们应该做的,那废话不多说,接下来就开始今天的学习吧。


目录

操作符分类

1.算术操作符

2. 移位操作符

        2.1 左移操作符

         2.2 右移操作符

3. 位操作符

4. 赋值操作符

        4.1 复合赋值符

5. 单目操作符

6. 关系操作符

7. 逻辑操作符

8. 条件操作符

9. 逗号表达式

10. 下标引用、函数调用和结构成员

11. 表达式求值

        11.1 隐式类型转换

        11.2 算术转换

        11.3 操作符的属性

 结语:


操作符分类

操作符包括:

  1. 算术操作符
  2. 移位操作符
  3. 位操作符
  4. 赋值操作符
  5. 单目操作符
  6. 关系操作符
  7. 逻辑操作符
  8. 条件操作符
  9. 逗号表达式
  10. 下标引用、函数调用和结构成员

1.算术操作符

+    -    *    /    %

算术操作符就包括上面这几种:加、减、乘、除和取余。

        这几个操作符中,加减乘没什么好说的,和正常的算数一样,但是这里的除就要注意了,它是否还是原来的除?

按照正常的算数来说,2除3结果应该是0.6 6的循环,但结果真的是这样吗?

最后的结果得0,有人就要说了,这个结果应该是一个浮点数,那把%d换成%f我们再来看一下结果。

 

很遗憾,这里也不是想要的0.666666,那是为什么呢?因为a、b两个变量是整型,这里进行的是整形的运算。那要是就想打印一个浮点数呢?这里只需要把运算符两边的任意一个数强制类型转化成浮点数,简单来说就是左右必须有一个浮点数。

还有另一种写法:

这里虽然打印的不是我们想要的,那是因为float的精度没有那么高,但是不影响,我们只需要知道这个操作符如何去使用,避免产生一些错误。

我们继续讨论一下 ' / ' :

结果因该是4.5,但最后却是4,这里的整形计算并不会自动四舍五入,和取余结合一下,可以看出 ' / ' 只计算得出商的部分,得到一个整型。

 那总结一下:

1. 除了 ' % ' 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 ' / ' 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. ' % ' 操作符的两个操作数必须为整数。返回的是整除之后的余数。


2. 移位操作符

<< 左移操作符
>> 右移操作符
注意:移位操作符的操作数只能是整数。

接下来这些操作符都会涉及到二进制的相关内容。

        2.1 左移操作符

移位操作符并没有改变原来 a 的值。

这里为什么b的结果是20呢?

         2.2 右移操作符

移位规则:
首先右移运算分两种:
1. 逻辑移位
左边用0填充,右边丢弃
2. 算术移位
左边用原该值的符号位填充,右边丢弃

 

 

注意:对于移位运算符,不要移动负数位,这个是标准未定义的。
如:

    int num = 10;
    num >> -1;


3. 位操作符

位操作符分为:

//按(二进制)位与

|    //按(二进制)位或

^   //按(二进制)位异或

注:他们的操作数必须是整数。

&  按位与

|  按位与

 ^  按位异或

使用操作符还可以实现无中间变量交换两个变量:

这样写a和b就交换过来了 


4. 赋值操作符

赋值,顾名思义就是给个值呗

int a = 10;
a = 2;

这里的 “=” 可不是算术中的等于,它的意思是赋值。

        4.1 复合赋值符

+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^

举一个例子:+=

x = x + 10; 等价于 x += 10;


5. 单目操作符

!            逻辑反操作符

-               负值

+              正值

&              取地址

sizeof       操作数的类型长度(以字节为单位)

~              对一个数的二进制按位取反

--              前置、后置--

++            前置、后置++

*               间接访问操作符(解引用操作符)

(类型名)   强制类型转换

这里介绍一下,后面我们用到的时候可以再解释,那样效果可能更好一些。


6. 关系操作符

>

>=

<

<=

!=        用于“不相等”

==        用于“相等”

这里就是要注意“==”和“=”用法。


7. 逻辑操作符

&&        逻辑与

||           逻辑或

这就要区分这两个和位操作符的区别,这里是两个。

int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;
    //i = a++||++b||d++;
    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
    return 0;
}

先看逻辑与的这个例子,它的打印结果是什么呢?

 可能有人觉得结果不对,但是这就是正确的结果,那这是为什么呢?

&&逻辑与的使用是从左往右,必须每个表达式都为真才会计算到最后,要不然就会像这里的a一样,后置++先使用再加1,所以一开始 a = 0,表达式为假,所以a后面的表达式就不会再计算了。

||逻辑或的使用规则是表达式中只要有一个表达式为真,就不会再往下计算了,一开始a为假,下一个b为真,所以后面的d就不会计算了。 


8. 条件操作符

也叫三目操作符

exp1 ? exp2 : exp3

a > b ? a : b;

转换一下:

if (a > b)

        (如果a > b 就执行a)

else

        (否则就执行b)


9. 逗号表达式

(exp1, exp2, exp3, …expN)

逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);

最后的结果c为13


10. 下标引用、函数调用和结构成员

1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值

2. ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数

3. 访问一个结构的成员

.        结构体 . 成员名

->      结构体指针 -> 成员名

11. 表达式求值

表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。

        11.1 隐式类型转换

C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

实例:

char a, b, c;                                                                                                                                a = b + c;

b和c的值被提升为普通整型,然后再执行加法运算,法运算完成之后,结果将被截断,然后再存储于a中。

//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:补码:11111111111111111111111111111111

//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001

//无符号整形提升,高位补0

        11.2 算术转换

        如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换

高等级        long double
                   double
                   float
                   unsigned long int
                   long int
                   unsigned int                                                                                                         
低等级       int

       如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。
警告:
但是算术转换要合理,要不然会有一些潜在的问题,可能会有精度的丢失。

        11.3 操作符的属性

复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。


 结语:

        年过完了,接下来要继续好好学习。

猜你喜欢

转载自blog.csdn.net/m0_64607843/article/details/122665466
今日推荐