02 基础语法:变量 / 数据类型 / 运算符 / 输入输出 / 分支 / 循环
GESP 1-2 级CSP-J 基础
级别标注:GESP 1-2 级(考级要求)/ CSP-J 必备基础(竞赛进阶)。
一、变量与基本数据类型
C++ 常用内置类型(sizeof 为 64 位系统典型值,实际以平台为准):
| 类型 | 关键字 | 字节 | 取值范围(典型) |
|---|---|---|---|
| 整型 | int |
4 | -2147483648 ~ 2147483647(-2^31 ~ 2^31-1) |
| 长整型 | long long |
8 | -2^63 ~ 2^63-1 |
| 无符号整型 | unsigned int |
4 | 0 ~ 4,294,967,295 |
| 字符 | char |
1 | 存 ASCII 码(与整数互通) |
| 布尔 | bool |
1 | true / false |
| 单精度浮点 | float |
4 | 约 7 位十进制有效数字(IEEE 754 单精度,尾数 24 位) |
| 双精度浮点 | double |
8 | 约 15~16 位十进制有效数字(IEEE 754 双精度,尾数 53 位) |
C++ 实例
#include <iostream>
using namespace std;
int main() {
int a = 10; // 整型
long long b = 10000000000LL; // 超出 int 范围必须用 long long,LL 后缀
double x = 3.14159; // 浮点
char ch = 'A'; // 字符用单引号
bool ok = true; // 布尔
cout << a << " " << b << " " << x << " " << ch << " " << ok << endl;
return 0;
}
形象理解变量像贴了标签的收纳盒:
int a = 10; 就是拿一个能装整数的盒子贴上名字 a、放进 10。盒子容量不同——int 小、long long 大、double 能装小数;装错类型会“装不下”(溢出)或“变样”(截断)。考级视角GESP 1-2 级常考 char 与 int 互通:
'A' 的 ASCII 是 65,char ch = 'A'; int k = ch; 得 65;反过来 char c = 65; 就是 'A'。这是读程序题高频考点。二、常量与变量声明的 C++17 细节
C++ 实例
const int MAXN = 10005; // const 常量,建议数组大小用 const
int arr[MAXN]; // 用常量定义数组长度是良好习惯
易错点数组大小必须是编译期常量:
int n; cin >> n; int a[n]; 在个别编译器能过,但 C++ 标准不允许,OJ 上可能 Runtime Error。正确写法:const int MAXN = 10005; int a[MAXN]; 或改用 vector。三、输入输出
3.1 cin / cout(推荐初学)
C++ 实例
#include <iostream>
#include <iomanip> // fixed / setprecision 需要该头文件
using namespace std;
int main() {
int a; double x; char ch;
cin >> a >> x >> ch; // 连续读入,cin 自动跳过空白
cout << a << " " << x << " " << ch << endl;
cout << "格式化: " << fixed << setprecision(2) << x << endl; // 保留2位小数
return 0;
}
使用
fixed << setprecision(2)需要#include <iomanip>。
3.2 scanf / printf(竞赛速度优化)
C++ 实例
#include <cstdio>
int main() {
int a; long long b;
scanf("%d%lld", &a, &b); // %d 读 int,%lld 读 long long
printf("%d %lld\n", a, b);
return 0;
}
3.3 字符串输入
C++ 实例
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1; // 不含空格的普通单词
cin >> s1; // 遇空格/换行停止
string s2;
getline(cin, s2); // 读一整行(含空格)
cout << s1 << "\n" << s2 << endl;
return 0;
}
形象理解
cin 像自动吸尘器——自动跳过空格换行、按类型“吸”走数据;getline 像整段搬运工——连空格一起搬走一整行。两者混用时,cin 留下的换行符会让 getline 先读到空行,这是经典坑。易错点先
cin >> x; 再 getline(cin, s); 时,务必先写 cin.ignore(); 吃掉残留的换行符,否则 s 会是空字符串。四、运算符
4.1 算术运算符
+ - * /(整除,整数相除向下取整)%(取余)。注意:整数 / 整数 结果为整数。
C++ 实例
cout << 7 / 2 << endl; // 输出 3(不是 3.5)
cout << 7.0 / 2 << endl; // 输出 3.5
cout << 7 % 2 << endl; // 输出 1
4.2 关系与逻辑运算符
C++ 实例
// 关系:== != > < >= <=
// 逻辑:&&(且) ||(或) !(非)
bool r1 = (3 > 2) && (1 < 2); // true
bool r2 = (3 > 2) || (5 < 1); // true
bool r3 = !(3 > 2); // false
cout << r1 << " " << r2 << " " << r3 << endl;
4.3 赋值与自增自减
C++ 实例
int a = 5;
a += 3; // a = 8,等价 a = a + 3
int b = a++; // 先用后加:b 取 a 的原值 8,然后 a 变 9
int c = ++a; // 先加后用:a 变 10,c 取 10
cout << a << " " << b << " " << c << endl; // 10 8 10
易错点整数除法:
5 / 2 得 2 而不是 2.5;取模符号:-7 % 3 在 C++ 中结果是 -1(符号跟随被除数)。这两条是读程序题最容易失分的点。考级视角自增自减
a++(先用后加)与 ++a(先加后用)是 GESP 1-2 级读程序题必考;建议在草稿纸上画“取值时间线”,逐个变量标注变化,避免心算出错。五、分支结构 if / else if / else
C++ 实例
#include <iostream>
using namespace std;
int main() {
int score;
cin >> score;
if (score >= 90) {
cout << "A" << endl;
} else if (score >= 80) {
cout << "B" << endl;
} else if (score >= 60) {
cout << "C" << endl;
} else {
cout << "D" << endl;
}
return 0;
}
条件表达式(三目运算符)
C++ 实例
int n; cin >> n;
int m = (n % 2 == 0) ? 1 : 0; // n 为偶数 m=1,否则 m=0
cout << m << endl;
形象理解if-else if 像医院分诊:从上往下,第一个满足条件的科室收治,后面的不再看。所以区间判断的顺序很重要——先写大范围会把后面的分支全部“拦截”。
易错点条件顺序写反会导致逻辑漏洞:先写
score >= 60 再写 score >= 90,90 分的人会先命中“>=60”分支,永远走不到 A。规则:范围判断从小到大(或从大到小)严格排序。六、循环结构
6.1 for 循环
C++ 实例
// 输出 1~10
for (int i = 1; i <= 10; i++) {
cout << i << " ";
}
cout << endl;
// 倒数输出 10~1
for (int i = 10; i >= 1; i--) {
cout << i << " ";
}
cout << endl;
6.2 while 循环
C++ 实例
int n; cin >> n;
int sum = 0;
while (n > 0) { // 逐位求和
sum += n % 10;
n /= 10;
}
cout << sum << endl;
6.3 do-while(至少执行一次)
C++ 实例
int n = 10, cnt = 0;
do {
n -= 2;
cnt++;
} while (n > 0);
cout << cnt << endl; // 5(n 依次为 8、6、4、2、0 共循环 5 次)
6.4 break / continue
C++ 实例
for (int i = 1; i <= 10; i++) {
if (i == 5) continue; // 跳过本次
if (i == 9) break; // 终止整个循环
cout << i << " "; // 1 2 3 4 6 7 8
}
cout << endl;
6.5 循环嵌套
C++ 实例
// 打印 1~5 的乘法表
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
cout << i << "*" << j << "=" << i * j << " ";
}
cout << endl;
}
形象理解for 循环像数台阶:从第 1 级数到第 10 级(初始化
i=1,检查 i<=10,每步 i++);while 像“走到没糖为止”,条件成立就继续;do-while 像“先吃一口再说”,至少执行一次。易错点死循环三件套:忘记更新循环变量、条件恒真、
i-- 误写成 i++ 永远到不了终点。程序卡死时优先检查这三处。七、易错点 / 常见坑点
- ⚠️ 整数除法陷阱:
5/2 == 2,需要小数时把其中一个数写成5.0/2或(double)5/2。 - ⚠️ int 溢出:数据可能超过 2147483647(约 21.47 亿)时,务必用
long long;读入格式对应%lld或cin(cin 自动适配)。 - ⚠️
==vs=:判断相等用==,赋值用=;if(a=5)是"把 5 赋给 a,恒为真"的经典错误。 - ⚠️ 浮点比较:不要直接用
double x == 0.1判等,用fabs(x - 0.1) < 1e-9(需要#include <cmath>)。 - ⚠️ 循环边界:
for(i=1; i<=n; i++)与< n容易差一,先想清闭开区间。 - ⚠️ char 与 int 混算:
'0' + 5得到字符'5'的 ASCII(53),字符转数字用ch - '0'。 - ⚠️
cin/cout关闭同步可提速:ios::sync_with_stdio(false); cin.tie(nullptr);(第 19 章详述)。
八、考级要求 vs 竞赛进阶
- 考级要求(GESP 1-2 级):会声明变量、四则运算、if-else 分支、for/while 循环、嵌套循环、读入输出。1 级涉及顺序/分支/循环基本结构,2 级扩展至多层分支与嵌套循环、数据类型转换。
- 竞赛进阶(CSP-J):必须掌握
long long范围判断、输入输出优化、while 常用于读未知个数数据、EOF 读取。
九、课内练习建议
- 求 1~100 的和与平均值。
- 判断输入的三位数是否为"水仙花数"(各位立方和等于本身)。
- 输出 1-100 内所有能被 3 整除但不能被 5 整除的数。
- 读入一个正整数,逆序输出它的各位数字(如 1234 → 4321)。