【C++学习第三讲】C++语句

2023-11-11

一、引入

C++程序是一组函数,而每个函数又是一组语句。C++有好几种语句,下面介绍其中的一些。下面提供了一些新的语句,声明语句创建变量赋值语句给该变量提供一个值。另外,该程序还演示了
cout的新功能。

#include<iostream>
int main(){
	using namespace std;
	int carrots;
	carrots = 25;
	cout << "I have ";
	cout << carrots;
	cout << " carrots ";
	cout << endl;
	carrots = carrots - 1;
	cout << "I have " << carrots << " carrots" << endl;
	return 0;
}

空行将声明语句与程序的其他部分分开。

这是C常用的方法,但在C++中不那么常见。下面是该程序的输出:

I have 25 carrots
I have 24 carrots

D:\C++Project\Project1\x64\Debug\Project1.exe (进程 39700)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

下面探讨这个程序。

二、声明语句和变量

计算机是一种精确的、有条理的机器。

要将信息项存储在计算机中,必须指出信息的存储位置和所需的内存空间。

在C++中,完成这种任务的一种相对简便的方法,是使用声明语句来指出存储类型并提供位置标签。

int carrots;

这条语句提供了两项信息:

  1. 需要的内存

  2. 该内存单元的名称。

具体地说,这条语句指出程序需要足够的存储空间来存储一个整数,在C++中用int表示整数。

编译器负责分配和标记内存的细节。

C++可以处理多种类型的数据,而int是最基本的数据类型。它表示整数—没有小数部分的数字。

C++的int类型可以为正,也可以为负,但是大小范围取决于实现。

完成的第二项任务是给存储单元指定名称。

在这里,该声明语句指出,此后程序将使用名称carrots来标识存储在该内存单元中的值。

Carrots被称为变量,因为它的值可以修改。

在C++中,所有变量都必须声明。

如果省略了声明,则当程序试图使用carrots时,编译器将指出错误。

事实上,程序员尝试省略声明,可能只是为了看看编译器的反应。这样,以后看到这样的反应时,便知道应检查是否省略了声明。

1. 为什么变量必须声明?

有些语言(最典型的是BASIC)在使用新名称时创建新的变量,而不用显式地进行声明。这看上去对用户比较友好,事实上从短期上说确实如此。问题是,如果错误地拼写了变量名,将在不知情的情况下创建一个新的变量。在BASIC中,ss程序员可能编写如下语句:
在这里插入图片描述

由于CastleDank是拼写错误(将r拼成了n),因此所作的修改实际上并没有修改CastleDark。这种错误很难发现,因为它没有违反BASIC中的任何规则。

然而,在C++中,将声明CastleDark,但不会声明被错误拼写的CastleDank,因此对应的C++代码将违反“使用变量前必须声明它”的规则,因此编译器将捕获这种错误,发现潜在的问题。

因此,声明通常指出了要存储的数据类型和程序对存储在这里的数据使用的名称

对上一个程序例子中,创建一个名为carrots的变量,它可以存储整数:

在这里插入图片描述
程序中的声明语句叫做定义声明(defining declaration)语句,简称为定义(definition)。

这意味着它将导致编译器为变量分配内存空间。在较为复杂的情况下,还可能有引用声明(reference declaration)。这些声明命令计算机使用在其他地方定义的变量。

通常,声明不一定是定义,但在这个例子中,声明是定义。

对于声明变量,C++的做法是尽可能在首次使用变量前声明它。

三、赋值语句

赋值语句将值赋给存储单元。例如,下面的语句将整数25赋给变量carrots表示的内存单元:

carrots = 25;

符号=叫做赋值运算符。

C++(和C)有一项不寻常的特性—可以连续使用赋值运算符。例如,下面的代码是合法的:
在这里插入图片描述
赋值将从右向左进行。

首先,88被赋给steinway;然后,steinway的值(现在是88)被赋给baldwin;然后baldwin的值88被赋给yamaha(C++遵循C的爱好,允许外观奇怪的代码)。

第二条赋值语句表明,可以对变量的值进行修改:

carrots = carrots - 1;

赋值运算符右边的表达式carrots – 1是一个算术表达式。计算机将变量carrots的值25减去1,得到24。然后,赋值运算符将这个新值存储到变量carrots对应的内存单元中。

四、cout新花样

到目前为止,学习的示例都使用cout来打印字符串,上述程序使用cout来打印变量,该变量的值是一个整数:

cout << carrots;

程序没有打印“carrots”,而是打印存储在carrots中的整数值,即25。实际上,这将两个操作合而为一了。首先,cout将carrots替换为其当前值25;然后,把值转换为合适的输出字符。

如上所示,cout可用于数字和字符串。这似乎没有什么不同寻常的地方,但别忘了,整数25与字符串“25”有天壤之别。

该字符串存储的是书写该数字时使用的字符,即字符3和8。程序在内部存储的是字符3和字符8的编码。要打印字符串,cout只需打印字符串中各个字符即可。

但整数25被存储为数值,计算机不是单独存储每个数字,而是将25存储为二进制数。

这里的要点是,在打印之前,cout必须将整数形式的数字转换为字符串形式。另外,cout很聪明,知道carrots是一个需要转换的整数。

与老式C语言的区别在于cout的聪明程度。在C语言中,要打印字符串“25”和整数25,可以使用C语言的多功能输出函数printf( )

在这里插入图片描述

撇开printf( )的复杂性不说,必须用特殊代码(%s和%d)来指出是要打印字符串还是整数

如果让printf( )打印字符串,但又错误地提供了一个整数,由于printf( )不够精密,因此根本发现不了错误。它将继续处理,显示一堆乱码。

cout的智能行为源自C++的面向对象特性。实际上,C++插入运算符(<<)将根据其后的数据类型相应地调整其行为,这是一个运算符重载的例子。

五、cout和printf( )

如果已经习惯了C语言和printf( ),可能觉得cout看起来很奇怪。

程序员甚至可能固执地坚持使用printf( )。但与使用所有转换说明的printf( )相比,cout的外观一点也不奇怪。更重要的是,cout还有明显的优点。它能够识别类型的功能表明,其设计更灵活、更好用。

另外,它是可扩展的(extensible)。也就是说,可以重新定义<<运算符,使cout能够识别和显示所开发的新数据类型。如果喜欢printf( )提供的细致的控制功能,可以使用更高级的cout来获得相同的效果。

六、其他C++语句

再来看几个C++语句的例子。

程序对前一个程序进行了扩展,要求在程序运行时输入一个值。

为实现这项任务,它使用了cin,这是与cout对应的用于输入的对象。

另外,该程序还演示了cout对象的多功能性。

#include<iostream>
int main(){
	using namespace std;
	int carrots;
	cout << "How many carrots do you have ?";
	cout << endl;
	cin >> carrots;
	cout << "Here are two more !";
	carrots = carrots + 2;
	cout << "Now you have " << carrots << "carrots" << endl;
	return 0;
}

下面是该程序的运行情况:

How many carrots do you have ?
10
Here are two more !Now you have 12carrots

D:\C++Project\Project1\x64\Debug\Project1.exe (进程 41100)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

该程序包含两项新特性:用cin来读取键盘输入以及将四条输出语句组合成一条。下面分别介绍它们:

1. 使用cin

上面的输出表明,从键盘输入的值(10)最终被赋给变量carrots。下面就是执行这项功能的语句:

cin >> carrots;

从这条语句可知,信息从cin流向carrots。

显然,对这一过程有更为正式的描述。就像C++将输出看作是流出程序的字符流一样,它也将输
入看作是流入程序的字符流。

iostream文件将cin定义为一个表示这种流的对象。

输出时,<<运算符将字符串插入到输出流中;

输入时,cin使用>>运算符从输入流中抽取字符。

通常,需要在运算符右侧提供一个变量,以接收抽取的信息(符号<<和>>被选择用来指示信息流的方向)。

与cout一样,cin也是一个智能对象。它可以将通过键盘输入的一系列字符(即输入)转换为接收信息的变量能够接受的形式。在这个例子中,程序将carrots声明为一个整型变量,因此输入被转换为计算机用来存储整数的数字形式。

2. 使用cout进行拼接

上面程序将4条输出语句合并为一条。

iostream文件定义了<<运算符,以便可以像下面这样合并(拼接)输出:

cout << "Now you have " << carrots << "carrots" << endl;

这样能够将字符串输出和整数输出合并为一条语句。得到的输出与下述代码生成的相似:

cout << "Now you have ";
cout << carrots;
cout << "carrots";
cout << endl;

根据有关cout的建议,也可以按照这样的方式重写拼接版本,即将一条语句放在4行上:

cout << "Now you have ";
     << carrots;
     << "carrots";
     << endl;

这是由于C++的自由格式规则将标记间的换行符和空格看作是可相互替换的。

当代码行很长,限制输出的显示风格时,最后一种技术很方便。

需要注意的另一点是:

Now you have 12carrots
Here are two more !

在同一行中。

这是因为前面指出过的,cout语句的输出紧跟在前一条cout语句的输出后面。即使两条cout语句之前有其他语句,情况也将如此。

七、类简介

看了足够多的cin和cout示例后,可以学习有关对象的知识了。

具体地说,本节将进一步介绍有关类的知识。

类是C++中面向对象编程(OOP)的核心概念之一。

类是用户定义的一种数据类型。

要定义类,需要描述它能够表示什么信息和可对数据执行哪些操作。

类之于对象就像类型之于变量。也就是说,类定义描述的是数据格式及其用法,而对象则是根据数据格式规范创建的实体。

换句话说,如果说类就好比所有著名演员,则对象就好比某个著名的演员。

下面更具体一些。前文讲述过下面的变量声明:

int carrots;

上面的代码将创建一个类型为int的变量(carrots)。也就是说,carrots可以存储整数,可以按特定的方式使用—例如,用于加和减。

现在来看cout。它是一个ostream类对象。ostream类定义(iostream文件的另一个成员)描述了ostream对象表示的数据以及可以对它执行的操作,如将数字或字符串插入到输出流中。同样,cin是一个istream类对象,也是在iostream中定义的。

类描述了一种数据类型的全部属性(包括可使用它执行的操作),对象是根据这些描述创建的实体。

知道类是用户定义的类型,但作为用户,并没有设计ostream和istream类。就像函数可以来自函数库一样,类也可以来自类库。ostream和istream类就属于这种情况。

从技术上说,它们没有被内置到C++语言中,而是语言标准指定的类。

这些类定义位于iostream文件中,没有被内置到编译器中。

类描述指定了可对类对象执行的所有操作。

要对特定对象执行这些允许的操作,需要给该对象发送一条消息。

例如,如果希望cout对象显示一个字符串,应向它发送一条消息,告诉它,“对象!显示这些内
容!”

C++提供了两种发送消息的方式:

  • 一种方式是使用类方法(本质上就是稍后将介绍的函数调用);
  • 另一种方式是重新定义运算符,cin和cout采用的就是这种方式。

因此,下面的语句使用重新定义的<<运算符将“显示消息”发送给cout:

cout << "I am not a crock"

在这个例子中,消息带一个参数—要显示的字符串:

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++学习第三讲】C++语句 的相关文章

  • 错误:表达式不可赋值三元运算符

    我有以下代码 MPLABX XC8 编译器给出此错误 错误 表达式不可分配 U1ERRIRbits RXFOIF uart1 oerr 1 uart1 oerr 0 这是相关代码部分 typedef union struct bool fe
  • copy_from_user() 错误:目标大小太小

    我正在为内核模块编写 ioctl 处理程序 我想从用户空间复制数据 当我编译禁用优化的代码时 O0 gflags 编译器返回以下错误 include linux thread info h 136 17 error call to bad
  • 使用管道在父级和子级之间传递整数值

    我对如何正确使用 pipeline 在两个进程之间传递整数值有点困惑 在我的程序中 我首先创建一个管道 然后分叉它 我假设我有 两个 管道 据我了解 这是我的任务 我的父母通过 for 循环检查某个操作的整数值 i 增加计数变量 并将值保存
  • 每个元素的 asp.net Web 表单自定义错误消息

    我创建了一个 Web 应用程序 表单 以及后端 SQL 插入和查询 目前我正在显示所有用户错误消息 div style padding 1em div
  • 从结构调用 C++ 成员函数指针

    我找到了有关调用 C 成员函数指针和调用结构中的指针的信息 但我需要调用结构内部存在的成员函数指针 但我无法获得正确的语法 我在类 MyClass 的方法中有以下代码片段 void MyClass run struct int MyClas
  • 如何以编程方式删除受信任的根证书颁发机构中的证书?

    我需要能够从组织中的每台电脑中删除特定的证书 是的 我可以逐个座位 但我要到周四才能完成 而且我没有人力逐个座位 是否有使用 C 的编程方式来执行此操作 我认为你不需要编写任何 C 看看certmgr exe del http msdn m
  • 我担心我添加了太多接口

    我正在构建我的领域模型并继续重构它 正如我所做的那样 我发现我喜欢接口 因为它允许我根据接口为具体类型创建可重用的方法 控制器 视图 但是 我发现每次向域实体之一添加新属性时 我都会创建一个接口 例如 我有一个会员状态从抽象继承的对象Ent
  • 如何在 C# 中以编程方式将行添加到 DataGrid?

    正如标题所述 我正在尝试使用 C 以编程方式将行添加到 DataGrid 但我似乎无法使其工作 这是我到目前为止所拥有的 I have a DataGrid declared as dg in the XAML foreach string
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • 维护 VS Test Project 中单元测试方法之间的上下文

    我想按顺序运行以下单元测试 使用随机数字的名称 密码等创建新客户 检索刚刚创建的客户并断言其属性包含相同的随机数 对同一用户调用 ForgotPassword 函数 并使用相同的随机数作为用户名 清楚地看到 我需要生成一次随机数 并在 3
  • 公交车公共交通算法

    我正在开发一个可以查找公交路线的离线 C 应用程序 我可以提取时间表 巴士 路线数据 我正在寻找适用于基本数据的最简单的解决方案 可以使用什么算法来查找从巴士站 A 到巴士站 B 的路线 是否有适用于 C Java 的开源解决方案 数据库的
  • 从图像创建半透明光标

    是否可以从图像创建光标并使其半透明 我目前正在拍摄自定义图像并覆盖鼠标光标图像 如果我可以将其设为半透明 那就太好了 但不是必需的 销售人员喜欢闪亮的 目前正在做这样的事情 Image cursorImage customImage Get
  • 如何在 C 中链接目标文件?失败并显示“架构 x86_64 的未定义符号”

    因此 我尝试在我的文件 file2 c 中使用另一个 C file1 c 文件中定义的函数 为了做到这一点 我包含了 file1 file1 h 的标头 但是 每当我尝试使用 gcc 编译文件时 我都会收到以下错误 Undefined sy
  • 使用 STL 流时如何格式化我自己的对象?

    我想将我自己的对象输出到 STL 流 但具有自定义格式 我想出了这样的东西 但由于我之前从未使用过 locale 和 imbue 所以我不知道这是否有意义以及如何实现 MyFacet 和operator 所以我的问题是 这是否有意义以及如何
  • MINIX内部碎片2

    我正在用 C 语言编写一些软件 它递归地列出给定目录中的所有文件 现在我需要计算出内部碎片 我花了很长时间研究这个问题 发现 ext2 上的内部碎片只发生在最后一个块中 我知道理论上你应该能够从索引节点号获得第一个和最后一个块地址 但我不知
  • 让 Windows 尝试读取文件

    我正在对 Windows 文件系统进行某种封装 当用户请求打开文件时 Windows 调用我的驱动程序来提供数据 在正常操作中 驱动程序返回缓存的文件内容 但是 在某些情况下 实际文件没有缓存 我需要从网络下载它 问题是是否有可能让 Win
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • C++ 中的析构函数

    我的 AB h 文件中有一个构造函数 class AB private int i public AB i 0 constructor AB i 0 destructor virtual void methodA unsigned int
  • 将同步 zip 操作转换为异步

    我们有一个现有的库 其中一些方法需要转换为异步方法 但是我不确定如何使用以下方法执行此操作 错误处理已被删除 该方法的目的是压缩文件并将其保存到磁盘 请注意 zip 类不公开任何异步方法 public static bool ZipAndS
  • 如何使用 Microsoft Graph API 更新 MailboxSettings

    我想从不同的日历更新邮箱设置 如何构建可以通过 Microsoft Graph 更新 MailboxSetting 的请求 这是我的代码示例 但有例外 代码示例 User obj GraphServiceClient Users roomC

随机推荐

  • 卫星通信系统概述

    卫星通信系统指通过在轨人造卫星作为中继站对无线电信号进行转发 实现地面及空间等用户之间信息传输的系统 卫星通信系统组成包括空间段及地面段 系统组成如图所示 其中空间段主要指在轨卫星 对在轨卫星进行操控的地面站 这些地面站主要实现跟踪 遥测
  • 《QDebug 2023年8月》

    一 Qt Widgets 问题交流 1 获取 QWidget 当前所在屏幕区域 本来以为 QWidget 的 screen 接口返回的是组件自己所在屏幕的 QSreen 实测是所属 Window 所在的屏幕 如果 Window 跨屏了两者所
  • Android 内存分析工具

    Dalvik 虚拟机支持垃圾收集 但是这不意味着你可以不用关心内存管理 你应该格外注意移动设备的内存使用 手机和平板的内存空间是受到限制的 在这篇文章里面 我们来看看Android SDK里面的一些内存剖析工具 profiling tool
  • Windows11安装Vim编辑器配置指南

    Vim简介 Vim 是一个高度可配置的文本编辑器 旨在让创建和更改任何类型的文本变得非常高效 大多数 UNIX 系统和 Apple OS X 都将它作为 vi 包含在内 用惯了Linux中的Vim编辑器 如果需在Windows的cmd终端中
  • form表单的单输入框回车出现同步提交事件处理

    问题 form表单中如果只有一个输入框 在输入时按Enter回车键会出发默认事件自动提交表单 该交互是同步发生的 会导致页面刷新 解决思路 有三种解决思路 1 增加input输入框的数量 如果form表单中不止一个input输入框 那么该表
  • 基于Python的餐厅点餐系统-订餐食堂预约Python爬虫安装数据分析与可视化计算机毕业设计

    更多项目资源 最下方联系我们 目录 一 项目技术介绍 二 项目配套文档 部分内容 资料获取 一 项目技术介绍 该项目含有源码 文档 PPT 配套开发软件 软件安装教程 项目发布教程 包运行成功以及课程答疑与微信售后交流群 送查重系统不限次数
  • 《管理的套路》图解(二)

    13 Iceburg冰山模型 备注 在组织行为学中 冰山模型从三个层面来描述一个人 A态度 深层 B行为 表层 C能力 中间层 14 Burke Litwin组织变革模型 备注 除了考虑外部环境因素 组织和个人绩效因素以及沟通反馈外 还要考
  • 【python】【kNN】【OCR】用python实现字符识别

    一 问题 OCR 光学字符识别 是机器学习重要的应用之一 一般要经过二值化 去噪 倾斜校正 特征抽取 字符切割 字符识别 后处理等过程 其中难度最大的是字符切割 最关键的步骤是字符识别 一般进行字符识别的方法有kNN SVM CNN等方式
  • NUMA模式

    NUMA模式 补充经常听师兄们提到一个词NUMA模式 NUMA架构产生的背景 早期的计算机中 内存控制器在北桥中 所有CPU对内存的访问都要通过北桥来完成 此时所有CPU访问内存都是 一致的 如下图所示 这样的架构称为UMA Uniform
  • GPT3.5插件免费使用方法(无须科学上网)

    1 下载并安装微软Edge浏览器 2 在浏览器输入 edge extensions 或者在页面操作 3 在扩展页面搜索 webtab 插件 4 启用插件 在浏览器输入 edge extensions 回到扩展管理页面 随后会自动进入页面 选
  • 图的拓扑序列

    拓扑序列 拓扑序是按照点的先后顺序排列的 拓扑序列满足以下两点 1 每个顶点在序列中出现且只出现一次 2 若存在一条从顶点 A 到顶点 B 的路径 那么在序列中顶点 A 出现在顶点 B 的前面 拓扑序列只存在于有向无环图中 可以理解成一个将
  • replace和replaceAll区别

    1 replace的参数是char和CharSequence 即可以支持字符的替换 也支持字符串的替换 CharSequence即字符串序列的意思 说白了也就是字符串 2 replaceAll的参数是regex 即基于规则表达式的替换 比如
  • 浅谈一下Python的现状、发展前景以及Python的就业岗位(含趋势)

    在面对职业选择时我们难免纠结 徘徊 不知道去哪能走多远 我们没有办法只考虑当下 无视未来 当下Python工程师正处于人才需求旺盛 供应短缺的时期 工资一路上涨 假如 即便选择了目前火热的Python编程 那你需要先来了解一下Python的
  • 知识产权贯标补贴政策查询大全及怎么申请,奖励20万

    华夏泰科小编认为知识产权贯标旨在促进企业知识产权创造 运用 保护能力提高 使管理工作制度化 规范化 常规化 整体推进全省企业知识产权管理水平有效提升 申请后可以提升企业无形资产价值 巩固企业市场地位 可向科技主管部门申请战略推进项目 专利实
  • win10下设置maven环境变量

    一 先去maven官网 http maven apache org download cgi 下载压缩包 下拉页面可以看到好多版本 注意下载的版本为红色标注版本 apache maven 3 5 0 bin zip 点击下载即可 二 将下载
  • JSR303(一) 简介

    1 简介 数据校验是任何一个应用程序都会用到的功能 无论是显示层还是持久层 通常 相同的校验逻辑会分散在各个层中 这样 不仅浪费了时间还会导致错误的发生 译注 重复代码 为了避免重复 开发人员经常会把这些校验逻辑直接写在领域模型里面 但是这
  • 关于$'\r': command not found错误的一点体会

    今天运行一个其他组开发的jar包 这个jar包由于运行参数是通过命令行的方式输入的 所以需要运行一个shell脚本来启动 启动脚本类似这样 bin bash jdbc driverClassName com mysql jdbc Drive
  • 力扣-->#剑指Offer 897 . 递增顺序搜索树(E)

    class Solution TreeNode curr public TreeNode increasingBST TreeNode root TreeNode first new TreeNode 1 用first 来记录curr的初始
  • 途客圈创业记--读书笔记

    一 初创公司股权结构 2011年6月公司创立 自筹启动资金50万 1 陈天和Alex 每人出资25万元 总计50万元 作为启动资金 2 陈天 CTO兼董事长 股份60 因为是想法的发起人 且在实现这个想法的过程中 Alex CEO 股份40
  • 【C++学习第三讲】C++语句

    目录 C 语句 一 引入 二 声明语句和变量 1 为什么变量必须声明 三 赋值语句 四 cout新花样 五 cout和printf 六 其他C 语句 1 使用cin 2 使用cout进行拼接 七 类简介 一 引入 C 程序是一组函数 而每个