第02讲:语言基础

《计算机程序设计》

苏醒

计算机学院计算机研究所编译系统研究室

课前准备

  • 在WSL Ubuntu中建立一个专门的目录用于课上练习,如~/course
$ mkdir ~/course
  • 打开VSCode并连接到WSL,打开此目录并新建文件,如~/course/main.cpp
  • 编辑main.cpp,随堂编程练习的代码请直接在此文件中编辑
main.cpp
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
  // ============= begin =============

  // =============  end  =============
  return 0;
}

温故

测一测

C/C++程序的开发过程是?

  1. 编辑、编译、运行、调试
  2. 编辑、编译、运行、测试
  3. 编辑、编译、链接、运行
  4. 编辑、编译、链接、调试

炸弹轨迹问题

编程求解

轰炸机在高度\(h=5000m\)处朝向目标以速度\(v=200m/s\)匀速飞行,设重力加速度\(g=9.8m/s^2\)为常数,忽略空气阻力,求给定时间后投弹点的位置\((x,y)\),结果仅保留整数部分

轰炸机投弹轨迹

学习目标

  • 学习内容
    • 标识符
    • 类型系统
    • 常量与变量
    • 表达式
    • 输入输出初步

学习目标

  • 构造合法、简洁、清晰的变量名
  • 掌握类型系统的构成并为变量选择合适类型
  • 正确书写不同类型的字面量、定义变量与符号常量
  • 综合运用各种运算符实现复杂的计算功能
  • 使用C++的输入输出流完成数据的输入输出

运用本次课所学内容,完成炸弹轨迹问题的求解!

1. 标识符

标识符

  • 标识符用于表示名字的概念
    • 变量名
    • 常量名
    • 函数名
    • 标号名(goto 语句的目标)
  • 标识符的组成
    • 字母(a–z/A–Z)、数字(0–9)、下划线(_)
    • 不可以数字作为开头
    • C++标识符区分大小写

考考你

C++标识符的构成规则与Python是否相同?

关键字

  • 关键字也称为“保留字”,在语言中具有特殊意义
    • C++ 关键字不可作为标识符

C++关键字

标识符练习

测一测

下列哪些是合法的C++标识符?

  1. Nudt
  2. Why?
  3. _decision
  4. _
  5. 3bodies
  6. for

2. 类型系统

位、字节与内存地址

  • 计算机以二进制形式表示数据
    • \((11)_{10} \leftrightarrow (1011)_2\)
    • \((12)_{10} \leftrightarrow (1100)_2\)
  • 二进制中的单个位称为位(bit)
  • 8个连续二进制位构成一个字节(byte)
  • 内存以字节为单位线性编址,每个字节具有唯一地址

内存编址

考考你

若地址使用32位整数表示,则系统最大支持多大的内存?

数据的存储

基础数据(整型数、浮点数、字符等)在内存中通常存储为连续的字节

  • 整数类型
    • 8位整型数(1字节)
    • 16位整型数(2字节)
    • 32位整型数(4字节)
    • 64位整型数(8字节)
  • 浮点类型
    • 半精度浮点数(2字节)
    • 单精度浮点数(4字节)
    • 双精度浮点数(8字节)
    • 四精度浮点数(16字节)

基础数据类型

C++ 定义了一个简单而完备的基础类型系统

C++基础数据类型

字符类型

  • 字符类型表示单个字符,长度为1字节
    • signed char/unsigned char 分别表示有符号/无符号字符类型
    • char是否有符号,与硬件平台与编译器实现相关
C++字符类型
char a = 'a';
unsigned char b = 'b';
signed char c = 0;

考考你

一个C++字符最多可编码多少个字符?

ASCII码表

布尔类型

  • 布尔类型bool用于表示逻辑值,即“真”“假”
    • 布尔类型仅有两个取值:truefalse
  • 布尔类型支持的运算包括
    • 逻辑运算:与、或、非
    • 关系运算:等价性比较
C++布尔类型
bool t = true;
bool f = false;
bool r1, r2, r3;
// 与、或、非运算,两种写法
r1 = t and f; r2 = t or f; r3 = not t; // 关键字
r1 = t && f; r2 = t || f; r3 = !t; // 运算符
// 等价性比较
r1 = (t == true);
r1 = (t != false);

考考你

在布尔类型及其逻辑运算的支持方面,C++与Python有何异同?

整数类型

  • 整型的分类
    • 根据存储长度,分为shortintlonglong long四类
    • 根据有无符号,分为有符号signed与无符号两类unsigned
    • 共计8种组合(教材表2-2)
  • 整数支持的运算包括
    • 算数运算:加、减、乘、除、取模
    • 关系运算:大小比较
    • 位运算:以每个bit为单位进行逻辑运算

整数类型的位宽
C++整数类型
// 整数类型
unsigned int b = 2u; long c = 3l; unsigned long long d = 4ull;
int x = 1, y = 2, z;
z = x + y; z = x - y; z = x * y; z = x / y; z = x % y;  // 算术运算
bool r = x > y; r = x < y; r = x == y; r = x != y;      // 关系运算
z = x & y; z = x | y; z = x ^ y; z = ~x; z = x << 1; z = x >> 1; // 位运算

考考你

C++类型系统中,整数类型的长度与平台相关,这样的设计好吗?

温馨提示

整数类型的长度与平台相关,若需要跨平台的整数类型定义,C++标准库在cstdint中定义了长度明确的整数类型

  • 有符号整型int8_t/int16_t/int32_t/int64_t
  • 无符号整型uint8_t/uint16_t/uint32_t/uint64_t

浮点类型

  • 浮点型的分类
    • 按存储长度分为三种:单精度float、双精度double与扩展精度long double
    • 浮点型均为有符号类型
  • 浮点型支持的运算包括
    • 算数运算:加减乘除
    • 关系运算:大小比较
    • 数学函数:三角函数、指数函数、对数函数等(C++标准库)
C++浮点类型
// 浮点类型
float a = 1.0f; double b = 2.0; long double c = 3.0l;
float x = 1.0f, y = 2.0f, z;
z = x + y; z = x - y; z = x * y; z = x / y;         // 算术运算
bool r = x > y; r = x < y; r = x == y; r = x != y;  // 关系运算
z = sin(x); z = exp(x); z = log(x);                 // 数学函数

长度与对齐

  • 长度:存储数据需要的字节数,使用sizeof操作符获取
  • 对齐:数据在内存中的首地址必须是某个值的整倍数,使用alignof操作符获取
  • C++基础类型的长度和对齐与平台相关
primitive-type-size-align.cpp
cout << setw(12) << "" << setw(8) << "size" << setw(8) << "align" << '\n';
cout << setw(12) << "bool" << setw(8) << sizeof(bool) <<setw(8) << alignof(bool) << '\n';
cout << setw(12) << "char" << setw(8) << sizeof(char) <<setw(8) << alignof(char) << '\n';
cout << setw(12) << "short" << setw(8) << sizeof(short) <<setw(8) << alignof(short) << '\n';
cout << setw(12) << "int" << setw(8) << sizeof(int) <<setw(8) << alignof(int) << '\n';
cout << setw(12) << "long" << setw(8) << sizeof(long) <<setw(8) << alignof(long) << '\n';
cout << setw(12) << "long long" << setw(8) << sizeof(long long) <<setw(8) << alignof(long long) << '\n';
cout << setw(12) << "float" << setw(8) << sizeof(float) <<setw(8) << alignof(float) << '\n';
cout << setw(12) << "double" << setw(8) << sizeof(double) <<setw(8) << alignof(double) << '\n';
cout << setw(12) << "long double" << setw(8) << sizeof(long double) <<setw(8) << alignof(long double) << '\n';

取值范围

整型与浮点类型的取值范围是有限的,浮点类型的精度也是有限的

基础数据类型取值范围

取值范围

  • 标准头文件climitscfloat中定义了基础类型取值范围、精度相关的常量
primitive-type-limits.cpp
cout << setw(12) << "" << setw(24) << "min" << setw(24) << "max" << '\n';
cout << setw(12) << "char" << setw(24) << SCHAR_MIN <<setw(24) << SCHAR_MAX << '\n';
cout << setw(12) << "short" << setw(24) << SHRT_MIN <<setw(24) << SHRT_MAX << '\n';
cout << setw(12) << "int" << setw(24) << INT_MIN <<setw(24) << INT_MAX << '\n';
cout << setw(12) << "long" << setw(24) << LONG_MIN <<setw(24) << LONG_MAX << '\n';
cout << setw(12) << "long long" << setw(24) << LLONG_MIN <<setw(24) << LLONG_MAX << '\n';
cout << setw(12) << "float" << setw(24) << FLT_MIN <<setw(24) << FLT_MAX << '\n';
cout << setw(12) << "double" << setw(24) << DBL_MIN <<setw(24) << DBL_MAX << '\n';
cout << setw(12) << "long double" << setw(24) << LDBL_MIN <<setw(24) << LDBL_MAX << '\n';

类型系统练习

测一测

  • Python整数类型能否表示任意整数?
  • C++整数类型能否表示任意整数?
  • C++浮点类型能否表示任意有理数?

测一测

下面的程序会输出什么?

short-overflow.cpp
short x = 32767; // 0b 0111 1111 1111 1111
x = x + 1;
cout << x << endl;

考考你

与Python不同,C++类型系统中,有不同长度的整数与浮点数类型,这是为什么?二者各有何优劣?

3. 常量与变量

常量与变量

  • 在程序执行过程中,值不能改变的数据对象称为常量
  • 除常量外,在程序执行过程中取值可以发生变化的数据对象,称为变量

考考你

如下积分公式中,常量和变量分别是?

\[\int_3^t f(x)dx\]

变量

  • 变量的六个属性

---
config:
  look: handDrawn
  themeVariables:
    fontSize: 20px
---

mindmap
Root(变量)
  变量名:标识符
  类型:数据类型
  值:存储的数据
  地址:内存中的位置
  作用域:变量的可见范围
  生存周期:变量的有效时间

属性一:变量名

  • 合法的标识符
  • 命名风格
    • camalCase:首字母小写,后续单词首字母大写,例如aGoodeName, heightOfTree
    • snake_case:单词之间使用下划线分隔,例如lovely_students, stupid_teacher

属性二:类型

  • C++变量必须先声明、再使用
  • 变量的类型决定了变量的取值范围存储方式(长度与对齐)

考考你

内存中变量cs之间为什么有一个“洞”?声明一个变量但不做初始化,这个变量的值是什么?

属性三:值

  • 变量对应的数据本身,取值范围由类型决定

属性四:地址

  • 变量对应存储空间的位置,由编译器分配

明察秋毫:地址与值

  • 变量的存储空间像一栋房屋
    • 地址是房屋的门牌号是房屋内的物品
    • 变量的地址在程序执行期间不会发生变化
    • 变量的随着程序运行可以发生变化

属性四/五:生存周期/作用域

且听下回分解!

变量声明
// 变量声明
char c;
short s;
int i = 1; // 初始化

变量声明的本质:在内存中分配存储空间

常量

常量分为字面量符号常量

常量的类别

整型字面量

  • 整型字面量由整数字面量+整数后缀组成
整数字面量
进制 示例 说明
十进制 789 非0前缀的十进制整数字面量
八进制 0123 0前缀的八进制整数字面量
十六进制 0xFF 0x/0X前缀的十六进制整数字面量

考考你

C++八进制整数字面量写法与Python有何区别?

整数后缀
后缀 示例 说明
123 int
u 123u unsigned int
l 123l long
ll 123ll long long
ul 123ul unsigned long
ull 123ull unsigned long long

常量的类别
整型字面量
int a = 789;
unsigned int b = 789u;
long c = 077l;
long long d = 077ll;
unsigned long e = 0xFFul;
unsigned long long f = 0xFFull;

浮点字面量

  • 浮点字面量由浮点数字面量+浮点数后缀组成
浮点数字面量
表示法 示例 说明
小数 3.14, .5, 3. 小数点前后至少有一个数字
指数 3.14e2, -.3e-4 使用e/E分隔有效数字部分与指数部分
浮点数后缀
后缀 示例 说明
3.14 double
f 3.14f float
l 3.14l long double

常量的类别
浮点字面量
float a = 3.14f;
double b = 3.14e2;
long double c = 3.e-10l;

布尔字面量

  • 布尔字面量仅有两个取值
    • true
    • false
布尔面量
bool t = true;
bool f = false;

常量的类别

字符字面量

  • 字符字面量写法为使用单引号括起单个字符,如's'
  • 特殊字符需要使用转义字符\进行转义

转义字符

常量的类别
字符字面量
char a = 'a';
char newline = '\n';
char tab = '\t';

字符串字面量

  • 字符串字面量写法为使用双引号括起的字符序列,如"Hello World!"
    • 字符串内部可包含转义字符,如"Hello\nWorld!"
    • 字符串长度可以为 0,即空字符串""

考考你

字符串是如何在内存中存储的?

C++字符串在内存中的存储方式

常量的类别
字符串字面量
const char* hello = "Hello World!\n";
const char* empty = "";

符号常量

  • 符号常量是值不可改变的命名符号,使用const关键字修饰
  • 符号常量可以在程序中多次引用
    • 如需修改,则只需要修改一处代码
符号常量
const double PI = 3.141592653

void circle(double r) {
  double diameter = 2 * r;
  double area = PI * r * r;
  double circ = 2 * PI * r;
  cout << "直径: " << diameter << endl;
  cout << "面积: " << area << endl;
  cout << "周长: " << circ << endl;
}

常量的类别

温馨提示

建议常量采用全大写命名,如PINUM_CPUS

常量与变量练习

测一测

下列哪些是合法的C++字符串?

  1. "Hello World!"
  2. 'Pretty cool!'
  3. "I'm a student."
  4. "A "孙悟空" style hero"

常量与变量练习

考考你

请定义炸弹轨迹问题中的常量与变量

轰炸机在高度\(h=5000m\)处朝向目标以速度\(v=200m/s\)匀速飞行,设重力加速度\(g=9.8m/s^2\)为常数,忽略空气阻力,求给定时间后投弹点的位置\((x,y)\),结果仅保留整数部分

常量与变量练习
// ----------- begin -----------//
// 在这里定义炸弹落点问题中的常量与变量


// ----------- end -------------//

cout << g << ' ' << v << ' ' << x << ' ' << y << '\n';

4. 表达式

表达式

  • 表达式是具有值语义的语言结构,如
    • 常量与变量的引用,如x1.2e10
    • 算数运算的结果,如x+ya*3
    • 类型转换的结果,如(int)2.3
    • 函数调用的结果,如sin(x)
  • 表达式的两个属性

---
config:
  look: handDrawn
  themeVariables:
    fontSize: 20px
---
mindmap
Root(表达式)
  类型
  值

表达式的类别

  • 基本表达式指结构上不可分的表达式,具有原子性
    • 字面量:3'c'1e-2"hello"true
    • 符号常量:PI
    • 变量:xradius
  • 复合表达式操作符操作数构成
    • 算数表达式:x+ya*3
    • 逻辑表达式:~aa && b
    • 函数调用:sin(x)printf("Hello")

注意

复合表达式中的操作数本身亦须是表达式

---
config:
  look: handDrawn
  themeVariables:
    fontSize: 28px
---
flowchart LR
  表达式 --> 基本表达式
  表达式 --> 复合表达式
  基本表达式 --> 常量
  基本表达式 --> 变量
  复合表达式 --> 运算符
  复合表达式 --> 类型转换
  复合表达式 --> 函数调用

表达式的类别

运算符

  • 算数运算符:+-*/%
  • 逻辑运算符:&&||!
  • 关系运算符:==!=><>=<=
  • 位运算符:&|^~<<>>
  • 赋值运算符:=+=-=*=
  • 自增自减运算符:++--
  • 逗号运算符:,
  • 条件运算符:? :
  • 特殊运算符:sizeofnew

C++运算符

运算符优先级与结合性

  • 优先级决定不同操作符的计算顺序
    • precedence值越小,优先级越高
    • a+b*c等价于a+(b*c)
  • 结合性决定同优先级操作符的结合方向
    • a+b-c等价于(a+b)-c
    • a=b+=1等价于a=(b+=1)
    • !!a等价于!(!a)

教员箴言

用括号,让自己清楚,让别人明白!

C++运算符

算术运算

  • C/C++ 支持的算数运算包括加(+)、减(-)、乘(*)、除(/)以及模(%
    • 整数除法的结果仍是整数,相当于结果向0取整
    • 模运算的结果的符号与被除数(左操作数)相同

明察秋毫

  • Python中的整数除法,结果是向下取整,而求模运算的结果,符号与除数(右操作数)相同。
  • 在两种语言中,整数除法运算与求模运算,均满足以下关系

\[a = (a/b) \cdot b + a\%b\]

测一测

下面程序的输出是什么?

算术运算
// 算术运算
cout << (10 % 3) << endl;
cout << (10 % -3) << endl;
cout << (-10 % 3) << endl;
cout << (-10 % -3) << endl;
cout << (10 / 3) << endl;
cout << (10 / -3) << endl;
cout << (-10 / 3) << endl;
cout << (-10 / -3) << endl;
cout << (10 / 3 * 3) << endl;

关系运算

  • 关系运算用于测试两个值的相等性与大小关系
    • 等于(==)、不等于(!=
    • 大于(>)、大于等于(>=)、小于(<)、小于等于(<=
    • 关系运算的结果是一个布尔值
    • 字符值和布尔值的大小比较,会转换成整数再进行比较
      • 字符值转换成其整数编码
      • true转换成1,false转换成0
关系运算
// 关系运算
cout << ('A' < 'a') << endl;
cout << (true < false) << endl;

位运算

  • 位运算用于对整数的比特位进行运算,包括按位逻辑运算移位运算
  • 逻辑运算:按位与(&)、按位或(|)、按位异或(^)以及按位取反(~
按位与
& 1 0
1 1 0
0 0 0
按位或
| 1 0
1 1 1
0 1 0
按位取反
~ 1 0
0 1
按位异或
^ 1 0
1 0 1
0 1 0
  • 移位运算:左移位(<<)与右移位(>>
    • 左为高位、右为低位
    • 向左移位,低位补零
    • 向右移位,高位补符号位

移位运算

逻辑运算

  • 逻辑运算用于构造逻辑表达式,包括包括
    • 逻辑与(&&/and
    • 逻辑或(||/or
    • 逻辑非(!/not
逻辑运算
// 逻辑运算
bool t = true, f = false;
cout << (t and f) << endl;
cout << (t or f) << endl;
cout << (not f) << endl;

明察秋毫

C++中有按位异或运算符(^),但没有逻辑异或运算符

逻辑与
and true false
true true false
false false false
逻辑或
or true false
true true true
false true false
逻辑非
not true false
false true

赋值运算

  • 赋值表达式实现变量的赋值,其本质是将一个值写入目标变量所在的内存区
    • 赋值表达式本身具有“值”语义,其值即为等号右端项的值
    • 赋值表达式具有副作用:改变目标变量所在内存区域的内容
  • 复合赋值表达式合并了一个二元操作与赋值运算
    • a+=2等价于a=a+2
    • 复合赋值运算符包括+=-=*=/=%=&=|=^=<<=>>=
赋值运算
// 赋值运算
int a = 0;
cout << (a = 1) << endl;
cout << (a = a + 1) << endl;
cout << (a += 1) << endl;
cout << (a *= 2) << endl;
cout << (a /= 2) << endl;
cout << (a %= 2) << endl;
cout << a << endl;

自增/自减运算

  • 自增表达式用于对变量进行增1(++)或减 1(--)的操作,有两个变种
    • 后缀自增表达式a++a--的值是增(减)1的值
    • 前缀自增表达式++a--a的值是增(减)1的值
自增/自减运算
// 自增/自减运算
int b = 0;
cout << (b++) << endl;
cout << (++b) << endl;
cout << (b--) << endl;
cout << (--b) << endl;
cout << b << endl;

明察秋毫

a++a--在副作用上等同于a+=1a-=1,但是在表达式值上有所不同

条件运算

  • 条件运算符是一个三元操作符b ? x : y
    • 计算表达式b
    • b为真,则计算表达式x作为条件表达式的值
    • 否则,计算表达式y作为条件表达式的值
条件运算
// 条件运算
int c = 2;
cout << (c > 0? (c -= 1) : (c += 1)) << endl;
cout << c << endl;

明察秋毫

b ? x : y中,xy有且仅有一个会被计算

逗号运算符

  • 逗号表达式先后计算逗号左侧和右侧的值,并以右侧的值作为逗号表达式的值
    • 例如ab的值分别为35,则表达式(a, b+3, b+a)的值为8
逗号运算
// 逗号运算
int d = 0, e = 0;
cout << (d++, e+2, e--) << endl;
cout << d << ' ' << e << endl;

搞事?

这鬼运算符有啥用?

  • 在某些情况下,逗号运算符可以用于简化代码,例如
    • for循环中初始化多个变量
    • 在单一表达式中执行多个具有副作用的操作

教员箴言

不要玩花活,除了少数惯用法,应当尽量避免逗号运算符的使用

逻辑表达式的短路

  • 当二元逻辑运算符的左操作数已经可以判定整个逻辑表达式的真值,则右操作数不会被计算,称为短路(shortcut)
    • x为真,则x || y的值为真,不会计算y
    • x为假,则x && y的值为假,不会计算y
逻辑表达式短路
// 逻辑表达式短路
int f = 0;
cout << ((f = 0) and (f = 1)) << endl;
cout << f << endl;
cout << ((f = 1) or (f = 0)) << endl;
cout << f << endl;

明察秋毫

短路是语言规范的行为,而非一种优化

运算符小结

C++运算符

类型转换

  • 类型转换用于将一个类型的值转换为另一个类型的值,例如
    • 将整型数转换为浮点数
    • 将字符转换为整型数

考考你

哪些应用场景需要用到类型转换?

  • 类型转换的应用场景
    • 不同类型数据之间执行算术运算,如整数求平均值
    • 跨类型赋值,如将一个整数字面量赋给一个浮点变量
    • 字符串处理,如移位加密

类型转换方式

---
config:
  look: handDrawn
  themeVariables:
    fontSize: 28px
---
flowchart TD
  类型转换 --> 隐式转换
  类型转换 --> 显式转换

类型转换方式

  • 显式类型转换通过显式地指定目标数据类型对源操作数进行转换
    • C++语法:static_cast<type>(expr)
    • C语法:(type)expr
显式类型转换
double d = 3.14;
int i = static_cast<int>(d); // cast double to int
int j = (int)'A'; // cast char to int
  • 隐式类型转换由编译器执行,典型场景包括
    • 当二元操作符两端操作数类型不同时,编译器将操作数转换为同一类型
    • 值赋给一种不同类型的变量时,编译器将赋值语句右端值转换为目标变量类型
隐式类型转换
double pi = 3.14;
int p = pi / 2; // cast int to double, then double back to int
bool b = p;     // cast int to bool

隐式类型转换规则

  • 隐式类型转换的总体原则:向表示范围更大、精度更高的类型转换
    • 整型数与浮点数做运算,整型向浮点转型
    • 浮点数与浮点数做运算,低精度向高精度转型
    • 整型数与整型数做运算,向更长的整型转型,但转型结果类型最低为int

测一测

下面的代码中,共发生了多少次隐式类型转换?

float a = 3;
int d = a + 3.14;
  • 布尔类型与其他类型的转换
    • 布尔值转换为整数时,true转换为1,false转换为0
    • 整数、浮点数、字符类型转换为布尔值时,0转换为false,非0转换为true

类型转换与数值范围、精度

避坑

当将高精度、范围大的数据类型转成低精度、范围小的数据类型时可能会造成精度损失数值溢出

基础类型的范围与精度
有符号与无符号整数类型转换
unsigned int u = 0xFFFFFFFF;
int s = (int)u;
cout << "unsigned: " << u << ", int: " << s << '\n';

考考你

同字长的有符号与无符号整型数之间转换是否会产生问题?不会损失精度,可能发生溢出

Ariane 5 火箭爆炸事故

1996年,欧洲航天局Ariane 5火箭首飞,火箭升空约40秒后解体爆炸。调查报告显示,事故原因源自控制程序中一个将64位浮点数转换为16位整型的语句,该语句未进行合理数值溢出处理

——The Worst Computer Bugs in History

Ariane 5火箭升空后爆炸
危险的类型转换
double horizontal_velocity ;
short velocity_16bit;
...
velocity_16bit = (short)horizontal_velocity;

表达式练习

考考你

下面的表达式是什么类型?

(1)3.14f + 2 (2)3.14 + 2.0f (3)1 && 2 (4)1 ^ 2 (5)true ^ false

表达式练习

考考你

请完成炸弹轨迹问题中的计算过程

轰炸机在高度\(h=5000m\)处朝向目标以速度\(v=200m/s\)匀速飞行,设重力加速度\(g=9.8m/s^2\)为常数,忽略空气阻力,求给定时间后投弹点的位置\((x,y)\),结果仅保留整数部分

表达式练习
// 常量与变量
const double g = 9.8;
double v = 60;
int x = 0;
int y = 5000;
double t = 2.3;

// 计算炸弹落点
// ----------- begin -----------//


// ----------- end -------------//

cout << x << ' ' << y << endl;

5. 输入输出初步

输入输出流

  • “流”是C++对I/O设备的一种抽象,表示数据通道上的一个连续字节序列
  • C++通过流对象实现输入输出功能
    • cout:标准输出流,即显示器
    • cin:标准输入流,即键盘
  • 要使用标准输入输出流对象,需要包含iostream头文件

明察秋毫

coutcin的功能相当于Python中的printinput函数

标准输入输出流
int answer = 34;
int guess = 0;
cout << "Guess it!\n";
cin >> guess;

流操作符

  • 输出流与输入流分别使用插入运算符(<<)和提取运算符(>>)进行输出与输入
    • 插入运算符(<<)用于将数据插入到输出流中
    • 提取运算符(>>)用于从输入流中提取数据
    • 若需输出或输入多个数据,可以连续使用流操作符
    • 输入流默认以空格、制表符、换行符等空白字符作为分隔符
标注输入输出流
double w = 0, h = 0;
cout << "Input the width and height of the rectangle: ";
cin >> w >> h;
cout << "Area of the rectangle is " << w * h << '\n';

明察秋毫

<<>>除了是流操作符,还是移位运算符,具体使用场景通过上下文区分

输入输出练习

考考你

请完成炸弹轨迹问题中的输入与输出

轰炸机在高度\(h=5000m\)处朝向目标以速度\(v=200m/s\)匀速飞行,设重力加速度\(g=9.8m/s^2\)为常数,忽略空气阻力,求给定时间后投弹点的位置\((x,y)\),结果仅保留整数部分

输入输出练习
// 常量与变量
const double g = 9.8;
double v = 60;
int x = 0;
int y = 5000;
double t = 2.3;

// 计算炸弹落点
x = v * t;
y -= g * t * t / 2;

// 输出结果,格式如下
// 在t时刻,炸弹位置为(x, y),其中t/x/y为相应变量的值
// ----------- begin -----------//

// ----------- end -------------//

总结

本节内容

---
config:
  look: handDrawn
  themeVariables:
    fontSize: 20px
---
mindmap
  C++语言基础
    标识符
      关键字
    类型系统
      基础数据类型
        字符类型
        整型
        浮点型
        布尔型
      长度与对齐
      取值范围
    变量与常量
      变量
      常量
        符号常量
        字面量
    表达式
      运算符
        算术运算
        逻辑运算
          短路
        关系运算
        位运算
        赋值运算
        自增自减运算
        条件运算
        逗号运算
      类型转换
        显式类型转换
        隐式类型转换
    输入输出
      标准输入输出流

学习目标

  • 构造合法、简洁、清晰的变量名
  • 掌握类型系统的构成并为变量选择合适类型
  • 正确书写不同类型的字面量、定义变量与符号常量
  • 综合运用各种运算符实现复杂的计算功能
  • 使用C++的输入输出流完成数据的输入输出

课后作业

  • 实训(截止时间2025.03.05
    • C&C++表达式语句实训
    • 综合练习——C&C++输入输出和表达式
  • 预习
    • 教材4.1–4.3:语句、顺序与选择结构

计算机程序设计