#10160. 2026/9/6/C++基础笔记

2026/9/6/C++基础笔记

C++ 基础做题与易错点复习笔记

复习提纲

  1. 看懂一道编程题:输入、处理、输出。
  2. 分清变量:数量、当前数据、循环编号、答案。
  3. 写好循环:读入位置、循环次数、初始值、输出位置。
  4. 写好判断:等号、范围、分支和括号。
  5. 检查答案:格式、样例、边界和错误原因。

一、怎样才算做对一道题?

一道题的基本过程是:读入数据 → 按要求处理 → 输出答案。

程序能运行,不代表答案正确;样例通过,也不代表整道题正确。

一般的编程题评测会使用多组测试数据,检查程序能否在规定限制内给出符合要求的答案。有些比赛有部分分,但通常根据测试点或子任务是否通过给分,不是阅读代码给“过程分”。

写代码前先回答:

  • 题目给了什么数据?
  • 要根据这些数据做什么?
  • 最后要输出什么,有几个结果?

**提交前核对题目和代码是否对应。**判断奇偶的程序,不能提交到比较十位和个位的题目;求最大值的程序,也不能提交到时间计算题目。

二、输入格式决定读什么,不能自己猜

情况一:输入 n,输出 1 到 n

输入只有一个数。后面的数字由循环产生,不需要再输入。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cout<<i<<endl;//依次输出,每行一个数
	}
	return 0;
}

输入:

3

输出:

1
2
3

情况二:输入 n,再输入 n 个数

每次循环都要读取一个新数据。

int n,a;
cin>>n;//先读取数量
for(int i=1;i<=n;i++){
	cin>>a;//每次读一个,共读n个
	//在这里处理刚读到的a
}

下面这样会多读取一个数:

cin>>n>>a;//这里已经读取了第一个数据
for(int i=1;i<=n;i++){
	cin>>a;//这里又尝试读取n个数据
}

需要处理多少个数,就按输入格式读取多少个:不多读、不漏读。

对于这里的整数输入,cin>>a 会跳过数字前的空格和换行。不要把“输入有两行”理解成“只能写两次 cin”,关键是读入的数据数量和顺序。

三、先分清变量的含义

变量 在循环输入题中的含义
n 一共有多少个数
i 当前处理第几个数
a 当前读到的数
s 或 cnt 已找到多少个符合条件的数
sum 已经算出的总和

例如输入:

3
8 2 90
循环次数 i a
第一次 1 8
第二次 2
第三次 3 90

判断“当前的数是否大于等于 5”,要写 if(a>=5),不是 if(i>=5)

不要在循环中写 cin>>n 读取当前数据,这样会把“总数量”改掉,循环次数也可能随之改变。

变量使用前,必须有值

int x;
cout<<x;//错误:x还没有输入或赋值

在函数里写 int x;,不代表它自动等于零。

新增变量前先想:它表示什么?它的值从哪里来?

四、循环中的三个关键位置

1. 每个数据都要输入:cin 放在循环里面

统计直角数量:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a,s=0;//最开始找到的直角数量为0
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a;//每次读一个新的角度
		if(a==90){
			s++;//找到一个直角,数量增加1
		}
	}
	cout<<s;//全部检查完,只输出一次总数
	return 0;
}

如果只在循环前读一次角度,循环中没有 cin>>a,就会反复检查同一个角。

2. 最终结果只输出一次:cout 放在循环后面

求 1 到 n 的和:

int n,sum=0;
cin>>n;
for(int i=1;i<=n;i++){
	sum+=i;//依次加1、2、3……n
}
cout<<sum;//答案保存在sum中,不是n中

当 n 为 3 时:

执行后 sum
初始 0
加上1 1
加上2 3
加上3 6

如果每次写 sum+=n,就变成反复加同一个 n;如果最后写 cout<<n,则输出的是输入数据,不是计算结果。

如果把输出放进循环,会打印中间结果。是否需要这样做,要看题目的输出要求。

3. return 0 放在所有任务完成之后

return 0; 会结束程序。放在循环里面,可能刚执行一次就结束,后面的数据还没处理。

另外,写在 for(int i=...) 中的 i,只在这个循环范围内使用,不要在循环结束后用它输出答案。

五、初始值、起点、终点、步长

求和、计数从 0 开始,连乘从 1 开始

int sum=0;//还没加任何数
int s=0;//还没找到符合条件的数
int ans=1;//连乘不能从0开始

求 1×2×…×n,在结果不超出 int 范围的题目中:

int ans=1;
for(int i=1;i<=n;i++){
	ans*=i;
}
cout<<ans;

如果 ans 从 0 开始,每一步都是零乘一个数,结果永远是零。

每次增加多少,要写清楚

从 a 开始,每次增加 3,不超过 b:

for(int i=a;i<=b;i+=3){
	cout<<i<<" ";
}

例如 a=2、b=9,i 依次是 2、5、8;再增加 3 得到 11,已经超过 9,循环结束。

不是随便找一个变量写 cout<<c+3;,而是让循环中的数按要求变化。

六、条件判断:把中文条件翻译完整

= 是赋值,== 是判断相等

a=5;//把a的值改成5
if(a==5){//判断a是不是5
	cout<<"YES";
}

比较十位和个位是否相等时,要写 if(a==b),不能写 if(a=b)

并且用 &&,或者用 ||

题目中的条件 代码
不少于10、至少10 a>=10
超过10 a>10
不超过10 a<=10
90到100之间,含两端 a>=90&&a<=100
小于0或者大于100 a<0||a>100
能被4整除 a%4==0

s>=90&&s<=100 的左右两边都是完整的判断,不能省成 s>=90&&<=100,也不要写成数学里的连写形式。

“能被4整除”不能只写 a%4。我们要判断的是“余数等于0”。

只选择一个结果:使用 if / else if / else

分数在 0 到 100 之间,90分及以上为A,75分及以上为B,60分及以上为C,其余为D:

if(s>=90){
	cout<<"A";
}else if(s>=75){
	cout<<"B";
}else if(s>=60){
	cout<<"C";
}else{
	cout<<"D";
}

走到第二个判断时,已经知道 s 小于90,因此只需要继续判断是否达到75。

每个数据都要比较:不能跳过后面的 if

找四个数的最大值:

int a,b,c,d;
cin>>a>>b>>c>>d;
int ma=a;//先把第一个数作为当前最大值
if(b>ma) ma=b;
if(c>ma) ma=c;
if(d>ma) ma=d;
cout<<ma;

这里三个判断都要执行。不能全连成 else if,否则前面成立后,后面的数就不会比较。

是否使用 else,要看后面的事情还需不需要继续做,不是固定套写法。

七、括号与缩进也能帮助减少错误

商品价格至少10元就减2元,否则原价输出:

if(a>=10){
	cout<<a-2<<" ";
}else{
	cout<<a<<" ";
}

else 要放在 if 对应的右大括号之后,不要放进 if 的大括号里面。

完整的循环处理:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a;
		if(a>=10){
			cout<<a-2<<" ";
		}else{
			cout<<a<<" ";
		}
	}
	return 0;
}

每进入一层大括号,就缩进一级。缺少右大括号、使用了未定义的变量,都可能导致编译错误。遇到编译错误,先检查第一条报错附近,不要盲目修改全部代码。

八、计算与输出的常见细节

1. 先统一单位,再计算

h小时m分钟,一共是:

int all=h*60+m;//全部换成分钟

如果再过t分钟,并且题目保证当天结束:

int all=h*60+m+t;
cout<<all/60<<" "<<all%60;//小时和分钟

每一步都要知道变量的单位。不要用还没有赋值的 x 参与计算。

2. / 求商,% 求余数

n支笔,每盒装k支,装满的盒数是 n/k,剩余支数是 n%k

cout<<n/k<<" "<<n%k;

3. 整数除法会丢掉小数部分

double avg=(a+b+c)/3.0;//使用3.0,让除法保留小数
printf("%.1f",avg);//按题意保留1位小数

即使左边是 double,右边写 (a+b+c)/3,仍会先进行整数除法,之后不能自动找回小数。

4. 算对还要输出对

输出要求 写法
两个数之间用空格分隔 cout<<a<<" "<<b;
两个数分别占一行 cout<<a<<endl<<b<<endl;
输出指定单词 cout<<"YES";

如果 a=6、b=5,cout<<a<<b; 会输出 65,而不是两个分开的数。

题目要求 ONES,就不能写成 OENS;要求整数,就按整数格式输出,不要随意加上小数。

不同评测对空白和数值误差的处理可能不同。最稳妥的方法是:**按照题目规定输出,不依赖评测放宽要求。**不要额外打印“请输入”“答案是”等文字。

九、样例检查之后,还要自己测试

样例有两个作用:帮助理解题意,帮助初步检查代码。

样例不一致时先查原因;样例一致时再补测其他情况。

题目 可以补充的测试
输出1到n n=1,检查有没有漏掉1
商品优惠 9、10、11,检查10是否优惠
统计直角 没有直角、全部直角、只有最后一个是直角
求和 n=3,应得到6,不是3或9
连乘 n=1得到1,n=3得到6
最大值 最大值放在首位、末位,几个数全为负数
分数等级 59、60、74、75、89、90、100

输出错了,拿一组很小的数据,逐行看变量变化:

  1. cin 实际读到了哪个数?
  2. 进入循环时,i、当前数据、答案分别是多少?
  3. if 条件到底成立不成立?
  4. 执行后变量变成了多少?
  5. 最后 cout 输出的是哪个变量?

**不要用“随便换一个符号试试”代替检查原因。**修改后重新运行原来出错的数据,再检查样例。

十、提交前一分钟检查

  • 我提交的代码,解决的是当前这道题吗?
  • 输入数量和顺序有没有多读、漏读、读反?
  • n、i、当前数据和答案有没有混淆?
  • 变量用之前有值吗?求和、计数、连乘的初值正确吗?
  • 循环起点、终点、步长,以及 cin、cout 的位置正确吗?
  • 等号、并且、或者、分界线是否正确?
  • 所有数据都处理完了吗?有没有提前 return?
  • 输出变量、空格、换行、单词和小数位数符合要求吗?

读清题目,写清每个变量的作用,用小数据一步一步检查,比反复猜着修改更有效。