第一章 顺序结构程序设计(1)

文章目录

  • [1.1 程序输入与变量](#1.1 程序输入与变量)
  • [1.2 整数与算术运算](#1.2 整数与算术运算)

从这个章节开始,我们将学习使用 C++ 解决一些数学问题,掌握计算机解决问题的流程。程序结构在这个过程中有着至关重要的作用,我们将从最简单的顺序结构开始,逐步学习程序的三大结构:顺序结构、分支结构、循环结构。

首先我们要弄明白计算机可以做什么,不可以做什么。想象你现在进入了一家餐厅,需要服务员给你倒一杯水解渴。如果你面对的是人类服务员,你只需要告诉他"请帮我倒一杯水"就可以了。那么如果你现在面对的是一个机器人呢?如果直接告诉它你需要一杯水,它或许并不知道怎么做。你大概需要告诉它"走到厨房,找到一个干净的杯子,找到一个装有热水的水壶,将水壶中的水倒入刚刚找到的干净杯子,将装有热水的杯子端到我面前"。当然了,这里面还有很多的细节需要让它知晓,比如厨房在哪里,如何走到厨房,什么是干净的杯子,什么是水壶等等。至此,我们可以做一个简单的总结,如果需要计算机做一些事,应该告诉它如何去做,而不是直接告诉它我们需要什么,原因在于计算机不具备人类的思考能力,它甚至都不知道你的指令过程会完成什么样的任务。

【小贴士】计算机可以完成清晰明确的指令过程,但是无法思考你的需求如何完成。

在上面的例子中,我们需要告诉机器人如何按照顺序,一步一步完成任务,这样的程序执行过程就称为顺序结构。

1.1 程序输入与变量

前面掌握了在 C++ 中如何输出信息,并且掌握了如何让输出信息换行。接下来我们学习如何输入信息,考虑下面这个问题。

【D1015 [OpenJudge] 字符三角形】给定一个字符,用它构造一个底边长 5 个字符,高 3 个字符的等腰字符三角形。

这里会由题目给定一个字符,程序要获取到这个字符信息,就需要用到输入。此外,获取的信息应当保存到计算机中,需要一个容器来承接。我们将程序中用于接收并存储信息的容器称为变量,其本质是内存中一段连续的空间。

C++ 是一个特别注重数据类型的语言(强类型语言),不同类型的信息需要使用对应类型的变量来存储。C++ 中存储字符信息的数据类型是 char(字符型),于是我们可以从内存中申请一段空间作为 char 类型的容器,为了便于在程序中识别和使用,应当给这段空间起一个名字,称为变量名 。不难想到,当我们需要使用一个容器的时候,首先得拥有这个容器,也就是说,变量必须在声明之后才能使用

变量名需要符合 C++ 的语法规则,才能够被编译器正确识别并翻译为机器指令。具体规则有如下 4 条:

  • 变量名只能包含大写字母、小写字母、数字和下划线;
  • 变量名的第一个字符不能是数字;
  • 同一个字母的大写和小写声明的两个变量是不同的,即大小写敏感;
  • 不能使用关键字作为变量名,所谓关键字就是对 C++ 编译器有着特殊含义的字符组合,比如用于表明字符型的 char,用于表明命名空间的 namespace

【小贴士】此外,变量命名还有一些约定俗成的建议,这些建议都是为了增加代码的可读性:变量名要见名知意;多个单词组合成一个变量名时,使用驼峰命名法(单词首字母大写)或蛇形命名法(单词之间添加下划线);尽可能不要使用单词缩写,除非这些缩写是众所周知的。

下面给出解决这个问题的完整代码。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    char ch;
    cin >> ch;

    cout << "  " << ch << endl;
    cout << " " << ch << ch << ch << endl;
    cout << ch << ch << ch << ch << ch << endl;

    return 0;
}

char ch; 这条语句的作用是声明一个字符型变量,变量名为 ch。数据类型和变量名之间需要用空格隔开。

cin >> ch; 这条语句的作用是从输入流中读取一个字符信息,并存储到变量 ch 中,其中 >> 称为流提取运算符。

编译运行这个程序,发现程序并没有马上输出结果。这是因为程序中存在输入语句,根据程序执行的顺序,需要先通过输入读取一个字符之后才能执行下面的输出语句。输入也在控制台进行,需要注意的是,在输入结束之后,需要按下回车键告诉程序输入已经结束。

【小贴士】第 3 条 cout 语句的末尾也输出了换行符 endl,这并不是必须的,只是为了增加代码的可读性,并方便后续增加新的输出语句,避免输出结果的粘连。程序中的空白行、运算符两边的空格,都是为了增加代码的可读性而形成的程序风格,尽管这并不是语法规则中的规定,但是强烈建议养成良好的程序风格,可以让你的竞赛之路少一些烦恼。

下面我们通过解决一个新问题来学习新的数据类型。

【D1194 [22 年 9 月一级] 指定顺序输出】依次输入 3 个整数 a a a、 b b b、 c c c,将他们以 c c c、 a a a、 b b b 的顺序输出。

int(整型)是 C++ 中存储整数信息的数据类型,我们可以在程序中使用关键字 int 来声明存储整数的变量。

注意到这个问题需要输入多个数据,与 cout 类似,cin 可以配合多个流提取运算符做连续输入。在控制台中输入多个数据时,数据之间需要使用空格隔开,用来告诉程序这是多个不同的数据。事实上,多个数据之间用 T a b \tt Tab Tab 或回车 隔开都是可以的,这是因为 cin 在输入时会自动过滤不可见字符。

下面给出解决这个问题的完整代码。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    int a, b, c;
    cin >> a >> b >> c;

    cout << c << " " << a << " " << b << endl;

    return 0;
}

int a, b, c; 这条语句同时声明了 3 个整型变量,这是符合 C++ 语法规则的。在我们需要声明多个相同类型的变量时,只需要用逗号将多个变量名分隔开即可。为了增强代码的可读性,可以在逗号后面键入一个空格。

本节习题

1.2 整数与算术运算

在掌握了输入语句之后,就可以开始解决一些数学问题了,先看下面的问题。

【P1000 A+B Problem】输入两个整数 a a a、 b b b,输出它们的和。

C++ 中做算术运算的逻辑与数学上基本一致,加减法运算的符号与数学上也是一致的(+-),乘除法运算符略有不同(*/)。解决这个问题的完整代码如下。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    int a, b;
    cin >> a >> b;

    cout << a + b;

    return 0;
}

cout << a + b; 这条语句的作用是输出变量 ab 中的数值相加的结果。也就是说 cout 可以直接输出算术运算的结果,事实上 cout 可以输出任意表达式的值。

所谓表达式,可以理解为由运算符与相应的操作数组合而成的式子,比如 a + b a + b a+b 可以称为加法表达式,表达式的值就是这个表达式的计算结果。C++ 中表达式的定义是比较宽泛的,单个变量也可以称为表达式。

【D1016 [20 年 12 月一级] 计算 (a+b)×(c-b) 的值】给定 3 个整数 a a a、 b b b、 c c c,计算表达式 ( a + b ) × ( c − b ) (a+b)×(c-b) (a+b)×(c−b) 的值。

数学上的圆括号在程序中仍适用,不过在涉及到多个括号嵌套的时候,只能使用圆括号,其它两种括号有别的用途,这个会在之后的内容中说明。解决这个问题的完整代码如下。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    int a, b, c;
    cin >> a >> b >> c;

    cout << (a + b) * (c - b);

    return 0;
}

【D1269 [2024 年 6 月一级] 九牛一毛】这是一道脑筋急转弯题:猪肉一斤 15 元,鸡肉一斤 20 元,那么一毛钱能买多少头牛?答案是 9,因为 "九牛一毛"。本题就请你按照这个逻辑,计算一下 n n n 元钱能买多少斤猪肉、多少斤鸡肉、多少头牛。

显然猪肉的数量应该是 n n n 除以 15 的整数商。C++ 中的除法运算除了符号与数学上不同,计算规则也有差别:当被除数和除数都是整数时,计算结果是整数商 。于是猪肉的数量在 C++ 中就是除法表达式 n / 15 的值,鸡肉类似,解决该问题的完整代码如下。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;

    cout << n / 15 << " " << n / 20 << " " << n * 10 * 9 << endl;

    return 0;
}

【G1085 [GESP2403 一级] 小杨买书】小杨同学积攒了一部分零用钱想要用来购买书籍,已知一本书的单价是 13 元,请根据小杨零用钱的金额,编写程序计算最多可以购买多少本书,还剩多少零用钱。

假设小杨共有 n n n 元零用钱,最多可以购买书籍的数目就是 n n n 除以 13 的整数商,剩余的零用钱数目应该是 n n n 除以 13 13 13 的余数。在 C++ 中可以用取余运算(%)求出整数除法的余数,优先级与乘除法运算相同,于是解决该问题的完整代码如下。

cpp 复制代码
#include <iostream>
using namespace std;

int main() 
{
    int n;
    cin >> n;

    cout << n / 13 << endl;
    cout << n % 13 << endl;

    return 0;
}

【D1092 [21 年 9 月一级] 计算乘积/长方形面积】给出一个长方形的长和宽,求该长方形的面积。假设长为 a a a,宽为 b b b,则面积 S = a × b S=a×b S=a×b, 0 < a , b < 10 8 0<a,b<10^8 0<a,b<108。

乍一看这个问题是比较容易解决的,然而使用 int 型变量存储边长,计算出的结果并非完全正确。这是因为 C++ 中 int 型数据能够表示的整数范围并非无限大,而是有着明确上下限的,具体来说,int 型能够表示的整数范围为 − 2147483648 ∼ 2147483647 -2147483648\sim 2147483647 −2147483648∼2147483647。C++ 中表达式的值与参与运算的数据类型是相关的,尽管我们可以用 int 型变量存储边长,但是计算出的面积有可能超出 int 型能够表示的范围。

显然这里需要一种能够表示更大整数范围的数据类型,long long 类型可以满足需求,它能够表示的数据范围约为 − 9.2 × 10 18 ∼ 9.2 × 10 18 -9.2×10^{18}\sim 9.2×10^{18} −9.2×1018∼9.2×1018。

前面我们了解到计算机唯一可识别和执行的语言是二进制语言,这是因为计算机中所有的数据信息都是用二进制表示的。一个二进制信息称为位( b i t \tt bit bit),这是计算机存储信息的最小单位 。然而这个单位太小了,于是人们将 8 位作为一个整体,称为字节( B y t e \tt Byte Byte),这是计算机存储和处理数据的基本单位。不同数据类型表示的数据范围不同,正是因为给它们分配的字节数不同。

  • char 类型占用 1 字节,由于每个 b i t \tt bit bit 可以表示两种不同的信息,于是一个字节可以表示 256( 2 8 2^8 28)种不同的信息,换言之,char 类型可以表示 256 个不同的字符。
  • int 类型占用 4 字节,由于整数分为正数、负数、零,正负数各自占用约一半的范围,但是由于零的存在,能够表示的正数比负数少 1 个,于是 int 型可以表示的数据范围就是 − 2 31 ∼ 2 31 − 1 -2^{31}\sim 2^{31}-1 −231∼231−1。
  • long long 类型占用 8 字节,表示范围为 − 2 63 ∼ 2 63 − 1 -2^{63}\sim 2^{63}-1 −263∼263−1。

【小贴士】事实上,还有两种用于表示整数的类型,不过并不常用,而且不同编译器的实现方式也不尽相同,这里仅做了解即可。

  • short 类型占用 2 ∼ \sim ∼ 4 字节,不超过 int 类型的表示范围,一般用于表示范围更小的整数,在 g++ 编译器中实现为 2 字节。
  • long 类型占用 4 ∼ \sim ∼ 8 字节,不低于 int 类型的表示范围,不超过 long long 类型的表示范围,在 g++ 编译器中实现为 4 字节。

解决这个问题的完整代码如下。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    long long a, b;
    cin >> a >> b;

    cout << a * b;

    return 0;
}

本节习题

相关推荐
老鼠只爱大米2 小时前
LeetCode经典算法面试题 #41:缺失的第一个正数(位置交换法、标记法等多种方法详解)
算法·leetcode·原地哈希·缺失的第一个正数·算法面试·位图法·集合哈希法
星火开发设计2 小时前
变量与常量:C++ 中 const 关键字的正确使用姿势
开发语言·c++·学习·const·知识
hetao17338372 小时前
2026-01-14~15 hetao1733837 的刷题笔记
c++·笔记·算法
百度搜不到…2 小时前
背包问题递推公式中的dp[j-nums[j]]到底怎么理解
算法·leetcode·动态规划·背包问题
一起养小猫2 小时前
LeetCode100天Day13-移除元素与多数元素
java·算法·leetcode
a***59263 小时前
C++跨平台开发:挑战与解决方案
开发语言·c++
ACERT3333 小时前
10.吴恩达机器学习——无监督学习01聚类与异常检测算法
python·算法·机器学习
诗词在线3 小时前
从算法重构到场景复用:古诗词数字化的技术破局与落地实践
python·算法·重构
不穿格子的程序员3 小时前
从零开始写算法——二叉树篇7:从前序与中序遍历序列构造二叉树 + 二叉树的最近公共祖先
数据结构·算法