int 和 double 声明变量,
掌握基础算术运算,理解整数除法的陷阱与解决方法,
最后做出一个能计算总价的购物小票程序。
int 和 double 声明变量,
掌握基础算术运算,理解整数除法的陷阱与解决方法,
最后做出一个能计算总价的购物小票程序。
上节课我们用 std::cout 输出了固定的文字,比如 "Hello, World!"。
但程序更多时候要处理会变化的数据——
玩家的血量、商品的价格、今天的气温。
如果每次都把数字写死在代码里,程序就“死了”:无法计算,无法更新,无法响应用户。 变量就是解决这个问题的工具——它是一个有名字的“容器”, 可以存入一个值,之后随时读取或修改。
Python:直接写名字和值
age = 14
score = 95
height = 1.75
Python 自动判断你存的是整数还是小数
C++:先写类型,再写名字
int age = 14;
int score = 95;
double height = 1.75;
必须告诉 C++ 这个容器装的是哪种数
int(整数,如 14、100、-5)和
double(带小数点的数,如 3.14、1.75)。
第四节课还会介绍 string(文字)。先把这两个用熟,其他类型用到时再学。
语法:类型 变量名 = 初始值;
| 写法 | 说明 |
|---|---|
int age = 14; | 声明并直接赋初始值(推荐) |
int score; | 先声明,后赋值(两步走) |
int a = 1, b = 2; | 一行声明多个(合法,但可读性差,不推荐) |
注意:同一个变量只能声明一次(写一次 int),但可以被赋值很多次。
#include <iostream>
int main() {
int age = 14;
int score = 95;
std::cout << "年龄:" << age << std::endl;
std::cout << "分数:" << score << std::endl;
return 0;
} std::cout 这一类输出语句里,<< 叫做流插入运算符。
可以先把 std::cout 理解成“输出流”,<< 的作用是把右边的数据插入到这个输出流里。
多个 << 可以连续连接,程序会按从左到右的顺序输出。
比如 std::cout << "年龄:" << age << std::endl;。
“变量”之所以叫变量,就是因为它能变。把新值直接赋给变量名就行, 不需要再写类型。还可以用变量自身参与计算后再存回去:
int age = 14;
std::cout << "今年:" << age << std::endl; // 输出 14
age = 15; // 直接赋新值(不加 int)
std::cout << "明年:" << age << std::endl; // 输出 15
age = age + 1; // 用自身参与计算
std::cout << "后年:" << age << std::endl; // 输出 16 int age = 14; 之后又写 int age = 15;——这是错误的。
同一个变量在同一作用域内不能声明两次。修改值直接写 age = 15;,不加 int。
写一个完整程序,完成以下要求:
int 变量:你的年龄、班级人数、你最喜欢的游戏评分(满分 100)std::cout 把三个值都输出出来,每行一个,加上标签(如 "年龄:14")std::cout << "年龄:" << age << std::endl; ——
文字用引号,变量直接写名字,用 << 连起来。
不是任意字符串都能当变量名。C++ 有几条硬规则:
| 规则 | 合法示例 | 非法示例 |
|---|---|---|
只能用字母、数字、下划线 _ | score1 | my-score(含 -) |
| 不能以数字开头 | level1 | 1level |
| 区分大小写 | age 和 Age 是两个不同变量 | — |
| 不能是 C++ 关键字 | myInt | int、return |
| 不能有空格 | totalScore | total score |
totalScore、playerHealth。
多个单词可以用小驼峰写法:第一个单词小写,后面的单词首字母大写。
int、double、return、
if、else、for、while、
true、false……
在 CLion 里,这些词会自动变色——看到变色就说明它是关键字,不能当变量名。
main 虽然不是关键字,但它是程序入口函数的特殊名字,也不要拿来当普通变量名。
下面这些名字,哪些合法?哪些有问题?口头判断,不用写代码:
| 变量名 | 合法? | 如果非法,原因是? |
|---|---|---|
myScore | —— | —— |
2ndPlace | —— | —— |
player_hp | —— | —— |
int | —— | —— |
total price | —— | —— |
backupValue | —— | —— |
myScore、player_hp、backupValue。2ndPlace(数字开头)、int(关键字)、total price(有空格)。
| 符号 | 名称 | 示例 | 结果 |
|---|---|---|---|
+ | 加法 | 10 + 3 | 13 |
- | 减法 | 10 - 3 | 7 |
* | 乘法 | 10 * 3 | 30 |
/ | 除法 | 10 / 3 | 3(注意!) |
% | 取余(模) | 10 % 3 | 1 |
% 是取余数,Python 里你们也用过。10 % 3 = 1,
因为 10 ÷ 3 商 3 余 1。常见用途:判断奇偶(n % 2 == 0 就是偶数)。
本节涉及的加减乘除取余,运算顺序和数学课基本一致: 先乘除取余,后加减,括号最优先。
不确定优先级时,直接加括号——括号是免费的,可以无限套。
int a = 2 + 3 * 4; // 先乘:结果 14
int b = (2 + 3) * 4; // 先括号:结果 20
int c = 10 / 3; // 整数除法:结果 3
int d = 10 % 3; // 余数:结果 1
std::cout << a << std::endl; // 14
std::cout << b << std::endl; // 20
std::cout << c << std::endl; // 3
std::cout << d << std::endl; // 1 下面每行代码会输出什么?先在纸上写下你的答案,再输入程序运行验证:
| 代码 | 你猜的结果 | 实际结果 |
|---|---|---|
std::cout << 3 + 4 * 2 << std::endl; | —— | —— |
std::cout << (3 + 4) * 2 << std::endl; | —— | —— |
std::cout << 17 % 5 << std::endl; | —— | —— |
std::cout << 9 / 2 << std::endl; | —— | —— |
std::cout << 9 % 2 << std::endl; | —— | —— |
std::cout << 100 - 3 * 10 + 5 << std::endl; | —— | —— |
9 / 2 写成 4.5。运行后你会发现是 4——
这正是下面要讲的整数除法陷阱。
当 / 两侧都是 int 时,结果也是 int——
小数部分会被直接截断丢弃(不是四舍五入)。
7 / 2 → 3,不是 3.5
1 / 4 → 0,不是 0.25
99 / 100 → 0,不是 0.99
这是 C++ 初学者最常踩的坑之一。写计算程序时,如果结果莫名其妙变成 0 或差很远,
先检查有没有两个 int 相除。
#include <iostream>
int main() {
int x = 7;
int y = 2;
std::cout << x / y << std::endl; // 输出 3,不是 3.5!
std::cout << x % y << std::endl; // 输出 1(7 除以 2 余 1)
return 0;
} int avg = totalScore / count;,如果 totalScore 比 count 小,结果直接是 0。
第五段会教你怎么修复这个问题。
需要带小数点的数时用 double。常见场景:
纯计数、序号、循环次数等用 int 就够。
不确定时,只要结果可能出现小数,就选 double。
#include <iostream>
int main() {
double height = 1.75;
double weight = 60.5;
std::cout << "身高:" << height << " 米" << std::endl;
std::cout << "体重:" << weight << " 千克" << std::endl;
return 0;
}
如果 / 两侧有一个是 double,结果就是 double,小数不会丢失。
| 表达式 | 结果 | 原因 |
|---|---|---|
7 / 2 | 3 | 两个 int,整数除法 |
7.0 / 2 | 3.5 | 左边是 double,结果提升为 double |
7 / 2.0 | 3.5 | 右边是 double,结果提升为 double |
如果两个变量都已经是 int,可以用 (double)
把其中一个临时转换成 double,再做除法,结果就会保留小数。
语法:(目标类型)变量名,这叫做强制类型转换(cast)。
注意:这只是本次计算中的临时转换,原变量的类型和值并不会改变。
int x = 7;
int y = 2;
std::cout << x / y << std::endl; // 3(两个 int,直接截断)
std::cout << (double)x / y << std::endl; // 3.5(先把 x 临时变成 double,再除)
写一个程序,模拟一张购物小票的计算过程。数字直接写在变量里,不需要用户输入。
已知商品单价是 29.9 元,购买数量是 3 件。
要求:
int 存数量,double 存单价std::cout 格式化输出,像一张收据参考输出:
========================
购物小票
========================
单价:29.9 元
数量:3 件
小计:89.7 元
税费:8.97 元
总计:98.67 元
======================== 分层目标:
在练习 2-3 的基础上加入折扣。假设商品打 八折(折扣率 = 0.8):
思考:折扣率 0.8 该存成 int 还是 double?
如果存成 int 会发生什么?
cin 让用户在运行时自己输入——
不同的用户输入不同的价格和数量,程序都能算出正确结果。
程序真正“活”起来了。