初学者必背【考点清单(大全)】【上篇】

建议初学 C++ 的同学阅读,文中大部分内容是为地方举办的小考试、或另一些学校的考试量身定做的。文章选取了很多在平时很难刷到、考场上会令你犹豫不决的题目。 并且每一个选项都有详细的解析和考点总结。

因为有些点写不完或者暂时没有想到,所以本文是上篇,可能出中篇和下篇,最后不断改进整理成合集。

好啦,话不多说,开始吧。阅读之前,请你留下宝贵的赞。

推荐 《基本算法(暴力/贪心/递归/递推/二分)》


变量名规则 \textcolor{orange}{变量名规则} 变量名规则

规则

  1. 不可以是 C++ 中的关键字(如 intusing 等)。
  2. 不可以用数字开头。
  3. 可以包含大小写字母、数字和下划线。除此之外其他字符不可以包含。
  4. 区分大小写(如 Aa 是不一样的)。

考场秘诀:关键字打在 C++ 上会变粗(小熊猫:变蓝),不是关键字则不会。

是关键字:

不是关键字:

易错/易考点

  • 【常考】 知识点:变量名中可以有下划线。

  • 易错点: 下划线是 _,不是 -,后者是不能出现的。不要混淆了。

例: 下列哪些变量名是合法的?

top-to-the-123_jc_12_jfkds_int_using

(答案:除第一个外都是合法的)

解析

  1. 第一个 top-to-the-123 很明显出现了 -,不是字母、数字、下划线,所以不合法。

  2. 第二个虽然只有一个字符 _,但是合法的,可以以下划线开头。这里容易错!

  3. 虽然第三个 jc_12_jfkds_int_using 出现了 intusing 两个关键字,但是除了这两个之外还是有其他的字母,且都合法。也容易错!

注意了:cincout 不是 关键字!(考试极易考到)

但是作为变量仍然可以运行:

所以,cincout 是合法的变量名

练习

一、请口述回忆变量名的四个规则,并尝试举例。

二、【必练】请问下列哪些是合法的变量名?

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.不要在规则上"反复横跳"

例如 cincout 虽然是合法的变量名,但是这样的写法不仅容易使逻辑错乱、代码可读性差,还会让你在阅读上花费大把的时间。

千万不要!

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
例子

cpp 复制代码
cout<<(6>5?"YES":"NO);
/*
这段代码的最终输出:YES
因为 6>5 成立,所以执行第一项,就是 YES
*/

考法1:嵌套三目运算符

因为我们知道:a?b:c,一定会执行 bc 中的某一个。

所以这种考法就是使得 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

题目推荐

推荐洛谷上适合练习的题目(顺序与题目难度无关):

P1143 进制转换

P2084 进制转换

B2143 进制转换

B3869 [GESP202309 四级] 进制转换

(或者点我)

学习资料

from:oi-wiki

oi-wiki--《进位制》


【上篇】暂时完

近 1w 字(SOS),感觉我废话太多了,要写一篇精炼点的(手动捂嘴)。

可能不会有人看到最后,但是如果你看到了,谢谢你的阅读,我们下次再见。

相关推荐
两年半的个人练习生^_^2 小时前
每日一学:设计模式之原型模式
java·开发语言·设计模式·原型模式
并不喜欢吃鱼2 小时前
从零开始C++----二.(下篇)模版进阶与编译全过程的复习
开发语言·c++
23471021272 小时前
4.17 学习笔记
开发语言·软件测试·笔记·python·学习
智者知已应修善业2 小时前
【51单片机按键控制流水灯+数码管显示按键次数】2023-6-15
c++·经验分享·笔记·算法·51单片机
汉克老师2 小时前
GESP2023年12月认证C++三级( 第三部分编程题(1、小猫分鱼))
c++·算法·模拟算法·枚举算法·gesp三级·gesp3级
不知名的老吴2 小时前
View的三大特性之一:迟绑定
开发语言·c++·算法
red_redemption2 小时前
自由学习记录(167)
学习·pawn是客体·pcontroller是主体·world是概念体
扣脑壳的FPGAer2 小时前
数字信号处理学习笔记--Chapter 1.4.1 时域采样定理基本概念
笔记·学习·信号处理
矢志航天的阿洪2 小时前
面目标 SAR 回波整体处理过程(教学技术文档)面目标 SAR 回波整体处理过程(教学技术文档)
学习