【C++基础】运算符和流程控制语句

C++中的运算符和流程控制语句

  • 一、运算符
    • 1. C++和Java在通用运算符中的不同之处对比
    • 2. C++中的位运算符
      • 2.1 移位运算符
      • 2.2 位逻辑运算符
    • 3. 运算时的类型转换总结
      • 3.1 隐式类型转换
      • 3.2 显式类型转换(强制类型转换)
    • 4. 注意
  • 二、流程控制语句
    • 1. C++和Java在通用流程控制语句中的不同之处对比
    • 2. 跳转语句goto

一、运算符

1. C++和Java在通用运算符中的不同之处对比

运算符C++Java
取余运算%两个操作数必须是整数类型两个操作数可以是浮点型
赋值运算=运算结果的类型就是左侧运算对象的类型,C++会自动进行隐式转换运算结果的类型如果和左侧运算对象的类型不一致,需要进行显式转换
逻辑运算符允许算数类型的数据参与运算只允许布尔类型的数据参与运算

2. C++中的位运算符

所有的算术类型,占用的空间都是以字节(byte,8位)作为单位来衡量的。在C++中,还有一类非常底层的运算符,可以直接操作到具体的每一位(bit)数据,这就是位运算符。位运算符可以分为两大类:移位运算符,和位逻辑运算符。下面列出了所有位运算符的优先级和用法:
在这里插入图片描述

2.1 移位运算符

算术类型的数据对象,都可以看做是一组位的集合。那么利用“位运算符,就可以让运算对象的所有位,整体移动指定的位数。移位运算符有两种:左移运算符<<和右移运算符>>。如下为移位运算符的具体案例:

unsigned char bits = 0xb5;    // 181
cout << hex;    // 以十六进制显示
cout << "0xb5 左移2位:" << (bits << 2) << endl;    // 0x 0000 02d4
cout << "0xb5 左移8位:" << (bits << 8) << endl;    // 0x 0000 b500
cout << "0xb5 左移31位:" << (bits << 31) << endl;    // 0x 8000 0000
cout << "0xb5 右移3位:" << (bits >> 3) << endl;    // 0x 0000 0016

cout << dec;
cout << (200 << 3) << endl;    // 乘8操作
cout << (-100 >> 2) << endl;    // 除4操作,一般右移是补符号位

在这里插入图片描述
移位运算符的运算规则如下:

  1. 较小的整数类型(char、short以及bool)会自动提升成int类型再做移位,得到的结果也是int类型
  2. 左移运算符<<将操作数左移之后,在右侧补0;
  3. 右移运算符>>将操作数右移之后,对于无符号数就在左侧补0;对于有符号数的操作则要看运行的机器环境,有可能补符号位,也有可能直接补0;
  4. 由于有符号数右移结果不确定,一般只对无符号数执行位移操作;

这里解释一下为什么有符号数右移结果不确定,这主要有两个原因:① 有符号数在进行右移动是补的数据是1还是0要根据该数据是正数还是负数来定,正数补0,负数补1② 相同的数据类型在不同的机器环境上的位数是不同的,可能在机器1上的定义正数转移到机器2上就被理解为负数。

2.2 位逻辑运算符

计算机存储的每一个位(bit)都是二进制的,有0和1两种取值,这跟布尔类型的真值表达非常类似。于是自然可以想到,两个位上的0或1都可以执行类似逻辑运算的操作。位逻辑运算符有:按位取反~,位与&,位或|和位异或^

  1. 按位取反~:一元运算符,类似逻辑非。对每个位取反值,也就是把1置为0、0置为1;
  2. 位与&:二元运算符,类似逻辑与。两个数对应位上都为1,结果对应位为1;否则结果对应位为0;
  3. 位或|:二元运算符,类似逻辑或。两个数对应位上只要有1,结果对应位就为1;如果全为0则结果对应位为0;
  4. 位异或^:两个数对应位相同,则结果对应位为0;不同则结果对应位为0;

位逻辑运算的具体案例如下:

// 位逻辑运算
cout << (~5) << endl;    // ~ (0... 0000 0101) = 1... 1111 1010,  -6
cout << (5 & 12) << endl;   // 0101 & 1100 = 0100, 4
cout << (5 | 12) << endl;   // 0101 | 1100 = 1101, 13
cout << (5 ^ 12) << endl;    // 0101 & 1100 = 1001, 9

在这里插入图片描述

3. 运算时的类型转换总结

3.1 隐式类型转换

大多数情况,C++编译器可以自动对类型进行转换,不需要我们干涉,这种方式叫做隐式类型转换。隐式类型转换主要发生在算术类型之间,基本思路就是将长度较小的类型转换成较大的类型,这样可以避免丢失精度。隐式类型转换不仅可以在变量赋值时发生,也可以在运算表达式中出现。

隐式类型转换的一般规则可以总结如下:

  1. 在大多数算术运算中,较小的整数类型(如bool、char、short)都会转换成int类型。这叫做整数提升;
  2. 当表达式中有整型也有浮点型时,整数值会转换成相应的浮点类型;
  3. 在条件判断语句中,其它整数类型会转换成布尔类型,即0为false、非0为true;
  4. 初始化变量时,初始值转换成变量的类型;
  5. 在赋值语句中,右侧对象的值会转换成左侧对象的类型;

3.2 显式类型转换(强制类型转换)

除去自动进行的隐式类型转换,我们也可以显式地要求编译器对数据对象的类型进行更改。这种转换叫做强制类型转换(cast)。比如对于除法运算,我们知道整数除法和浮点数除法是不同的。如果希望对一组整数求一个平均数,直接相加后除以个数是无法得到想要的结果的:

// 求平均数
int total = 20, num = 6;
double avg = total / num;
cout << " avg = " << avg << endl;    // avg = 3

因为两个int类型的数相除,执行的是整数除法,得到3;再转换成double类型对avg做初始化,得到是3.0。如果想要更准确的结果,就必须将int类型强制转换成double,做浮点数除法。

C++中要想进行强制类型转换,主要有以下三种方式:

  1. C语言风格:(类型名称) 值
  2. C++函数调用风格(推荐):类型名称 (值)
  3. C++强制类型转换运算符:static_cast<类型名称> (值)

案例如下:

// C语言风格
cout << " avg = " << (double) total / num << endl;  
// C++函数风格  
cout << " avg = " << double (total) / num << endl;   
// C++强转运算符
cout << " avg = " << static_cast<double>(total) / num << endl;    

4. 注意

  1. 要尽量避免将较大类型的值赋给较小类型的变量,这样很容易出现精度丢失或者数据溢出。
  2. 如果希望判断一个整型变量a是否在某个范围(0, 100)内,不能直接写:0 < a < 100;由于小于运算符<满足左结合律,要先计算0 < a,得到一个布尔类型的结果,再跟后面的100进行比较。此时布尔类型做整数提升,不管值是真(1)还是假(0),都会满足 < 100 的判断,因此最终结果一定是true。要想得到正确的结果,需要将两次关系判断拆开,写成逻辑与的关系。

二、流程控制语句

1. C++和Java在通用流程控制语句中的不同之处对比

语句C++Java
switchC++中switch中的条件类型必须是整型Java中switch中的条件表类型必须是char、byte、short、int、String、enum中的一种

2. 跳转语句goto

goto语句表示无条件地跳转到程序中的另一条语句。goto的语法形式为:

goto 标签;

这里的标签可以认为是一条语句的名字,跟变量类似,只不过它是指代一条语句的标识符。定义标签也非常简单,只要在一条语句前写出标识符,然后跟上冒号就可以了,比如:

begin:  int a = 0;

下面是一个具体的例子:

int x = 0;

cout << "程序开始..." << endl;

begin:
do
{
	cout << " x = " << ++x << endl;
} while (x < 10);

if (x < 15) {
	cout << "回到原点!" << endl;
	goto begin;
}

cout << "程序结束!" << endl;

由于goto可以任意跳转,所以它非常灵活,也非常危险。一般在代码中不要使用goto。

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

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

相关文章

网工内推 | 安全运维、服务工程师,软考中级、CISP优先,六险一金

01 华成峰科技 招聘岗位&#xff1a;安全运维工程师 职责描述&#xff1a; 1、负责安全产品的运维管理&#xff0c;包括设备升级变更、策略配置优化、设备巡检等&#xff1b; 2、负责7*24小时安全监控与应急响应&#xff0c;包括态势感知日志监测、安全事件分析及处置等&#…

【Keil5-报错】

Keil5-报错 ■ 调试烧录出现问题■ 烧录程序失败■ 编译报错 .\Objects\stm32h7_tms.axf: Error: L6218E: Undefined symbol __heap_base (referred from alloc.o).■ Keil5 load 出错■ No Space in execution regions with .ANY selector matching startup ...■ Execution r…

selenium自动化测试实战

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

SSD涨价停不下来!

随着HBM内存产能短缺问题的出现&#xff0c;存储市场正遭遇另一波供应短缺。在2021年存储市场陷入低迷后&#xff0c;SSD价格已连续下滑约两年。面对市场变化&#xff0c;存储厂商减少了NAND闪存的生产。随着减产策略的有效执行&#xff0c;需求部分回升&#xff0c;导致SSD供应…

Hot100【十一】:最大子数组和

// 定义dp&#xff1a;以i结尾的最大子数组和 dp[i] max(dp[i-1] nums[i],nums[i]) class Solution {public int maxSubArray(int[] nums) {// 1. 不需要特殊处理// 2. 定义dpint[] dp new int[nums.length];dp[0] nums[0];int maxResult nums[0];// 3. dp递推for (int i …

Oracle 在线回缩表

Oracle 在线回缩表 conn scott/tiger DROP TABLE EMP1 PURGE; CREATE TABLE EMP1 AS SELECT * FROM EMP; alter table emp1 enable row movement; -- 启动回缩特性 insert into emp1 select * from emp1; / / commit; -- 增加到14000行 -- 分析表的结构 analyz…

Vue2 —— 学习(五)

一、生命周期 &#xff08;一&#xff09;引入案例 我们想让一行文字按一定频率逐渐变得透明 1. Vue 实例外写法 函数写在 Vue 实例外面也能实现但是不推荐 <body><div id"root"><h2 :style"{opacity}">欢迎学习Vue</h2><…

ELK大型日志收集分析系统

目录 一、 ELK日志分析系统 1.1ELK介绍 1.2ELK各组件介绍 1.2.1ElasticSearch 1.2.2Kiabana 1.2.3Logstash 1.2.4可以添加的其它组件 1.2.4.1Filebeat filebeat 结合logstash 带来好处 1.2.4.2缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09; 1.2.4…

100道面试必会算法-21-二叉树的最近公共祖先

100道面试必会算法-21-二叉树的最近公共祖先 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且…

springcloud==springboot3.X+JDK21

2024年新版springcloud springboot3.X JDK21 ROADMAP 配套代码地址 GitHub - hebian1994/cloud2024

外包干了3天,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

最祥解决python 将Dataframe格式数据上传数据库所碰到的问题

碰到的问题 上传Datafrane格式的数据到数据库 会碰见很多错误 举几个很普遍遇到的问题(主要以SqlServer举例) 这里解释下 将截断字符串或二进制数据 这个是字符长度超过数据库设置的长度 然后还有字符转int失败 或者字符串转换日期/或时间失败 这个是碰到的需要解决的最多的问…

【MATLAB源码-第179期】基于matlab的64QAM调制解调系统频偏估计及补偿算法仿真,对比补偿前后的星座图误码率。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在通信系统中&#xff0c;频率偏移是一种常见的问题&#xff0c;它会导致接收到的信号频率与发送信号的频率不完全匹配&#xff0c;进而影响通信质量。在调制技术中&#xff0c;QPSK&#xff08;Quadrature Phase Shift Keyi…

在开发过程中使用 git rebase 还是 git merge

在开发过程中使用 git rebase 还是 git merge Merge(合并)的优点和缺点Rebase(变基)的优点和缺点总结&#xff1a; Git merge 和rebase的目的是一样的&#xff0c;它们都是将多个分支合并成一个。 虽然他们最终的目标是一样的&#xff0c;但这两种方法实现的方式是不同的。那么…

SpringBoot常用注解及其使用示例

Spring Boot是一个用于快速构建Java应用程序的框架&#xff0c;它简化了Spring应用程序的创建和部署过程。 Spring Boot提供了很多注解&#xff0c;用于简化开发过程&#xff0c;提高开发效率。本文将介绍几个Spring Boot常用注解的使用案例&#xff0c;包括Controller、Reques…

rancher踩坑日志:prometheus访问kubelet 10250端口提示鉴权失败

该原因是因为kubectl禁止了非授权用户访问10250端口来获取node的数据。 解决思路&#xff1a; 添加prometheus访问kubelet时带上证书进行验证匹配 --> 由于我的prometheus是rancher安装的&#xff0c;不知道要怎么修改所以研究了一会没研究明白就放弃了。设置prometheus访问…

《深入Linux内核架构》第2章 进程管理和调度 (2)

目录 2.4 进程管理相关的系统调用 2.4.1 进程复制 2.4.2 内核线程 2.4.3 启动新程序 2.4.4 退出进程 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;订阅后续文章。 2.4 进程管理相关的系统调用 2.4.1 进程复制 1. _do_fork函数 fork vfork clone都最终调用_…

YOLOv5实战记录06 Gradio搭建Web GUI

个人打卡&#xff0c;慎看。 指路大佬&#xff1a;【手把手带你实战YOLOv5-入门篇】YOLOv5 Gradio搭建Web GUI_哔哩哔哩_bilibili 先放一张效果图&#xff1a; 零、虚拟环境激活 之前up说要激活环境时&#xff0c;我没当回事儿&#xff0c;今天突然想&#xff0c;激活环境然后…

设计模式之创建型模式---建造者模式

文章目录 建造者模式概述经典的建造者模式建造者模式的变种总结 建造者模式概述 建造者模式是一种广泛使用的设计模式&#xff0c;在三方开源库和各种SDK中经常见到。建造者设计模式在四人帮的经典著作《设计模式&#xff1a;可复用面向对象软件基础》中被提及&#xff0c;它的…

Flink常见面试问题(附答案)

目录 基础篇1. 什么是Apache Flink&#xff1f;2. Flink与Hadoop的区别是什么&#xff1f;3. Flink中的事件时间&#xff08;Event Time&#xff09;和处理时间&#xff08;Processing Time&#xff09;有什么区别&#xff1f;4. Flink的容错机制是如何实现的&#xff1f;5. 什…