C语言 ─── 操作符详解

目录

[1. 算术操作符](#1. 算术操作符)

[2. 移位操作符](#2. 移位操作符)

[2.1 左移操作符](#2.1 左移操作符)

[2.2 右移操作符](#2.2 右移操作符)

[3. 位操作符](#3. 位操作符)

[4. 复合赋值符](#4. 复合赋值符)

[5. 单目操作符](#5. 单目操作符)

[6. 逗号表达式](#6. 逗号表达式)

[7. 隐式类型转换](#7. 隐式类型转换)

[7.1 整型提升的意义:](#7.1 整型提升的意义:)

[7.2 如何进行整体提升呢?](#7.2 如何进行整体提升呢?)

[8. 算术转换](#8. 算术转换)

★★★数组名



**1.**算术操作符

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

2. 移位操作符

cpp 复制代码
<< 左移操作符
>> 右移操作符
    
注:移位操作符的操作数只能是整数。

2.1****左移操作符

移位规则:
左边抛弃、右边补 0

2.2****右移操作符

移位规则:
首先右移运算分两种:

  1. 逻辑移位
    左边用0填充,右边丢弃
  2. 算术移位
    左边用原该值的符号位填充,右边丢弃

    警告⚠ :
    对于移位运算符,不要移动负数位,这个是标准未定义的。
    例如:
cpp 复制代码
int num = 10;
num>>-1;//error

3. 位操作符

位操作符有:

cpp 复制代码
& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。

练习:
编写代码实现:求一个整数存储在内存中的二进制中1 的个数。

cpp 复制代码
#include <stdio.h>
int main()
{
     int num = -1;
     int i = 0;
     int count = 0;//计数
     for(i=0; i<32; i++)
     {
         if( num & (1 << i) )
         count++; 
     }
     printf("二进制中1的个数 = %d\n",count);
     return 0;
}
//思考还能不能更加优化,这里必须循环32次的。

#include <stdio.h>
int main()
{
     int num = -1;
     int i = 0;
     int count = 0;//计数
     while(num)
     {
         count++;
        //n=n&(n-1)执行一次可以把n的二进制最右面的1去掉一个
         num = num&(num-1);
     }
     printf("二进制中1的个数 = %d\n",count);
     return 0;
}
//这种方式是不是很好?达到了优化的效果,但是难以想到。

判断一个数是否为2的次方

cpp 复制代码
int main()
{
	int n;
	scanf("%d", &n);
	if ((n & (n - 1)) == 0)
	{
		printf("Yes ");
	}
	else
	{
		printf("No ");
	}
}

4. 复合赋值符

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

5. 单目操作符

! 逻辑反操作

  • 负值
  • 正值
    & 取地址
    sizeof 操作数的类型长度(以字节为单位)
    ~ 对一个数的二进制按位取反
    -- 前置、后置 --
    ++ 前置、后置 ++
    * 间接访问操作符 ( 解引用操作符 )
    ( 类型 ) 强制类型转换
    笔试题:
cpp 复制代码
#include <stdio.h>
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;
}
//程序输出的结果是什么?

答案:1 2 3 4

1 3 3 5

6. 逗号表达式

cpp 复制代码
exp1, exp2,exp3,exp4,...expN

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

7. 隐式类型转换

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

7.1 整型提升的意义

表达式的整型运算要在CPU 的相应运算器件内执行, CPU 内整型运算器 (ALU) 的操作数的 字节长度一般就是int的字节长度 ,同时也是 CPU 的通用寄存器的长度。
因此,即使两个char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长度。
通用CPU ( general-purpose CPU )是难以直接实现两个 8 比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以, 表达式中各种长度可能小于int长度的整型值 ,都必须先转换为int 或 unsigned int ,然后才能送入 CPU 去执行运算。

cpp 复制代码
//实例1
char a,b,c;
...
a = b + c;

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

7.2 如何进行整体提升呢?

整形提升是按照变量的数据类型的符号位来提升的

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

整形提升的例子 :

cpp 复制代码
//实例1
int main()
{
     char a = 0xb6;
     short b = 0xb600;
     int c = 0xb6000000;
     if(a==0xb6)
     printf("a");
     if(b==0xb600)
     printf("b");
     if(c==0xb6000000)
     printf("c");
     return 0;
}

实例1 中的 a,b 要进行整形提升 , 但是 c 不需要整形提升
a,b 整形提升之后 , 变成了负数 , 所以表达式 a==0xb6 , b==0xb600 的结果是假 , 但是 c 不发生整形提升 , 则表达式 c==0xb6000000 的结果是真 .
所程序输出的结果是:
c

cpp 复制代码
//实例2
int main()
{
 char c = 1;
 printf("%u\n", sizeof(c));
 printf("%u\n", sizeof(+c));
 printf("%u\n", sizeof(-c));
 return 0;
}

实例2 中的 , c只要参与表达式运算,就会发生整形提升 , 表达式 +c , 就会发生提升 , 所以 sizeof(+c) 是 4 个字节.
表达式 - c 也会发生整形提升 , 所以 sizeof( - c) 是 4 个字节 , 但是 sizeof(c) , 就是 1 个字节 .

8. 算术转换

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

cpp 复制代码
long double
double
float
unsigned long int
long int
unsigned int
int

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

cpp 复制代码
float f = 3.14;
int num = f;//隐式转换,会有精度丢失

整形提升是针对小于int的值进行运算时需要整形提升,

算数转换最低也是int

★★★数组名

相关推荐
Paddi93015 分钟前
Codeforces Round 1004 (Div. 1) C. Bitwise Slides
c++·算法
Luis Li 的猫猫1 小时前
深度学习中的知识蒸馏
人工智能·经验分享·深度学习·学习·算法
查理零世1 小时前
【蓝桥杯集训·每日一题2025】 AcWing 6118. 蛋糕游戏 python
python·算法·蓝桥杯
敲代码的小王!1 小时前
MD5加密算法和BCrypt密码加密算法
java·算法·安全
带娃的IT创业者2 小时前
机器学习实战(6):支持向量机(SVM)——强大的非线性分类器
算法·机器学习·支持向量机
Java能学吗5 小时前
2.17学习总结
数据结构·学习
孑么5 小时前
力扣 买卖股票的最佳时机
算法·leetcode·职场和发展·贪心算法·动态规划
诚信爱国敬业友善6 小时前
常见排序方法的总结归类
开发语言·python·算法
罗政6 小时前
冒险岛079 V8 整合版源码搭建教程+IDEA启动
java·ide·intellij-idea
gentle_ice6 小时前
跳跃游戏 II - 贪心算法解法
数据结构·算法·leetcode·贪心算法