《C语言深度解剖》:(5)C语言操作符一网打尽

🤡博客主页:醉竺

🥰本文专栏:《C语言深度解剖》

😻欢迎关注:感谢大家的点赞评论+关注,祝您学有所成!


✨✨💜💛想要学习更多数据结构与算法点击专栏链接查看💛💜✨✨ 


学习各种操作符之前,先说一个重要的基础知识:

整数在内存中存储的是补码,对整数的二进制位的各种操作其实 是对内存中的二进制补码进行操作,而打印出来,“拿出来用的时候”是以原码的形式。

正数的原反补一样;负数的原码、反码、补码的相互转换方式:

1. 操作符分类 

  • 算术操作符
  • 移位操作符
  • 位操作符
  • 赋值操作符
  • 单目操作符
  • 关系操作符
  • 逻辑操作符
  • 条件操作符
  • 逗号表达式
  • 下标引用、函数调用和结构成员 

2. 算术操作符 

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

 3. 移位操作符

<< 左移操作符
>> 右移操作符

注:

移位操作符的操作数只能是整数。

移动的是二进制位 移位操作符不会改变原来的变量 。

3.1 左移操作符 

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

3.2 右移操作符 

移位规则:

首先右移运算分两种: 

1. 逻辑移位:左边用0填充,右边丢弃

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

警告⚠️ : 对于移位运算符,不要移动负数位,这个是标准未定义的。 

例如:

int num = 10;
num >> -1;//error

4. 位操作符(难点) 

位操作符有: 

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

& 按二进制位与

二进制位相&的时候,其中一个二进制为0,结果则为0,两个同时为1,才为1

| 按二进制位或

二进制相 | 的时候,其中一个二进制为1,结果则为1,两个同时为0则为0

^ 按二进制位异或

两个二进制位 相同为0,相异为1 

这里对于异或运算有一个重要的秘诀: 

  1. 两个相同的数异或 = 0,a ^ a = 0
  2. 任意一个数与0异或 = 这个数本身,a ^ 0 = a
  3. 异或操作支持交换律 

练习一下:

#include <stdio.h>
int main()
{
	int num1 = 1;
	int num2 = 2;
	printf("%d",num1 & num2); // 0
	printf("%d",num1 | num2); // 3
	printf("%d",num1 ^ num2); // 3
	
	return 0;
}

一道变态的面试题:

  • 不能创建临时变量(第三个变量),实现两个数的交换。 

这里就运用了上述的异或秘诀 

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a ^ b; 
	b = a ^ b; // a^b ^b (a)
	a = a ^ b; // a^b ^a (b)
	printf("a = %d b = %d\n", a, b);  // 10 20
	return 0;
}

其实还有一种不交换变量的方法,相互加减法:

#include <stdio.h>
int main()
{
	int a = 10, b = 20;

	a = a + b; 
	b = a - b; // 等价于a + b - b ->结果b = 原先的a
	a = a - b; // 等价于a + b - a ->结果a = 原先的b
	printf("a = %d b = %d\n", a, b); // 输出a = 20 b = 10
	return 0;
}

下面是我自己总结的一些关于位运算符常出现题目的背后解题原理! 

后面出几个非常优质经典的题目,根据上面的原理,大家学会融会贯通。 

练习: 

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

上面三种方法都可以,好好思考每一种如何实现的,建议举一个数试一试。

5. 赋值操作符 

赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。 

int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值。

赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y + 1;//连续赋值
这样的代码感觉怎么样?

那同样的语义,你看看:
x = y + 1;
a = x;
这样的写法是不是更加清晰爽朗而且易于调试。

复合赋值符  

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

这些运算符都可以写成复合的效果。 比如: 

int x = 10;
x = x + 10;
x += 10;//复合赋值
//其他运算符一样的道理。这样写更加简洁。

6. 单目操作符 

6.1 单目操作符介绍 

!	逻辑反操作
-	负值
+	正值
&	取地址
sizeof	操作数的类型长度(以字节为单位)
~   对一个数的二进制按位取反
--  前置、后置--
++  前置、后置++
*   间接访问操作符(解引用操作符)
(类型)  强制类型转换

一个小技巧:~x的结果 = -x-1 

关于sizeof其实我们之前已经见过了,可以求变量(类型)所占空间的大小 

下面再演示一个例子,认真看是如何计算的:  

6.2 sizeof 和 数组 

问:
(1)、(2)两个地方分别输出多少?
(3)、(4)两个地方分别输出多少? 

#include <stdio.h>
void test1(int arr[])
{
	printf("%d\n", sizeof(arr));//(2)  4或者8
}
void test2(char ch[])
{
	printf("%d\n", sizeof(ch));//(4)   4或者8
}
int main()
{
	int arr[10] = { 0 };
	char ch[10] = { 0 };
	printf("%d\n", sizeof(arr));//(1)  40
	printf("%d\n", sizeof(ch));//(3)   10
	test1(arr);
	test2(ch);
	return 0;
}
//++和--运算符
//前置++和--
#include <stdio.h>
int main()
{
    int a = 10;
    int x = ++a;
    //先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。
    int y = --a;
    //先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;
    return 0;
}
//后置++和--
#include <stdio.h>
int main()
{
    int a = 10;
    int x = a++;
    //先对a先使用,再增加,这样x的值是10;之后a变成11;
    int y = a--;
    //先对a先使用,再自减,这样y的值是11;之后a变成10;
    return 0;
}

7. 关系操作符 

关系操作符 

>
>=
<

 <=
 !=   用于测试“不相等”
 == 用于测试“相等” 

这些关系运算符比较简单,没什么可讲的,但是我们要注意一些运算符使用时候的陷阱。

警告: 在编程的过程中== 和=不小心写错,导致的错误。 

8. 逻辑操作符

逻辑与和或的特点: 

360笔试题 

9. 条件操作符 

exp1 ? exp2 : ex  p3 

若表达式exp1成立,则整个条件表达式返回exp2的结果,否则返回exp3的结果.

这意味着只有 exp1或 exp3中的一个会被计算,另一个则会被忽略。 

练习: 

1.下面代码转换成条件表达式,是什么样?

if (a > 5)
    b = 3;
else
    b = -3;

2.使用条件表达式实现找两个数中较大值。
1:
b = (a > 5) ? 3 : -3;

2.
max = (x > y) ? x : y;

10. 逗号表达式 

exp1, exp2, exp3, …expN 

逗号表达式,就是用逗号隔开的多个表达式。

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

//代码1
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式
c是多少?
答案:c = 13

//代码2
if (a = b + 1, c = a / 2, d > 0)

//代码3
a = get_val();
count_val(a);
while (a > 0)
{
    //业务处理
    a = get_val();
    count_val(a);
}

如果使用逗号表达式,改写:
while (a = get_val(), count_val(a), a > 0)
{
    //业务处理
}

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

1. [ ] 下标引用操作符

操作数:一个数组名 + 一个索引值

int arr[10];//创建数组

arr[9] = 10;//实用下标引用操作符。

[ ]的两个操作数是arr和9。 

2. ( ) 函数调用操作符 

接受一个或者多个操作数:第一个操作数是函数名剩余的操作数就是传递给函数的参数。 

#include <stdio.h>
void test1()
{
	printf("hehe\n");
}
void test2(const char* str)
{
	printf("%s\n", str);
}
int main()
{
	test1();            //实用()作为函数调用操作符。
	test2("hello bit.");//实用()作为函数调用操作符。
	return 0;
}

3. 访问一个结构的成员 

.         结构体.成员名

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

#include <stdio.h>
struct Stu
{
	char name[10];
	int age;
	char sex[5];
	double score;
};
void set_age1(struct Stu stu)
{
	stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
	pStu->age = 18;//结构成员访问
}
int main()
{
	struct Stu stu;
	struct Stu* pStu = &stu;//结构成员访问

	stu.age = 20;//结构成员访问
	set_age1(stu);

	pStu->age = 20;//结构成员访问
	set_age2(pStu);
	return 0;
}

12.表达式求值(重难点) 

表达式求值的顺序一部分是由操作符的优先级和结合性决定。

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。 

12.1 隐式类型转换 

C的整型算术运算总是至少以默认整型类型的精度来进行的。 

为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。(即char类型或者short类型进行运算的时候会被转换为int类型进行计算,提高精度

整型提升的意义:

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。 

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

如何进行整形提升呢? (重点)

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

请认真研读下面这张图片以及右侧的例子。 

整形提升的例子: 

实例1中的a,b要进行整形提升,但是c不需要整形提升

a,b整形提升之后,变成了负数,所以表达式 a==0xb6 , b==0xb600 的结果是假,但是c不发生整形提升,则表达式 c==0xb6000000 的结果是真. 

所程序输出的结果是:

//实例2
#include <stdio.h>
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个字节. 

12.2 算术转换 

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

如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。 

 警告: 但是算术转换要合理,要不然会有一些潜在的问题。

float f = 3.14;
int num = f;//隐式转换,会有精度丢失

12.3 操作符的属性 

复杂表达式的求值有三个影响的因素。 

  1. 操作符的优先级
  2. 操作符的结合性
  3. 是否控制求值顺序

两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。 

操作符优先级 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/552696.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一些docker安装配置以及常见命令

​常用命令 docker 命令 //进去容器内部&#xff0c;找到需要拷贝的文件及目录 docker exec -it 2c2600fb60f8 /bin/bash ​ //将container id为4db8edd86202的容器内elasticsearch.yml文件拷贝到宿主机指定目录下&#xff1a; docker cp 4db8edd86202:/usr/share/elasticsea…

pytest系列——allure之在测试用例添加标题(@allure.title())

前言 通过使用装饰器allure.title可以为测试用例自定义一个更具有阅读性的易读的标题。 allure.title的三种使用方式&#xff1a; 直接使用allure.title为测试用例自定义标题&#xff1b;allure.title支持通过占位符的方式传递参数&#xff0c;可以实现测试用例标题参数化&a…

温度对射频电路性能的影响

对于射频电路,通常会有使用温度范围的要求,即在特定的温度范围内其性能变化不超出指标要求的值。对于工业级产品,一般要求使用温度范围为-40℃~+70℃,而军品要求使用温度范围为-55℃~+85℃。有一些其他特殊使用场景的产品会有不同的要求。 不同的温度对电路性能的影响,…

nginx安装在linux上

nginx主要用于反向代理和负载均衡&#xff0c;现在简单的说说如何在linux操作系统上安装nginx 第一步&#xff1a;安装依赖 yum install -y gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel 第二步&#xff1a; 下载nginx&#xff0c;访问官网&#xff0c;ngin…

char和varchar的区别?

一、问题解析 char和varchar都是用于在数据库中存储字符串的数据类型。它们之间的主要区别在于存储空间的使用方式&#xff1a; char是一种定长的数据类型&#xff0c;它的长度固定且在存储时会自动在结尾添加空格来将字符串填满指定的长度。char的长度范围是0-255&#xff0c…

机器学习理论入门---线性回归从理论到实践

线性回归是机器学习里面最简单也是最常用的算法&#xff0c;理解了线性回归的推导之后对于后续的学习有很大帮助&#xff0c;所以我决定从这里开始深入学习相关的机器学习模型。 本篇首先从矩阵求导开始切入&#xff0c;然后介绍一次线性回归的推导&#xff0c;再到代码实现。本…

【八股】Redisson分布式锁

Redisson分布式锁 主要了解了Redisson分布式锁实现的三个功能&#xff1a; 1.可重入 -> 防止死锁 2.可重试&#xff08;i.e. 非阻塞获取锁&#xff09; 3.自动续约 1. 可重入 原理&#xff1a; 利用Redis的Hash结构&#xff0c;记录了使用当前锁的线程id和重用次数&#…

零基础小白,如何入门计算机视觉?

目录 前言 计算机视觉技术学习路线 基础知识 1. 数学基础 2. 编程基础 3. 图像处理基础 基础算法与技术 1. 特征提取与描述符 2. 图像分割与对象检测 3. 三维重建与立体视觉 机器学习与深度学习 1. 机器学习基础 2. 深度学习 高级主题与应用 1. 高级机器学习与深度学习 2. 计算…

Linux之 USB驱动框架-USB总线核心和主控驱动(4)

一、USB设备描述符 一个USB设备描述符中可以有多个配置描述符&#xff0c;即USB设备可以有多种配置&#xff1b;一个配置描述符中可以有多个接口描述符&#xff0c;即USB设备可以支持多种功能&#xff08;接口&#xff09;&#xff1b;一个接口描述符中可以有多个端点描述符。 …

【YOLOv8改进[Neck]】使用BiFPN助力V8更优秀

目录 一 BiFPN(双向特征金字塔网络) 1 BiFPN 2 EfficientDet 二 使用BiFPN助力模型更优秀 1 整体修改 2 配置文件 3 训练 其他 一 BiFPN(双向特征金字塔网络) BiFPN(双向特征金字塔网络&#xff0c; 2020)用于特征融合层。 官方论文地址&#xff1a;https://arxiv.org…

445. 两数相加 II

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 示例1&#xff1a; 输入&#xff1a;l1 [7,2,4,3], l2 [5,6,4]…

什么地推网推拉新副业平台最值得推荐? 赚取互联网第一桶金

随着互联网的发展&#xff0c;新型行业层出不穷。其中地推网推拉新作为互联网行业具有收入高、门槛低、时间自由等优势&#xff0c;一部分人从中嗅到了商机&#xff0c;开始纷纷接触并加入了进来。但还是有一部分人对于地推网推拉新的了解很少&#xff0c;不知道如何才能加入其…

这个“高端智库”落地上塘,数字生活商务社区企航俱乐部正式成立

4月10日上午&#xff0c;由浙江省跨境电子商务产业联盟指导&#xff0c;上塘街道党工委、办事处主办&#xff0c;上塘街道数字生活商务社区、运河&#xff08;国际&#xff09;跨境电子商务园承办的上塘街道数字生活商务社区企航俱乐部成立仪式暨助力跨境电商高质量发展首期交流…

计算机考研都将采用408!?

这个根本不可能&#xff0c;高考还没做到全国统一考试呢 每个学校对于计算机招生的需求是不一样的&#xff0c;比如清华大学&#xff0c;专业课912&#xff0c;算的上是最难的计算机专业课了&#xff0c;那他为什么搞这么难啊&#xff0c;还不是因为那群敢考清华的卷王们太变态…

Re65:读论文 GPT-3 Language Models are Few-Shot Learners

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;Language Models are Few-Shot Learners ArXiv网址&#xff1a;https://arxiv.org/abs/2005.14165 2020 NeurIPS&#xff1a;https://papers.nips.cc/paper/2020/hash/1457c0d6bfcb49674…

2024阿里云4核8G服务器租用优惠价格700元一年

阿里云4核8G服务器租用优惠价格700元1年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云优惠 aliyunfuwuqi…

MSSQL 命令行操作说明 sql server 2022 命令行下进行配置管理

说明&#xff1a;本文的内容是因为我在导入Access2019的 *.accdb 格式的数据时&#xff0c;总是出错的背景下&#xff0c;不得已搜索和整理了一下&#xff0c;如何用命令行进行sql server 数据库和用户管理的方法&#xff0c;作为从Access2019 直接导出数据到sql server 数据库…

1997-2022年各省技术市场发展水平数据(原始数据+计算过程+计算结果)

1997-2022年各省技术市场发展水平数据&#xff08;原始数据计算过程计算结果&#xff09; 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;国家统计局、统计年鉴 3、范围&#xff1a;30省 4、指标&#xff1a;技术市场成交额、国内生产总值、技术市场发展水平 5、计算…

牛仔裤哪个牌子质量好?平价高品质牛仔裤推荐

一条好的裤子&#xff0c;不仅穿着能够显瘦显高&#xff0c;同时质量也更加耐洗耐穿。但大家却极少能够选择到这些质量好的裤子。其实这都是因为目前市面上的裤子品牌实在太多&#xff0c;而且还有不少质量不够出色的品牌混杂在其中。那么要选什么品牌的裤子才好呢&#xff1f;…

iPad手绘+Ai二合一课程,Procreate+Mj+SD零基础到精通(10节视频课)

课程内容&#xff1a; 1 系统课 AI辅助设计流-从零进阶轻松驾驭AI设计,mp4 2 商务沟通阶段 ChatGPT Midjourney-聊天机器人 项目调研资料收集 ,mp4 3_商务沟通阶段 ChatGPT_Midjourney-Midjourney基础 界面初识初步设置 .mp4 4_商务沟通阶段 ChatGPT_Midjourney-Midjourney…