【C语言基础】:操作符详解(二)

文章目录

    • 操作符详解
      • 一、上期扩展
      • 二、单目操作符
      • 三、逗号表达式
      • 四、下标访问[]、 函数调用()
      • 五、结构成员访问操作符
      • 六、操作符的属性:优先级、结合性
        • 1. 优先级
        • 2. 结合性

操作符详解

上期回顾:【C语言基础】:操作符详解(一)

一、上期扩展

【练习一】:不能创建临时变量(第三个变量), 实现两个整数的交换。

方法一:我们可以运用加减法来实现这个功能。
分析:

交换前:a = 3,b = 5;
我们先让 a + b 然后把这个结果赋值给a,也就是a = a + b
现在a的值变成了8,而b的值还是5;
接下来我们让a - b,把这个表达式赋值给吧,也就是b = a - b
现在a的值是8,b的值是3;
最后我们只要将a - b这个表达式赋值给a就行啦,也就是a = a - b。
我们就会发现a和b的值发生了互换。

下面是代码实现:

#include<stdio.h>
int main()
{int a = 3;int b = 5;printf("交换前:a = %d b = %d\n", a, b);a = a + b;// a = 8, b = 5b = a - b;// a = 8, b = 3a = a - b;// a = 5, b = 3printf("交换后:a = %d b = %d\n", a, b);return 0;
}

在这里插入图片描述
很明显,这种方法也存在着明显的不足,那就是当a和b的值比较大时,a和b可能会超出int的范围,会出现溢出的现象,导致无法进行值的互换。

方法二:按位异或实现
上次我们学习了位操作符,其中按位异或就是对应二进制位相同为0,相异为1。根据这个特性,我们也能实现这个功能。

分析

首先我们要了解按位异或中几种特殊的情况。比如a ^ aa ^ 0等等。
1101
1101
按位异或后的结果就是0,而任何数与0按位异或后还是它本身。
根据这个特点,我们也能实现a和b的互换。
注意:按位异或是支持交换律的。

下面说代码实现:

#include<stdio.h>
int main()
{int a = 3;int b = 5;printf("交换前:a = %d b = %d\n", a, b);a = a ^ b;b = a ^ b;  // b = a ^ b ^ b, b ^ b就等于0// 现在a = a ^ b, b = aa = a ^ b;// a = a ^ b ^ a, 因为a ^ a等于0// 现在a = b, b = aprintf("交换后:a = %d b = %d\n", a, b);return 0;
}

在这里插入图片描述
这种方法也存在着局限性,首先要知道按位操作符的操作数必须是整数,其次代码的可读性也不高,不方便他人理解。

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

方法一:通过不断的去模2,除2来获得二进制中1的个数。
注意:这里是指补码

#include<stdio.h>
int count_one_of_bite(unsigned int n)
{int count = 0; // 计数while (n){if (n % 2 == 1)count++;n = n / 2;}return count;
}
int main()
{int n = 0;scanf("%d", &n);int ret = count_one_of_bite(n);printf("二进制中一的个数:%d\n", ret);return 0;
}

在这里插入图片描述

方法二:n & (n - 1)

#include<stdio.h>
int count_one_of_bite(unsigned int n)
{int count = 0; // 计数while (n){count++;n = n & (n - 1);}return count;
}
int main()
{int n = 0;scanf("%d", &n);int ret = count_one_of_bite(n);printf("二进制中一的个数:%d\n", ret);return 0;
}

在这里插入图片描述

二、单目操作符

单目操作符(Unary Operator)是一种只操作一个操作数的操作符。

!++&+-~*、sizeof(类型)

  1. 正号 (+):用于表示正数,例如 +5 表示正数 5。
  2. 负号 (-):用于表示负数,例如 -5 表示负数 5。
  3. 递增 (++):用于将操作数的值增加 1。可以作为前缀 (++i) 或后缀 (i++) 使用。
  4. 递减 (–):用于将操作数的值减少 1。可以作为前缀 (–i) 或后缀 (i–) 使用。
  5. 取址 (&):用于获取变量的内存地址,例如 &x 表示变量 x 的地址。
  6. 解引用 (*):用于访问指针所指向的内存中的值。例如,*ptr 表示指针 ptr 指向的值。
  7. 逻辑非 (!):用于求取操作数的逻辑非,即取反。例如,!x 表示 x 的逻辑非。
  8. 按位取反 (~):用于对操作数执行按位取反操作。例如, ~ x 表示对 x 的每个位取反。

这些是 C 语言中常用的一些单目操作符。它们可以用来执行各种不同的操作,如数值运算、递增递减、逻辑运算和位运算等。

三、逗号表达式

逗号表达式(Comma Expression)是一种由逗号操作符连接起来的表达式,其特点是依次计算每个子表达式,并返回最后一个子表达式的值作为整个表达式的值。逗号表达式的一般形式如下:

expr1, expr2, expr3, ..., exprN

在逗号表达式中,逗号操作符 , 用于连接多个子表达式。在计算逗号表达式时,每个子表达式都会按顺序依次执行,但整个表达式的值将是最后一个子表达式的值。

逗号表达式在 C 语言中可以用于一些特定的场景,如在 for 循环的初始化和迭代部分、函数调用参数中以及变量初始化等地方。例如,在 for 循环中使用逗号表达式可以同时初始化多个变量:

for (int i = 0, j = 10; i < 10; i++, j--) {// 循环体
}

在函数调用参数中使用逗号表达式可以依次计算多个表达式并将它们作为函数的参数:

int result = myFunction(a, b, c+1, d*2);

逗号表达式的使用要谨慎,因为它可能会使代码变得难以理解。在某些情况下,使用逗号表达式可能降低代码的可读性,因此应该根据具体情况慎重考虑是否使用。

【练习】

#include<stdio.h>
int main()
{int a = 1;int b = 2;int c = (a > b, a = b + 10, a, b = a + 1);  // 逗号表达式printf("%d\n", c);return 0;
}

可以看到,第六行是一个逗号表达式,从左到右依次进行计算,最后返回最右边的结果。
在这里插入图片描述

四、下标访问[]、 函数调用()

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

【举例】

int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[]的两个操作数是arr和9

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

【举例】

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

五、结构成员访问操作符

结构体
结构体(Struct)是一种用户自定义的数据类型,用于将不同类型的数据组合成一个单独的实体。结构体能够将多个变量打包成一个整体,方便操作和传递。

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:标量、数组、指针,甚⾄是其他结构体。

结构体的声明包括两个部分:结构体模板的定义和结构体变量的声明。

  1. 结构体模板的定义:
struct 结构体名称 {数据类型 成员1;数据类型 成员2;// 更多成员...
};

其中,“结构体名称” 是用户定义的结构体类型的名称,可以根据需要自行命名。“成员1”、“成员2” 等是结构体中的成员变量,每个成员变量都有自己的数据类型。

【示例】:坐标结构体的定义

struct Point {int x;int y;
};

这个结构体定义了一个名为 Point 的结构体类型,它有两个成员变量 x 和 y,都是 int 类型。

  1. 结构体变量的声明:
struct 结构体名称 变量名称;

在结构体定义之后,可以通过声明结构体变量来创建实际的结构体对象。

【示例】:使用上述定义的 Point 结构体来声明一个名为 p 的结构体变量

struct Point p;

现在,变量 p 是一个具有两个成员变量的结构体对象。可以通过 . 运算符来访问结构体的成员变量,例如 p.x 或 p.y。

另外,C 语言还提供了一种更简洁的方式来声明结构体变量,即使用 typedef 关键字:

typedef struct {数据类型 成员1;数据类型 成员2;// 更多成员...
} 结构体名称;

这样就可以直接使用 结构体名称 来定义结构体变量,而不需要再写 struct 关键字。例如:

typedef struct {int x;int y;
} Point;
Point p;

这里的 Point 就是一个结构体类型,并且可以直接用于声明结构体变量。

//代码1:变量的定义
struct Point
{int x;int y;
}p1;               //声明类型的同时定义变量p1
struct Point p2;    //定义结构体变量p2//代码2:初始化。
struct Point p3 = { 10, 20 };struct Stu        //类型声明
{char name[15];//名字int age;     //年龄
};struct Stu s1 = { "zhangsan", 20 };//初始化
struct Stu s2 = { .age = 20, .name = "lisi" };//指定顺序初始化//代码3
struct Node
{int data;struct Point p;struct Node* next;
}n1 = { 10, {4,5}, NULL };            //结构体嵌套初始化
struct Node n2 = { 20, {5, 6}, NULL };//结构体嵌套初始化

结构体成员的直接访问
结构体成员的直接访问是通过点操作符( .) 访问的。点操作符接受两个操作数。如下所示:

#include <stdio.h>
struct Point
{int x;int y;
}p = { 1,2 };
int main()
{printf("x: %d y: %d\n", p.x, p.y);return 0;
}

在这里插入图片描述
使用方式:结构体变量.成员名

结构体成员的间接访问
有时候我们得到的不是⼀个结构体变量,而是得到了⼀个指向结构体的指针。如下所示:

#include <stdio.h>
struct Point
{int x;int y;
};
int main()
{struct Point p = {3, 4};struct Point *ptr = &p;ptr->x = 10;ptr->y = 20;printf("x = %d y = %d\n", ptr->x, ptr->y);return 0;
}

在这里插入图片描述
使用方式:结构体指针->成员名

综合举例

#include <stdio.h>
#include <string.h>
struct Stu
{char name[15];//名字int age; //年龄
};
void print_stu(struct Stu s)
{printf("%s %d\n", s.name, s.age);
}
void set_stu(struct Stu* ps)
{strcpy(ps->name, "李四");ps->age = 28;
}
int main()
{struct Stu s = { "张三", 20 };print_stu(s);set_stu(&s);print_stu(s);return 0;
}

在这里插入图片描述

六、操作符的属性:优先级、结合性

C语⾔的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。

1. 优先级

优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。

3 + 4 * 5;

上⾯⽰例中,表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4 。
在这里插入图片描述
在这里插入图片描述

2. 结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执行顺序。⼤部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符( = )。

5 * 6 / 2;

上面示例中, * 和 / 的优先级相同,它们都是左结合运算符,所以从左到右执行,先计算 5 * 6 ,再计算 6 / 2 。
运算符的优先级顺序很多,下⾯是部分运算符的优先级顺序(按照优先级从高到低排列),建议大概记住这些操作符的优先级就行,其他操作符在使用的时候查看下面表格就可以了。

• 圆括号( () )
• ⾃增运算符( ++ ),⾃减运算符( – )
• 单⽬运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( < 、 > 等)
• 赋值运算符( = )

由于圆括号的优先级最高,可以使用它改变其他运算符的优先级。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

https://htmlunit.sourceforge.io/

https://htmlunit.sourceforge.io/ 爬虫 HtmlUnit – Welcome to HtmlUnit HtmlUnit 3.11.0 API https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit/2.70.0 https://s01.oss.sonatype.org/service/local/repositories/releases/content/org/htmlunit…

进程间通信学习笔记(有名管道和无名管道)

进程间通信方式&#xff1a; 无名管道(pipe)有名管道(fifo)信号(signal)共享内存(mmap)套接字(socket) 无名管道&#xff1a; 在内核里面开辟一片内存&#xff0c;进程1和进程2都可以通过这片内存进行通信 无名管道特点&#xff1a; 只能用于具有亲缘关系的进程之间的通信&am…

YOLOv9图像标注和格式转换

一、软件安装 labelimg安装&#xff08;anaconda&#xff09; 方法一、 pip install labelImg 方法二、 pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install lxml -i ht…

系统找不到xinput1_3.dll怎么办?试试这五种解决方法轻松搞定

在计算机系统运行过程中&#xff0c;当我们遭遇“找不到xinput1_3.dll”这一错误提示时&#xff0c;实际上正面临一个软件兼容性、系统组件缺失以及游戏或应用程序无法正常启动的关键问题。深入探究这一现象&#xff0c;我们会发现它可能引发一系列连带问题&#xff0c;例如某些…

linux之前后端项目部署与发布

目录 前言 简介 一、安装Nginx 二、后端部署 2.1多个tomcat负载均衡 2.2 负载均衡 2.3 后端项目部署 三、前端部署 1.解压前端 2.Nginx配置文件修改 3.IP域名映射 4.重启Nginx服务 前言 上篇博主已经讲解过了单机项目的部署linux之JAVA环境配置JDK&Tomcat&a…

车载终端_联发科MTK6762车载平板电脑解决方案

智能车载终端方案搭载了MTK联发科8xARM Cortex-A53(64bit)高速CPU&#xff0c;采用12nm工艺制程&#xff0c;提供更快的数据采集速度和APP响应速度&#xff0c;能够快速满足用户的应用需求。配备3GB RAM32GB ROM的低功耗EMCP一体化存储&#xff0c;性能良好&#xff0c;支持多任…

【LeetCode:2476. 二叉搜索树最近节点查询 + 中序遍历 + 有序表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

python使用winio控制x86工控机的gpio

视频讲解 https://www.bilibili.com/video/BV1Nu4m1w7iv/?vd_source5ba34935b7845cd15c65ef62c64ba82f pywinio库 https://pypi.org/project/pywinio/ 安装库 pip install pywinio寄存器地址 测试代码 import pywinio winio get_winio() # 设置排针2输出1,0x40是bit6置…

嵌入式中逻辑分析仪基本操作方法

前期准备 1.一块能触摸的屏对应的主板机 2.逻辑分析仪对应的软件工具 3.对应的拓展板 4.确定拓展板的引脚分布情况 第一步&#xff1a;逻辑分析仪j基本操作 1.数据捕捉需要先进行对应软件安装,并按照需求进行配置 2.这里以A20为例:此手机使用显示驱动芯片CST148,触摸屏分辨…

插件废土课:打造属于你的“智能笔记”!

哎呀嘞&#xff0c;亲爱的网页冲浪者们&#xff0c;抓紧浮板&#xff0c;我们要继续在Chrome插件的海浪上翻滚啦&#xff01;上次我们玩了个小把戏&#xff0c;搞了个显示时间的Hello World插件&#xff0c;这次我们要把游戏玩大&#xff0c;准备打造一个能让你在网页上乱涂乱画…

数学建模【GM(1, 1)灰色预测】

一、GM(1, 1)灰色预测简介 乍一看&#xff0c;这个名字好奇怪&#xff0c;其实是有含义的 G&#xff1a;Grey&#xff08;灰色&#xff09;M&#xff1a;Model&#xff08;模型&#xff09;(1, 1)&#xff1a;只含有一个变量的一阶微分方程模型 提到灰色&#xff0c;就得先说…

大数据开发项目--音乐排行榜

环境&#xff1a;windows10&#xff0c;centos7.9&#xff0c;hadoop3.2、hbase2.5.3和zookeeper3.8完全分布式&#xff1b; 环境搭建具体操作请参考以下文章&#xff1a; CentOS7 Hadoop3.X完全分布式环境搭建 Hadoop3.x完全分布式环境搭建Zookeeper和Hbase 1. 集成MapReduce…

消息中间件之RocketMQ源码分析(十八)

Broker CommitLog索引机制中的构建过程 1.创建ConsumeQueue和IndexFile。 ConsumeQueue和IndexFile两个索引都是由ReputMessageService类创建的 RequestMessageService类图 ReputMessageService服务启动后的执行过程。 doReput()方法用于创建索引的入口&#xff0c;通常通过…

运用工具Postman快速导出python接口测试脚本

Postman的脚本可以导出多种语言的脚本&#xff0c;方便二次维护开发。 Python的requests库&#xff0c;支持python2和python3&#xff0c;用于发送http/https请求 使用unittest进行接口自动化测试 一、环境准备 1、安装python&#xff08;使用python2或3都可以&#xff09;…

【数据结构与算法】常用算法 前缀和

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

离散数学——树思维导图

离散数学——树思维导图 文章目录 前言内容大纲参考 前言 这是当初学习离散数学时整理的笔记大纲&#xff0c;其中包含了自己对于一些知识点的体悟。现将其放在这里作为备份&#xff0c;也希望能够对你有所帮助。 当初记录这些笔记只是为了在复习时更快地找到对应的知识点。…

Python爬虫之极验滑动验证码的识别

极验滑动验证码的识别 上节我们了解了可以直接利用 tesserocr 来识别简单的图形验证码。近几年出现了一些新型验证码&#xff0c;其中比较有代表性的就是极验验证码&#xff0c;它需要拖动拼合滑块才可以完成验证&#xff0c;相对图形验证码来说识别难度上升了几个等级。本节将…

如何在Linux部署Portainer并结合内网穿透远程管理本地Docker容器

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

用c# 自己封装的Modbus工具类库源码

前言 Modbus通讯协议在工控行业的应用是很多的&#xff0c;并且也是上位机开发的基本技能之一。相关的类库也很多也很好用。以前只负责用&#xff0c;对其并没有深入学习和了解。前段时间有点空就在这块挖了挖。想做到知其然还要知其所以然。所以就有了自己封装的Modbus工具类库…

Mysql 常用数据类型

数值型(整数)的基本使用 如何定义一个无符号的整数 数值型(bit)的使用 数值型(小数)的基本使用 字符串的基本使用 字符串使用细节 日期类型的基本使用