一、前言:为什么用 C++ 的视角学 Python
很多同学是先从 C / C++ 入门,再来学 Python 的。这两门语言的设计哲学差异非常大:- C++ 强调性能与控制,变量的类型在编译期就固定死了,编译器替你"把关",写错了直接编译报错。
- Python 强调简洁与开发效率,变量的类型在运行时才确定,怎么写都行,写错了运行时报错。
正因为差异大,学 Python 最忌讳"照着 C++ 的思维硬套"。这篇文章把课程笔记里每一个知识点都和 C++ 做对比,哪里有区别,就同时给出 Python 和 C++ 两段代码,让你"边找不同边记语法"。对于课程里一句带过的内容(位运算、身份运算符、成员运算符等),我也做了补充,保证覆盖全面。二、常量和表达式
2.1 什么是"表达式"
在编程里,1 + 2 - 3 这种算式称为表达式,算出来的结果叫表达式的返回值;其中 1、2、
3 这种直接写出来的数据叫字面值常量,+ - * / 这种符号叫运算符(操作符)。print(1 + 2 - 3) # 0print(1 + 2 * 3) # 7 先乘除后加减print((1 + 2) * 3) # 9 括号改变优先级
注意:Python 里运算符和数字之间有没有空格、有几个空格都无所谓(1+2 和 1 + 2 等价),但为了美观,习惯上写一个空格。2.2 关键差异:除法 /
这一条 C 系选手最容易踩坑。在 C++ 里,两个整数相除,小数部分直接截断;在 Python 里,/ 永远返回浮点数,更符合日常直觉。print(1 / 2) # 0.5 不会截断成 0print(5 / 2) # 2.5print(10 / 4) # 2.5
int a = 1, b = 2;std::cout << a / b << std::endl; std::cout <5.0 / 2 << std::endl;
记忆口诀:Python 的 / 永远做"真除法";C++ 的 / 只有在两边都是整数时才做"整数除法"。2.3 示例:求平均值
print((67.5 + 89.0 + 12.9 + 32.2) / 4) # 50.400000000000006
(为什么会多个小尾巴?这就是后面 6.2.2 节要讲的浮点数精度问题,先留个印象。)double avg = (67.5 + 89.0 + 12.9 + 32.2) / 4;std::cout << avg << std::endl;
三、变量和类 型
3.1 变量是什么
计算稍微复杂一点时,需要把中间结果保存下来,这就用到了变量。比如求四个分数的方差,得先算出平均值 avg 存起来:avg = (67.5 + 89.0 + 12.9 + 32.2) / 4total = (67.5 - avg) ** 2 + (89.0 - avg) ** 2 + (12.9 - avg) ** 2 + (32.2 - avg) ** 2result = total / 3print(result)
可以把变量理解成内存里的一块空间(就像宿舍楼里的房间),每个房间有名字、能存数据。avg、total、result 就是三个变量。3.2 定义变量:类型声明是最大区别
Python 定义变量极其简单,不需要写类型:
int a = 10; std::string name = "Tom";
为什么? C++ 要在编译期就知道变量占几个字节、能做什么操作;Python 是解释执行的,运行时看到赋了什么值再"猜"类型,所以可以省掉类型声明。3.3 变量命名规则
两门语言的硬性规则基本一致:
软性规范也相通:名字要"见名知义",多个单词组合起来(
totalCount、personInfo)。补充小知识:Python 官方规范 PEP 8 更推荐用 snake_case(全小写 + 下划线,如 total_count),而 C++ 习惯用驼峰(totalCount)。课程里示例用驼峰也没问题,但面试或写正式项目时,Python 风格请尽量用下划线命名。3.4 使用变量:读取与修改
a = 10print(a) a = 20 print(a)
注意:Python 里定义变量和修改变量用的都是 =,语法上没区别,这点和 C++ 一样。也支持用一个变量给另一个变量赋值:注意:Python 里定义变量和修改变量用的都是 =,语法上没区别,这点和 C++ 一样。也支持用一个变量给另一个变量赋值:3.5 数据类型对比
Python 内置的几种基本类型:
a = 10print(type(a)) a = 0.5print(type(a)) a = 'hello'print(type(a)) a = Trueprint(type(a))
int a = 10; float f = 0.5f; double d = 0.5; bool flag = true;
3.5.1 重点差异一:Python 的 int 没有上限
C++ 的 int 一般占 4 字节,最大值约 21.47 亿,超出就溢出(甚至属于未定义行为):
int a = 2147483647;a = a + 1;
Python 的 int 只要内存够,想多大就多大:print(10 ** 30) # 1000000000000000000000000000000,照算不误
3.5.2 重点差异二:Python 没有单独的"字符类型"
C++ 里有 char,一个字符占一字节;Python 里 'a' 和 "hello" 都是 str,没有单字符类型。而且 Python 的单引号和双引号完全等价,'hello'
和 "hello" 没有任何区别。字符串拼接用 +:a = 'hello'b = 'world'print(a + b) print(len(a))
std::string a = "hello";std::string b = "world";std::cout << a + b << std::endl; std::cout << a.size() << std::endl;
注意:两门语言里字符串都不能直接和整数相加。Python 的 'a' + 10 会直接抛 TypeError;C++ 的 std::string + 整数 则是编译报错(没有对应的 operator+ 重载)。C++ 里 std::string 可以 +
单个字符(s + 'a' 合法),这算是小差异。3.6 动态类型 vs 静态类型
这是 Python 和 C++ 最本质的区别之一。Python 是动态类型:一个变量的类型在程序运行过程中可以改变。a = 10print(type(a)) a = 'hello'print(type(a))
C++ 是静态类型:变量一旦定义,类型就固定了,再赋别的类型直接编译报错。int a = 10;a = "hello"; // 编译错误:不能把 const char* 赋给 int
- 优点:中小型程序写起来快,一段代码能同时处理多种类型(比如一个函数既能传整数又能传字符串)。
- 缺点:大型项目里,A 同事写的代码 B 同事看不懂到底传进来什么类型,协作成本高。所以很多大型 Python 项目后来都引入了"类型注解"(type hints)。
3.7 类型转换
Python 用内置函数转类型:int()、float()、str()、
bool()。s = "10"num = int(s) f = float("3.14") t = str(123)
std::string s = "10";int num = std::stoi(s); int num2 = static_cast<int>(3.99);
注意 int("3.14") 在 Python 里会报错(无法直接转换带小数点的字符串),要先用 float()。C++ 的 static_cast(3.99) 则是直接截断小数位。四、注释
注释不会被程序执行,只是给人看的,帮自己和别人理解代码。两门语言的单行注释符号不同:- 内容要准确
- 篇幅要合理:既不能不写,也不要长篇大论;中文团队一般要求用中文写。
五、输入输出
5.1 输出:print vs std::cout
Python 用 print() 输出,可以一次打印多个值,默认用空格分隔:
print(1, 2, 3) # 1 2 3print('hello') # hellonum = 10print(num) # 10
C++ 用流输出,每个值之间要靠 << 手动连接,分隔符也要自己写:Python 的 print 还支持自定义分隔符和结尾:print(1, 2, 3, sep='-') # 1-2-3print(1, 2, 3, sep='-', end='!\n') # 1-2-3!
对应记忆:print(a, b) ≈ C++ 的 std::cout << a << " " << b;。5.2 格式化输出:f-string vs C++
Python 最常用的是 f-string,在字符串前加 f,用
{} 内嵌变量或表达式:
num = 10print(f'num = {num}') print(f'3 的平方是 {3 ** 2}')
int num = 10;printf("num = %d\n", num); std::cout << num << std::endl;
5.3 输入:input vs std::cin
这是新手最常踩的坑:Python 的 input() 返回的一定是字符串,想做算术运算必须先转类型!
num = input('请输入一个整数: ') print(f'你输入的是 {num}')
a = input('请输入第一个整数: ')b = input('请输入第二个整数: ')print(f'a + b = {a + b}')
a = int(input('请输入第一个整数: '))b = int(input('请输入第二个整数: '))print(f'a + b = {a + b}')
C++ 的 std::cin 会根据变量的类型自动转换,不需要手动转:int num;std::cin >> num; int a, b;std::cin >> a >> b; std::cout << a + b << std::endl;
总结差异:C++ 的 cin >> 是"喂给类型化变量",读进来就是那个类型;binpt() 永远给字符串,一切类型转换都得自己动手。这也体现了 Python "少魔法、多显式"的设计。5.4 综合示例:输入 4 个小数求平均值
a = float(input('请输入第一个数字: '))b = float(input('请输入第二个数字: '))c = float(input('请输入第三个数字: '))d = float(input('请输入第四个数字: '))avg = (a + b + c + d) / 4print(f'平均值: {avg}')
#include int main() { double a, b, c, d; std::cin >> a >> b >> c >> d; double avg = (a + b + c + d) / 4; std::cout << avg << std::endl; return 0;}
六、运算符
6.1 算术运算符
两门语言共有的:+ - * / %(取余)。Python 独有:**(乘方)和 //(整除)。
print(4 ** 2) # 16print(4 ** 0.5) # 2.0 还能算小数次方
#include std::cout << std::pow(4, 2) << std::endl;
std::cout << std::sqrt(4) << std::endl;
// 是地板除(floor division),结果是往负无穷方向取整,而不是往零取整。这和 C++ 的整数除法(往零截断)在负数场景下结果完全不同,是高频考点:print(7 // 2) # 3print(-7 // 2) # -4 注意!不是 -3
为什么不一样? -7 / 2 的数学结果是 -3.5。Python 的 // 向负无穷取整 → -4;C++ 的整数除法向零取整 →
-3。 同理,取余 % 的负数结果也两套逻辑:print(-7 % 2) # 1 因为 -7 = 2 * (-4) + 1print(7 % -2) # -1
std::cout % 2 << std::endl;
两门语言都满足恒等式 a == (a // b) * b + (a % b),只是对"整除"的定义不同。记住 Python 的结果永远非负(当除数为正时)即可。print(10 / 0) # ZeroDivisionError: division by zero
int x = 10 / 0; // 运行时崩溃 / 未定义行为
6.2 关系运算符
< <= > >= == !=,两门语言写法完全一样,返回布尔值。
a, b = 10, 20print(a < b) print(a == b) print(a != b)
int a = 10, b = 20;std::cout << (a < b) << std::endl; std::cout << (a == b) << std::endl;
6.2.1 字符串可以比较大小(字典序)
Python 直接支持字符串比较,规则是字典序(按字符的编码逐个比较,和查英语词典一个道理):
print('hello' == 'world') print('abc' 'abd')
C++ 的 std::string 也支持 == 和 <;但 C 风格的 char[] 必须用 strcmp:#include std::string s1 = "hello", s2 = "world";std::cout << (s1 == s2) << std::endl;
char c1[] = "abc";char c2[] = "abd";int r = strcmp(c1, c2);
易错点:C 语言里 char s1[] = "abc"; char s2[] = "abc"; s1 == s2 比的是地址而不是内容,永远是 false。很多 C 系出身的同学在 Python 里一对比就懵,其实 Python 和 C++ 的
std::string 的 == 都是按内容比较的。6.2.2 浮点数比较:千万不要用 ==(重点)
浮点数在计算机里是近似存储的(IEEE 754 标准),运算会产生极小的误差:
print(0.1 + 0.2) # 0.30000000000000004print(0.1 + 0.2 == 0.3) # False ← 坑!数学上明明相等
double a = 0.1 + 0.2;double b = 0.3;std::cout << (a == b) << std::endl; // 0(false)
正确做法:比较差值是否在误差范围内,而不是严格相等。a = 0.1 + 0.2b = 0.3print(abs(a - b) 1e-9) # Trueprint(-0.000001 < (a - b) 0.000001) # True ← 注意:Python 支持连续比较!
#include double a = 0.1 + 0.2, b = 0.3;std::cout << (std::abs(a - b) 1e-9) << std::endl;
6.2.3 Python 独有的"连续比较"
Python 可以直接写 a < b < c,一次比较三个数,相当于"夹在中间"的判断:
a, b, c = 10, 20, 30print(a < b < c) # True
C++ 不支持
这种写法,必须拆开用 && 连接:int a = 10, b = 20, c = 30;std::cout << (a < b && b < c) << std::endl; // 1
6.3 逻辑运算符(重点)
6.3.1 写法对比
a, b, c = 10, 20, 30print(a < b and b < c) print(a < b and b > c) print(a > b or b > c) print(not a < b)
int a = 10, b = 20, c = 30;std::cout << (a < b && b < c) << std::endl; std::cout << (a < b && b > c) << std::endl; std::cout << (a > b || b > c) << std::endl; std::cout << (!(a < b)) << std::endl;
6.3.2 短路求值(重点)
最经典的验证方法:让右侧写一个除以 0,如果被短路了就不会报错。print(4 > 7 and 10 / 0 == 1) # False(10/0 没被求值)print(4 7 or 10 / 0
== 1) # True(10/0 没被求值)
bool r1 = (4 > 7) && (10 / 0 == 1); bool r2 = (4 7) || (10 / 0 == 1);
短路求值非常实用,常用于先判断、再取值,比如 if x is not None and x > 0:,保证不会因为 x 为空而报错。6.3.3 深度差异:and / or 返回的是操作数,不是布尔值!
这是 Python 和 C++ 一个非常隐蔽、又很重要的区别。
- C++ 的
&& / || 结果永远是 bool(true/false)。 - Python 的
and / or 返回的是某个参与运算的对象本身:
print(0 and 5) # 0 0 是假,返回 0print(3 and 5) # 5 3 是真,返回 5print(0 or 5) # 5 0 是假,返回 5print('a' or 'b') # 'a' 'a' 非空即真,返回 'a'
name = input('请输入姓名: ') or '匿名用户'print(f'你好,{name}')
6.3.4 深度差异:Python 里的"真值"概念
C++ 里 && || ! 严格要求 bool 操作数(其它类型要自己转);
Python 里任何对象都可以直接当布尔用,有一套"真值判定"规则:
- 判定为假的常见对象:
0、0.0、''(空字符串)、[](空列表)、None
if '': print('不会执行')if 'hello': print('会执行')if []: print('不会执行')
C++ 则要显式写条件,比如判断指针/容器是否为空:int* p = nullptr;if (p) { } std::string s = "";if (!s.empty()) { }
6.4 赋值运算符
6.4.1 链式赋值:a = b = 10
Python 和 C++ 都支持,把同一个值赋给多个变量,从右往左依次赋值:
a = b = 10print(a, b) # 10 10
6.4.2 多元赋值:a, b = 10, 20(Python 独有)
Python 可以一行给多个变量赋不同的值,左边是变量元组 ,右边是对应的值元组:
a, b = 10, 20print(a, b) # 10 20
C++ 没有这个语法,只能分开写或用 std::tie:int a = 10, b = 20;std::tie(a, b) = std::make_tuple(10, 20);
6.4.3 变量交换(重点)
传统写法(借助临时变量,两门语言通用):
int tmp = a;a = b;b = tmp;std::swap(a, b);
Python 特有写法(利用多元赋值,一行搞定):这个写法能生效的原理:右边的 b, a 会先求值打包成一个元组
,再整体赋给左边。所以不存在"先改了 a 导致 b 取错"的问题,也不需要临时变量。6.4.4 复合赋值运算符
+= -= *= /= %= 等,两门语言含义一致:a += 1 等价于 a = a + 1。
a = 10a += 1print(a) # 11
int a = 10;a += 1;std::cout << a << std::endl;
6.4.5 重点差异:Python 不支持 ++ --!
C++ 里 ++ / -- 有前置和后置之分,极易混淆:
int a = 10;int x = a++; // 后置:先取 a 的值 10 赋给 x,再自增 → x = 10, a = 11int y = ++a; // 前置:先自增再取 a 的值 → a = 12, y = 12
Python 故意砍掉了 ++ --,因为前置后置太容易出错,不符合 Python 追求简洁直观的理念。需要自增自减时,直接用复合赋值:注意一个坑:Python 里 ++a 不会报语法错,但它是 +(+a),也就是对
a 连续取两次正号,值不变!新手看到不报错就以为自增成功了,其实 a 根本没变。调试时尤其要小心。6.5 位运算符
两门语言的位运算符符号完全一样:&(按位与)、|(按位或)、~(按位取反)、^(按位异或)、<<(左移)、>>(右移)。以 a = 5(二进制 0101)、
b = 3(二进制 0011)为例:a, b = 5, 3print(a & b) # 1 0101 & 0011 = 0001print(a | b) # 7 0101 | 0011 = 0111print(a ^ b) # 6 0101 ^ 0011 = 0110(相同为0,不同为1)print(~a) # -6 按位取反:~5 = -6print(a <1) # 10 左移1位:0101 → 1010,相当于 ×2print(a >> 1) # 2 右移1位:0101 → 0010,相当于 ÷2
int a = 5, b = 3;std::cout << (a & b) << std::endl; std::cout << (a | b) << std::endl; std::cout << (a ^ b) << std::endl; std::cout << (~a) << std::endl; std::cout << (a <1) << std::endl; std::cout << (a >> 1) << std::endl;
- 判断奇偶:
x & 1(为 1 是奇数,为 0 是偶数),比 x % 2 更快。 - 乘 2 / 除 2:
x << 1 / x >> 1。 - 交换两个数:
a ^= b; b ^= a; a ^= b;(了解即可,实际开发用多元赋值更清晰)。
位运算对比小差异:Python 的整数是无限位宽的,对负数做 >> 是
算术右移(高位补 1),C++ 对有符号负数的右移行为由实现决定(现代编译器基本也是算术右移)。日常正数运算两者表现一致,不必深究,知道有这回事即可。6.6 身份运算符 is / is not
is 比较的是是不是同一个对象(内存地址),和比较值相等的 == 是两码事:
a = [1, 2, 3]b = [1, 2, 3]print(a == b) print(a is b)
c = aprint(a is c)
int x = 5;int* p1 = &x;int* p2 = &x;std::cout << (p1 == p2) << std::endl; std::cout << (*p1 == *p2) << std::endl;
经典坑:a is None 判断是否为空;a == None 判断值是否相等。判空习惯用 is None。另外小整数在 Python 里会被缓存,a = 1; b = 1; a is b 可能为 True,但这属于实现细节,不要依赖 is 比较整数,要判断值就用
==。6.7 成员运算符 in / not in(补充)
判断某个元素在不在一个容器(字符串、列表、元组)里:
print('a' in 'hello') print('l' in 'hello') print(3 in [1, 2, 3]) print(5 not in [1, 2, 3])
std::string s = "hello";bool has_l = s.find('l') != std::string::npos; // trueint arr[] = {1, 2, 3};bool has_3 = std::find(std::begin(arr), std::end(arr), 3) != std::end(arr); // true
6.8 运算符优先级
整体优先级和 C++ 高度相似,从高到低大致为:
差别最大的一个:Python 里 ** 优先级高于一元负号,所以 -3 ** 2 的结果是 -9(先算 3**2 再取负),而 C++ 里没有乘方运算符,不存在这个纠结。
实战建议:别硬背优先级,拿不准就加括号,代码可读性永远第一。七、总结:一张表记住所有差异
C++ 是"铁板钉钉"——类型、内存、运算符行为都在编译期定死,性能可控但写起来啰嗦、容易踩底层坑;Python 是"随遇而安"——类型动态推断、语法追求简洁直观,砍掉了 ++ -- 这种容易混淆的特性,开发效率高,适合把精力放在解决问题本身。