建议初学 C++ 的同学阅读,文中大部分内容是为地方举办的小考试、或另一些学校的考试量身定做的。文章选取了很多在平时很难刷到、考场上会令你犹豫不决的题目。 并且每一个选项都有详细的解析和考点总结。
因为有些点写不完或者暂时没有想到,所以本文是上篇,可能出中篇和下篇,最后不断改进整理成合集。
好啦,话不多说,开始吧。阅读之前,请你留下宝贵的赞。
变量名规则 \textcolor{orange}{变量名规则} 变量名规则
规则
- 不可以是 C++ 中的关键字(如
int、using等)。- 不可以用数字开头。
- 可以包含大小写字母、数字和下划线。除此之外其他字符不可以包含。
- 区分大小写(如
A和a是不一样的)。
考场秘诀:关键字打在 C++ 上会变粗(小熊猫:变蓝),不是关键字则不会。
是关键字:

不是关键字:

易错/易考点
一
-
【常考】 知识点:变量名中可以有下划线。
-
易错点: 下划线是
_,不是-,后者是不能出现的。不要混淆了。
例: 下列哪些变量名是合法的?
top-to-the-123、_、jc_12_jfkds_int_using。
(答案:除第一个外都是合法的)
解析:
-
第一个
top-to-the-123很明显出现了-,不是字母、数字、下划线,所以不合法。 -
第二个虽然只有一个字符
_,但是合法的,可以以下划线开头。这里容易错! -
虽然第三个
jc_12_jfkds_int_using出现了int和using两个关键字,但是除了这两个之外还是有其他的字母,且都合法。也容易错!
二
注意了:cin 、cout 不是 关键字!(考试极易考到)
但是作为变量仍然可以运行:

所以,cin 和 cout 是合法的变量名。
练习
一、请口述回忆变量名的四个规则,并尝试举例。
二、【必练】请问下列哪些是合法的变量名?
cpp
//合法填 T,不合法填 F
I1lo3vec_
namespace
_
cout
and
Int
up-to-the-top
while
or
1314wow
w0w1315
G
do
(答案)
cpp
//答案
================
//合法的变量名:
I1lo3vec_
_
cout
Int
w0w1315
G
------------
//不合法的变量名:
//关键字:
namespace
and
while
or
do
//混淆下划线(_)与 "-":
up-to-the-top
//数字开头:
1314wow
平时练习提示
虽然某些变量名合法,但是它的可读性很差,所以在平时的练习中,我们仍然要选择能够一目了然的、合法的变量名。
这里不是考点,可以跳过。
1.不要在规则上"反复横跳"
例如 cin 和 cout 虽然是合法的变量名,但是这样的写法不仅容易使逻辑错乱、代码可读性差,还会让你在阅读上花费大把的时间。
千万不要!
2.不要从 a 列到 z
部分初学者的情况就是把变量名从 a 列到了 z,虽然看上去简洁、整齐,但是变量的功能容易被忘记!
3.不要按乱码
? 诡异行为。
4.不要长长的一串英文
说实话,眼睛受不了。
返回值 \textcolor{orange}{返回值} 返回值
部分初学者情况
"返回值"在大部分初学者的脑海中可能是一个非常高深的概念,其实就是 "这个式子的值" 而已。
当然,你可能不是这种同学,[点赞]。
一个幼儿园孩子都看得懂的例子
比如这段不完整的代码:
cpp
5>6
很明显是有问题的。所以它的返回值就是------"假。"
反之如果正确,那么就是 真。
真和假
真
如果表达式是正确的,则返回值是真。
这个真是 bool 类型,叫做 "true"。
假
也是 bool 类型,叫做 "false"。
在分支中
cpp
if(1<10) {
cout<<"yes";
}
else {
cout<<"no";
}
你有没有想过,为什么上面的代码会输出 yes?
因为 1<10 是成立的,所以它的一个返回值就是 真 ,也就是 true。
这个 true 给了 if,if 收到之后也就执行了花括号内的代码。输出了 yes。
true 和 false
cpp
if(true) {
cout<<"yes";
}
else {
cout<<"no";
}
上面代码输出 yes,因为 if 的括号里是"真",所以执行了。
cpp
if(false) {
cout<<"yes";
}
else {
cout<<"no";
}
上面的代码输出 no,原因即:返回值是"假",所以不执行 if,执行 else。
在循环中
为什么以下内容当 i==2 时会被执行?
cpp
for(int i=0;i<=100;i++) {
//...
}
因为循环条件是 i<=100 就会被执行。在每次执行前,都会先判断这时的情况是否满足要求。因为满足,返回值真,循环会被运行;但如果不满足了(比如 i==101),就不会再进入这个循环。
如果还有问题
由于我发现的、我经历的问题就只有以上这些,我尽力地把问题讲清楚了。
但是,如果你还有一些其他的问题,请勇敢地提出来,这可能也是更多人的问题,让我们一起学习。如果你问出来了,我一定会解答。
在学习这门语言时,很多同学的"通病"就是不敢问,导致学不好。那何必不问出来呢?
三目运算符 \textcolor{orange}{三目运算符} 三目运算符
基本格式
基本格式:
a?b:c。意思是 :当a成立时执行b,不成立则执行c。
例子:
cppcout<<(6>5?"YES":"NO); /* 这段代码的最终输出:YES 因为 6>5 成立,所以执行第一项,就是 YES */
考法1:嵌套三目运算符
因为我们知道:a?b:c,一定会执行 b 和 c 中的某一个。
所以这种考法就是使得 b 或者 c 也是三目运算 。看上去长长的。在这个三目运算里可能还会再套,从小到大算即可。
说人话吧!
cpp
cout<<(7>10?(1==1?"yes":"no"):(65<98?"Yes":"No"));
看上去好长!
不过没关系,一步步拆开:首先,7>10 不成立,执行冒号后的部分(65<98?"Yes":"No")。65<98 成立,所以输出 Yes。
考法2:if-else 与 三目运算 的转换
很好转。这里做个例子,不懂问。
三目运算:
cpp
int a=5,b=3;
cout<<(a>b?"yes":"no");
转换成 if-else 语句的相同代码:
cpp
int a=5,b=3;
if(a>b) {
cout<<"yes";
}
else {
cout<<"no";
}
题外话
重要的事情说三遍:这里不是知识点,不会考! 这里不是知识点,不会考! 这里不是知识点,不会考! 仅供娱乐。
三目运算符虽然比 if-else 短一点点,但是可读性比较差,看上去 扁扁的,所以我们一般称之为 "压行",或者......
shi
(三声)
i + + 与 + + i \textcolor{orange}{i++ 与 ++i} i++与++i
区别
这东西真是让人头晕!
大概就是,i++ 是先用(值)再加,++i 是先加再用。
例子&考法
这里是一个简单但容易混淆的变量赋值代码,重点考察
i++和++i的区别:
cpp#include <stdio.h> using namespace std; int main() { int i = 5; int a, b, c, d; // 后自增:先赋值,再自增 a = i++; // a = 5, i 变成 6 printf("a = %d, i = %d\n", a, i); // a=5, i=6 // 前自增:先自增,再赋值 b = ++i; // i 先变成 7, b = 7 printf("b = %d, i = %d\n", b, i); // b=7, i=7 // 重置 i i = 5; // 表达式中的混合 c = i++ + ++i; // 危险!这是未定义行为,不同编译器结果不同 // 理论分析:某些编译器: i++=5, i=6, ++i=7, 总=12, i最终=7 printf("c = %d, i = %d\n", c, i); // 安全写法:分开 i = 5; int temp1 = i++; // temp1=5, i=6 int temp2 = ++i; // i=7, temp2=7 d = temp1 + temp2; // d=12 printf("d = %d, i = %d\n", d, i); // d=12, i=7 return 0; }核心区别:
i++:先用 i 的当前值,然后 i 加 1++i:先 i 加 1,然后用新值
进制转换 \textcolor{orange}{进制转换} 进制转换
(老大难+陈年老稿警告)
进制是一种计数制,不同的进制间可以互相转换。
K进制的意思就是"逢K进一",比如现在我们常用的进制就是十进制,计算时逢10进位。
K进制拥有K个符号(0 ~ K-1)。比如十进制里是0 ~ 9,而不是1 ~ 10。
K进制转十进制方法(整数)
Question:这里有一个二进制数 1011 0110,将其转化为十进制数。
计算步骤:
将K进制转十进制时,先从最低位算起。
从右往左计算,取每一位的值,将其乘以自己的位权,再将所有答案相加。
位权即每一位先从最右边的"0"开始,乘以 2 的 n 次方,n 为数字的位置,最低位是 0 ,从左数依次加一。
那么,二进制数"1011 0110"转化为十进制便是:
| 二进制位 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 位权 | 2 7 2^7 27 | 2 6 2^6 26 | 2 5 2^5 25 | 2 4 2^4 24 | 2 3 2^3 23 | 2 2 2^2 22 | 2 1 2^1 21 | 2 0 2^0 20 |
| 相乘结果 | 128 | 0 | 32 | 16 | 0 | 4 | 2 | 0 |
将结果相加:(注:"D"表示结果为十进制)
math
128+0+32+16+0+4+2+0=182(D)
上面的算式整合成一个直观的式子便是:
math
(0*2^0)+(1*2^1)+(1*2^2)+(0*2^3)+(1*2^4)+(1*2^5)+(0*2^6)+(1*2^7)=182
2.再举例
再举例。
Question:八进制数 7143 转换成十进制数是多少?
这里的位权就不同了,不是 2 n 2^n 2n ,而是 8 n 8^n 8n ,由此可见的,位权是 K n K^n Kn ,其中 K K K 为进制, n n n 为位数。
列表计算:
| 进制位 | 7 | 1 | 4 | 3 |
|---|---|---|---|---|
| 位权 | 8 3 8^3 83 | 8 2 8^2 82 | 8 1 8^1 81 | 8 0 8^0 80 |
| 相乘结果 | 3584 | 64 | 32 | 3 |
答案相加:
math
(3*8^0)+(4*8^1)+(1*8^2)+(7*8^3)=3683
3.字母表示
当一个 K 进制数的某一位大于9(即是一个两位数)时,无法用自然数表示,就会用字母代替。(通常是大写字母)
比如说 16 进制数 AB 就是 10 进制内的 171(计算过程略)。
A代表 10 进制内的 10,B代表 11,以此类推,这里不再赘述。
10进制转K进制方法(整数)
Question:十进制数 20 用 二进制 表示是多少?
短除法
将 20 用短除法不断除以 2 ,并且保留得到的余数,将余数倒序记录下来。
20 / 2 = 10...0 20 / 2 = 10 ... 0 20/2=10...0
10 / 2 = 5...0 10 / 2 = 5 ... 0 10/2=5...0
5 / 2 = 2...1 5 / 2 = 2 ... 1 5/2=2...1
2 / 2 = 1...0 2 / 2 = 1 ... 0 2/2=1...0
得 10100。这里特殊的是,最后一个算式的商也要算进得数。
再举例
再举例。
Question:十进制数 250 用八进制数表示是什么?
根据上文,将十进制数转化为二进制的方法是除以二。不妨猜出,转化成八进制就是不断除以8。将十进制数转化为K进制,就是不断除以K,取余数,最后倒序记录余数。
计算过程如下:
250 / 8 = 31...2 250/8=31...2 250/8=31...2
31 / 8 = 3...7 31/8=3...7 31/8=3...7
3 / 8 = 0...3 3/8=0...3 3/8=0...3
开头的0省去,最终答案得 372 。
(注:由于不方便写短除过程,建议手推一遍,会比较清晰)
K进制转十进制方法(小数)
Question:二进制数 10.01 转十进制是多少?
位权相乘法
首先,先将 10.01 的整数和小数部分分开,得到 10 和 0.01。
先计算 10 转化为十进制数是 ( 0 ∗ 2 0 ) + ( 1 ∗ 2 1 ) = 2 (0*2^0)+(1*2^1)=2 (0∗20)+(1∗21)=2 ,然后使用类似的方法计算小数部分。
小数部分的计算也是将每一位上的数字乘以对应的位权,十分位的位权是 K − 1 K^{-1} K−1 (K代表进制),百分位的位权是 K − 2 K^{-2} K−2 ,......依次类推。
那么我们轻松地可以得到:
| 二进制位 | 0 | 1 |
|---|---|---|
| 位权 | 2 − 1 2^ {-1} 2−1 | 2 − 2 2^ {-2} 2−2 |
| 相乘结果 | 0 | 0.25 |
然后计算小数部分代表的数值:
( 0 ∗ 2 − 1 ) + ( 0 ∗ 2 − 2 ) = 0 + 0.25 = 0.25 (0*2^{-1})+(0*2^{-2})=0+0.25=0.25 (0∗2−1)+(0∗2−2)=0+0.25=0.25
最后,我们将小数部分和整数部分代表的数值相加:
2 + 0.25 = 2.25 2+0.25=2.25 2+0.25=2.25
由此得到,二进制数 10.01 用十进制表示为 2.25 。
再举例
Question:十六进制数 EA.26 用十进制如何表示?
分离小数部分和整数部分,分别是"EA"和"0.26"。
先计算整数部分: ( 10 ( A ) ∗ 16 0 ) + ( 14 ( E ) ∗ 16 1 ) = 10 + 224 = 234 (10(A)*16^0)+(14(E)*16^1)=10+224=234 (10(A)∗160)+(14(E)∗161)=10+224=234
然后计算小数部分: ( 2 ∗ 16 − 1 ) + ( 2 ∗ 16 − 2 ) = 0.125 + 0.0234375 = 0.1484375 (2*16^{-1})+(2*16^{-2})=0.125+0.0234375=0.1484375 (2∗16−1)+(2∗16−2)=0.125+0.0234375=0.1484375
最后将小数代表的值和整数代表的值相加: 234 + 0.1484375 = 234.1484375 234+0.1484375=234.1484375 234+0.1484375=234.1484375
得到十六进制数 EA.26 转化为十进制数是 234.1484375
这里需要注意,在计算十六进制数的转化的时候,可能会遇到含有字母的情况,即上文"字母表示"中所述。在这道题里,先将"EA"分别转化为"14"和"10",再进行计算,这样的计算方式更便捷一点。
十进制转K进制方法(小数)
乘K取整法
Question:十进制小数 21.625 用二进制如何表示?
同样如转化十进制一样,我们先把整数部分和小数部分分开计算,得到两个部分:"21"和"0.625"。
计算整数部分用二进制的表示:(过程繁琐,略过) 10101 10101 10101
小数部分要一直将其乘 2 ,直到乘积为 1.0 1.0 1.0 而止。计算过程如下:
| 计算步骤 | 乘法公式 | 乘积 | 整数部分 | 剩余小数 |
|---|---|---|---|---|
| 第1步 | 0.625 × 2 0.625 × 2 0.625×2 | 1.25 | 1 | 0.25 0.25 0.25 |
| 第2步 | 0.25 × 2 0.25 × 2 0.25×2 | 0.5 0.5 0.5 | 0 | 0.5 0.5 0.5 |
| 第3步 | 0.5 × 2 | 1.0 1.0 1.0 | 1 | 0.0 0.0 0.0 |
然后(不是逆序)顺序记录它们:101
将整数部分与小数部分组合得:10101.101
再举例
再举例。
Question:将十进制小数 0.78125 转换为八进制是多少?
计算小数部分:
| 计算步骤 | 乘法公式 | 乘积 | 整数部分 | 剩余小数 |
|---|---|---|---|---|
| 第1步 | 0.78125 × 8 0.78125 × 8 0.78125×8 | 6.25 6.25 6.25 | 6 | 0.25 0.25 0.25 |
| 第2步 | 0.25 × 8 0.25 × 8 0.25×8 | 2.0 2.0 2.0 | 2 | 0.0 0.0 0.0 |
顺序组合,最终答案得:0.62
参考代码
输入:第一行两个正整数 N N N、 M M M,第二行一个 N N N 进制数 x x x。
输出:在 M M M 进制下的 x x x。
cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
// 字符转数值
int charToInt(char c) {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
return c - 'a' + 10; // 小写字母
}
// 数值转字符
char intToChar(int x) {
if (x < 10) return '0' + x;
return 'A' + (x - 10);
}
int main() {
int N, M;
string s;
cin >> N >> M >> s;
// 1. N进制转十进制(使用long long防止溢出)
long long dec = 0;
for (char c : s) {
dec = dec * N + charToInt(c);
}
// 2. 十进制转M进制
if (dec == 0) {
cout << "0" << endl;
return 0;
}
string result;
while (dec > 0) {
result.push_back(intToChar(dec % M));
dec /= M;
}
reverse(result.begin(), result.end());
cout << result << endl;
return 0;
}
涉及到的数学知识
整数的负数次方
计算公式:
a − n = 1 a n ( a ≠ 0 , n > 0 ) a^{-n} = \frac{1}{a^n} \quad (a \neq 0, n > 0) a−n=an1(a=0,n>0)
例子:
2 − 1 = 1 2 1 = 1 2 = 0.5 2^{-1}=\frac{1}{2^{1}}=\frac{1}{2}=0.5 2−1=211=21=0.5
一个数的0次方为1
对于任意一个数,其 0 次方的值为 1(而不是 0 )。
例子:
3 0 = 5 0 = 32 0 = 1 3^0=5^0=32^0=1 30=50=320=1
题目推荐
推荐洛谷上适合练习的题目(顺序与题目难度无关):
学习资料
from:oi-wiki
【上篇】暂时完
近 1w 字(SOS),感觉我废话太多了,要写一篇精炼点的(手动捂嘴)。
可能不会有人看到最后,但是如果你看到了,谢谢你的阅读,我们下次再见。