C++ 核心知识点汇总(第一日)
一、变量
1. 变量定义与命名规则(必考考点)
(1)变量定义语法
变量是程序中可修改的存储单元,定义必须指定数据类型,支持"定义即初始化"或"先定义后赋值":
cpp
// 推荐:定义时初始化(避免野值)
int score = 95;
double pi = 3.14159;
char ch = 'A';
// 不推荐:先定义后赋值(未初始化的变量值随机)
int age;
age = 18;
(2)命名规则(高频错题点)
C++变量名必须符合"标识符规则",以下是合法/非法对比表:
| 规则要求 | 合法示例 | 非法示例 | 非法原因 |
|---|---|---|---|
| 只能包含字母、数字、下划线 | _userName、score100、MAX_AGE |
user-name、score 100、Man&Woman |
含减号、空格、特殊符号(&) |
| 首字符不能是数字 | star5、FiveStar |
5Star、0x321 |
以数字开头 |
| 不能是C++关键字 | int_age、float_score |
int、break、if |
关键字是语言保留字 |
| 不能是标准库标识符(潜规则) | my_cin、my_printf |
cin、cout、scanf、printf |
虽非关键字,但会覆盖标准库功能 |
| 区分大小写 | Score、score |
- | 两个不同的变量 |
真题考点:
five-Star(含减号)、red star(含空格)、CCF GESP(含空格)、2_from(数字开头)均为非法变量名;_Var_1、five_star、fiveStar、_fiveStar均为合法变量名。
(3)关键字列表(入门必记)
入门阶段需避开的核心关键字:
int、char、double、float、bool、long、short、if、else、for、while、const、return、void
2. 常量:不可修改的"固定值"
常量是程序运行中值不变的量,分为字面常量 和自定义常量:
(1)字面常量(直接写在代码里的值)
| 常量类型 | 示例 | 数据类型说明 |
|---|---|---|
| 整数常量 | 100、-5 |
默认int类型 |
| 字符常量 | '3'、'A'、' ' |
char类型(底层是ASCII值) |
| 浮点常量 | 3.14、7.0 |
默认double类型(float需加f后缀:3.14f) |
| 字符串常量 | "10"、"Hello" |
const char*类型(非基本类型) |
真题考点:
'3'是char类型(ASCII值51),不是int类型;3.14是double类型,不是float类型。
(2)自定义常量
-
const常量 (推荐):有类型检查,编译期确定值cppconst int MAX_SCORE = 100; // MAX_SCORE = 120; // 编译报错:常量不可修改 -
#define宏常量 (不推荐):文本替换,无类型检查cpp#define PI 3.14 // PI = 3.1415; // 编译报错:宏常量不可修改
3. 字符常量与ASCII编码(核心底层知识)
字符常量用单引号'包裹,底层存储的是ASCII编码值(0-127的整数),因此字符可直接参与算术运算:
(1)核心ASCII对应表(必考)
| 字符范围 | ASCII值范围 | 运算示例 |
|---|---|---|
'0' ~ '9' |
48 ~ 57 | '5' - '0' = 5(字符转数字) |
'A' ~ 'Z' |
65 ~ 90 | 'A' + 32 = 'a'(大写转小写) |
'a' ~ 'z' |
97 ~ 122 | 'z' - 32 = 'Z'(小写转大写) |
' '(空格) |
32 | - |
(2)字符运算示例(真题高频)
cpp
// 示例1:字符转数字
char ch1 = '8';
int num1 = ch1 - '0'; // '8'的ASCII值56 - '0'的48 = 8
cout << num1; // 输出:8
// 示例2:数字转字符
int num2 = 9;
char ch2 = num2 + '0'; // 9 + 48 = 57,对应字符'9'
cout << ch2; // 输出:9
// 示例3:字母大小写转换
char ch3 = 'M';
ch3 = ch3 + 32; // 77 + 32 = 109,对应字符'm'
cout << ch3; // 输出:m
真题坑点:
'9' + '1'不是10,而是57 + 49 = 106(对应字符'j');a = '2'时,a + 1会让a变为'3',但a + 1;(无赋值)不会改变a的值。
二、 输入输出
(1)C 风格:printf & scanf
一、printf 函数核心基础
格式字符串构成
printf 的核心是格式字符串(format),分为两类内容:
- 普通字符:原样输出(如字母、数字、空格、逗号、中文等);
- 格式说明符 :以
%开头,用于指定可变参数的输出格式,是printf的核心。
二、格式说明符完整语法
格式说明符的标准完整语法(方括号内为可选部分):
%[width][flags][.precision][length]specifier
| 组成部分 | 作用 | 是否必填 |
|---|---|---|
width |
指定输出的最小字符宽度 | 否 |
flags |
控制对齐、填充、符号等样式 | 否 |
.precision |
指定输出精度(小数位数/最小位数/字符串长度) | 否 |
length |
修饰数据类型长度(适配不同字节的整数/浮点数) | 否 |
specifier |
核心格式符,指定数据类型(如d表示整数、f表示浮点数) |
是 |
1. width(输出宽度):指定最小字符数
width 定义输出的最小字符宽度 ,实际宽度超过时按实际输出,不足时按flags填充(无flags则补空格)。
| width 写法 | 说明 | 示例 | 输出结果 |
|---|---|---|---|
| 数字 | 固定宽度 | printf("%10d", 234) |
234(前补7空格) |
* |
动态宽度(参数指定) | printf("%*d", 5, 10) |
10(前补3空格) |
width 示例
c
#include <stdio.h>
int main() {
int n = 234;
float f = 9.8f;
char c = '@';
char str[] = "C Language is great";
// 分别指定宽度:10(int)、12(float)、4(char)、8(string)
printf("%10d%12f%4c%8s\n", n, f, c, str);
// 动态宽度(第一个参数5指定宽度)
printf("动态宽度:%*d\n", 5, 100);
return 0;
}
输出:
234 9.800000 @C Language is great
动态宽度: 100
解释 :字符串str实际长度19>指定宽度8,因此按实际输出;整数、浮点数、字符不足宽度时默认补空格(右对齐)。
2. flags(标志位):控制输出样式
flags 用于调整对齐、填充、符号等,多个标志可组合使用(如%-010d),优先级:左对齐- > 0填充0 > 默认右对齐。
| flags | 说明 | 适用场景 | 示例(输入值) | 输出结果 |
|---|---|---|---|---|
- |
左对齐(默认右对齐) | 所有类型 | printf("%-10d", 192) |
192 (后补7空格) |
+ |
强制显示正负号(正数+,负数-) | 整数/浮点数 | printf("%+d", 192) |
+192 |
| 空格 | 正数前补空格,负数前补- | 整数/浮点数 | printf("% d", 192) |
192(前补1空格) |
# |
1. 八进制加前缀0,十六进制加0x/0X 2. 浮点数强制显示小数点 |
o/x/X/a/A/e/E/f/F/g/G |
printf("%#x", 100) printf("%#.0f", 84) |
0x64 84. |
0 |
宽度不足时左侧补0(默认补空格) | 整数/浮点数 | printf("%010d", 1977) |
0000001977 |
flags 组合示例
c
#include <stdio.h>
int main() {
int m = 192, n = -943;
float f = 84.342;
// 左对齐+宽度
printf("m=%10d, m=%-10d\n", m, m);
// 强制正负号
printf("m=%+d, n=%+d\n", m, n);
// 空格符号
printf("m=% d, n=% d\n", m, n);
// # + 0位小数(强制小数点)
printf("f=%.0f, f=%#.0f\n", f, f);
// 0填充+左对齐(0失效,优先左对齐)
printf("m=%-010d\n", m);
return 0;
}
输出:
m= 192, m=192
m=+192, n=-943
m= 192, n=-943
f=84, f=84.
m=192
3. 核心:specifier(格式字符)
specifier 是唯一必填项,决定输出数据的类型和形式,完整对照表如下:
| specifier | 输出形式 | 适用数据类型 | 示例(输入值) | 输出结果 |
|---|---|---|---|---|
d/i |
有符号十进制整数 | int/short/long | printf("%d", 392) |
392 |
u |
无符号十进制整数 | unsigned int/long | printf("%u", 7235) |
7235 |
o |
无符号八进制整数 | unsigned int/long | printf("%o", 100) |
144 |
x |
无符号十六进制(小写) | unsigned int/long | printf("%x", 100) |
64 |
X |
无符号十六进制(大写) | unsigned int/long | printf("%X", 100) |
64 |
f/F |
十进制浮点数(大小写一致) | float/double | printf("%.2f", 392.654) |
392.65 |
e |
科学计数法(小写) | float/double | printf("%e", 392.65) |
3.926500e+02 |
E |
科学计数法(大写) | float/double | printf("%E", 392.65) |
3.926500E+02 |
g |
%e/%f 较短形式(去末尾零) |
float/double | printf("%g", 392.6500) |
392.65 |
G |
%E/%F 较短形式(去末尾零) |
float/double | printf("%G", 392.6500) |
392.65 |
a/A |
十六进制浮点数(小/大写) | float/double | printf("%a", -3.14) |
-0xc.90fep-2 |
c |
单个字符 | char/int(ASCII值) | printf("%c", 65) |
A |
s |
字符串 | char* | printf("%s", "sample") |
sample |
p |
指针地址(十六进制) | void* | printf("%p", &age) |
0x7ffeefbff5c4 |
n |
存储已输出字符数(无输出) | int* | 见下文示例 | - |
% |
输出百分号(转义) | - | printf("%%") |
% |
特殊格式符 %n 示例
%n 不输出内容,仅将已输出的字符数存入指针指向的变量:
c
#include <stdio.h>
int main() {
int count = 0;
printf("Hello%n World\n", &count); // %n前输出了"Hello"(5个字符)
printf("已输出字符数:%d\n", count);
return 0;
}
输出:
Hello World
已输出字符数:5
4. .precision(精度):控制输出精度
.precision 对不同类型的含义完全不同,是printf最易出错的部分,核心规则如下:
| 适用 specifier | .precision 含义 | 示例(输入值) | 输出结果 |
|---|---|---|---|
d/i/o/u/x/X |
最小输出位数,不足补0;0则不输出0 | printf("%.9d", 123456) printf("%.0d", 0) |
000123456 (无输出) |
f/F/e/E/a/A |
小数位数(四舍五入),默认6位 | printf("%.2f", 882.923672) printf("%.4f", 882.923672) |
882.92 882.9237 |
g/G |
最大有效数字个数 | printf("%.3g", 123.456) |
123 |
s |
最大输出字符数(截断) | printf("%.5s", "abcdefghi") |
abcde |
.* |
动态精度(参数指定) | printf("%.*f", 2, 3.1415) |
3.14 |
precision 示例
c
#include <stdio.h>
int main(){
int n = 123456;
double f = 882.923672;
char *str = "abcdefghi";
// 整数精度(补0)
printf("n: %.9d %.4d\n", n, n);
// 浮点数精度(四舍五入/补0)
printf("f: %.2lf %.4lf %.10lf\n", f, f, f);
// 字符串精度(截断)
printf("str: %.5s %.15s\n", str, str);
// 动态精度(第一个参数3指定小数位数)
printf("动态精度:%.*f\n", 3, f);
return 0;
}
输出:
n: 000123456 123456
f: 882.92 882.9237 882.9236720000
str: abcde abcdefghi
动态精度:882.924
5. length(长度修饰符):适配数据类型长度
length 用于修饰specifier,适配不同字节长度的变量,避免类型不匹配导致的输出错误。
| length | 适用 specifier | 对应数据类型 | 示例 |
|---|---|---|---|
hh |
d/i/u/o/x/X/n |
signed char/unsigned char | printf("%hhd", (char)128) |
h |
d/i/u/o/x/X/n |
short int/unsigned short | printf("%hd", (short)32767) |
l |
d/i/u/o/x/X/n |
long int/unsigned long | printf("%ld", 650000L) |
ll |
d/i/u/o/x/X/n |
long long/unsigned long long | printf("%lld", 1234567890123LL) |
L |
f/F/e/E/g/G/a/A |
long double | printf("%Lf", 3.141592653589793238L) |
j |
d/i/u/o/x/X/n |
intmax_t/uintmax_t | printf("%jd", INTMAX_MAX) |
z |
d/i/u/o/x/X/n |
size_t | printf("%zu", sizeof(int)) |
t |
d/i/u/o/x/X/n |
ptrdiff_t | printf("%td", &a - &b) |
length 示例
c
#include <stdio.h>
#include <stdint.h> // 包含intmax_t/size_t
int main() {
long long num1 = 1234567890123LL;
long double num2 = 3.141592653589793238L;
size_t num3 = sizeof(double);
printf("long long: %lld\n", num1);
printf("long double: %.10Lf\n", num2);
printf("size_t: %zu\n", num3);
return 0;
}
输出:
long long: 1234567890123
long double: 3.1415926536
size_t: 8
三、特殊字符输出(转义+格式控制)
日常开发中常需输出反斜杠、单引号、双引号等特殊字符,核心规则如下:
| 要输出的字符 | 写法 | 示例 | 输出结果 |
|---|---|---|---|
反斜杠 \ |
\\(转义) |
printf("路径:C:\\test\\file.txt") |
路径:C:\test\file.txt |
单引号 ' |
\' 或 直接写 |
printf("字符:%c 或 '%c'", 'a', 'b') |
字符:a 或 'b' |
双引号 " |
\"(转义) |
printf("字符串:\"Hello\"") |
字符串:"Hello" |
百分号 % |
%%(转义) |
printf("进度:%d%%", 50) |
进度:50% |
换行符 \n |
\n |
printf("第一行\n第二行") |
第一行 第二行 |
制表符 \t |
\t |
printf("列1\t列2\t列3") |
列1 列2 列3 |
回车符 \r |
\r |
printf("倒计时3\r倒计时2") |
倒计时2(覆盖本行) |
特殊字符综合示例
c
#include <stdio.h>
int main() {
// 反斜杠+双引号
printf("文件路径:\"C:\\Program Files\\test.exe\"\n");
// 单引号+百分号
printf("字符'%c'的ASCII值:%d(正确率100%%)\n", 'A', 65);
// 制表符+换行符
printf("姓名\t年龄\t成绩\nTom\t14\t96.5\n");
return 0;
}
输出:
文件路径:"C:\Program Files\test.exe"
字符'A'的ASCII值:65(正确率100%)
姓名 年龄 成绩
Tom 14 96.5
四、综合实战示例
c
#include <stdio.h>
int main(){
// 1. 字符+ASCII值
printf("输出字符: %c %c \n", 'a', 65); // a A
// 2. 整数+长度修饰符
printf("输出十进制数: %d %ld\n", 1977, 650000L); // 1977 650000
// 3. 宽度+空格填充
printf("用空格填充: %10d \n", 1977); // 1977
// 4. 宽度+0填充
printf("用0填充: %010d \n", 1977); // 0000001977
// 5. 不同进制+#标志
printf("输出不同进制: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100); // 100 64 144 0x64 0144
// 6. 浮点数+精度+科学计数法
printf("输出小数: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416); // 3.14 +3e+00 3.141600E+00
// 7. 动态宽度
printf("指定宽度: %*d \n", 5, 10); // 10
// 8. 字符串
printf("输出字符串:%s \n", "C language is great"); // C language is great
// 9. 指针地址
int num = 100;
printf("指针地址:%p \n", &num); // 0x7ffeefbff5c4(实际地址不同)
return 0;
}
输出:
输出字符: a A
输出十进制数: 1977 650000
用空格填充: 1977
用0填充: 0000001977
输出不同进制: 100 64 144 0x64 0144
输出小数: 3.14 +3e+00 3.141600E+00
指定宽度: 10
输出字符串:C language is great
指针地址:0x7ffeefbff5c4
五、总结
printf格式说明符完整语法调整后为%[width][flags][.precision][length]specifier,仅specifier必填;width控制最小输出宽度,不足时按flags填充(默认空格),超过时按实际输出;flags控制对齐/填充/符号,左对齐-优先级高于0填充0,#可给进制加前缀、给浮点数强制加小数点;- 特殊字符输出需转义:
\→\\、%→%%、"→\",单引号可直接输出; .precision对整数补0、对浮点数控制小数位数、对字符串截断,是printf最易出错的部分。
六、scanf
-
scanf格式化输入
核心语法:scanf("格式控制符", &变量地址);
示例:cppchar ch; scanf("%c", &ch); // 读取单个字符 scanf("%d", &num); // 读取整数
(2)C++风格输入输出(cout/cin)
cout输出
核心语法:cout << 表达式1 << 表达式2 << endl;(endl表示换行),支持多类型拼接输出:
cpp
// 示例1:输出a+1= 2(真题考点)
int a = 1;
cout << "a+1= " << a+1 << endl; // 输出:a+1= 2
// 示例2:逗号表达式输出(高频错题)
cout << (3, 2); // 输出:2(逗号表达式返回最后一个值)
cout << (3 + 3 % 3 * 2 - 1); // 输出:4(优先级:% > * > + > -)
真题坑点:
cout << 7 % 3 << ' ' << "7%3" << ' ' << "7%3={7%3}"输出:1 7%3 7%3={7%3}(字符串原样输出,表达式计算后输出)。
cin输入(高频坑点)
核心语法:cin >> 变量;,读取规则:
- 按变量类型读取,遇到非对应类型字符停止;
- 输入表达式(如
5+2)时,int变量只会读取5,+2被留在输入缓冲区; - 未定义变量时使用
cin >> 变量会直接编译报错。
真题示例
cpp
// 坑点1:输入5+2,int变量只读取5
int a;
cin >> a; // 输入5+2
cout << a; // 输出:5
// 坑点2:char变量读取数字时,存储的是ASCII值
char N;
cin >> N; // 输入10
cout << N * 2; // 输出:49*2=98('1'的ASCII值是49)
(3) 输入输出核心坑点对比
| 场景 | 错误写法 | 正确写法 | 输出/结果 |
|---|---|---|---|
printf输出百分号 |
printf("5%2=%d",5%2) |
printf("5%%2=%d",5%2) |
5%2=1 |
cin输入表达式 |
int a; cin>>a;(输入5+2) |
- | a=5(而非7) |
| 逗号表达式输出 | cout << (3,2) |
- | 输出2(而非3,2) |
cout输出布尔值 |
cout << (5>3) |
- | 输出1(true=1,false=0) |
三、数据类型与转换
1. 基本数据类型
| 类型 | 占用空间 | 取值范围 | 核心特点 |
|---|---|---|---|
char |
1字节 | -128~127 或 0~255 |
存储字符/小整数,底层为ASCII编码 |
short |
2字节 | −215∼215−1-2^{15} \sim 2^{15}-1−215∼215−1 | 小范围整数 |
int |
4字节 | −231∼231−1-2^{31} \sim 2^{31}-1−231∼231−1 | 通用整数,默认整数类型 |
long |
4/8字节 | −231∼231−1-2^{31} \sim 2^{31}-1−231∼231−1 | 较大整数(Windows为4字节,Linux为8字节) |
long long |
8字节 | −263∼263−1-2^{63} \sim 2^{63}-1−263∼263−1 | 超大整数 |
float |
4字节 | 约 10−38∼103810^{-38} \sim 10^{38}10−38∼1038 | 单精度浮点数,精度约6~7位 |
double |
8字节 | 约 10−308∼1030810^{-308} \sim 10^{308}10−308∼10308 | 双精度浮点数,精度约15~16位 |
bool |
1字节 | true/false |
布尔值,本质为1/0 |
2. 类型转换
(1)隐式转换(自动转换)
编译器会在不同类型运算时自动转换为同一类型,遵循"低精度→高精度"的安全原则,核心规则如下:
- 字节数优先 :不同字节数的类型,转换为字节数更高的类型(如
int→long long→double) - 浮点默认双精度 :所有浮点运算(包括
float)都会先转换为double再计算 - 小类型提升 :
char、short、bool参与运算时,会自动提升为int - 赋值转换规则:赋值时右边类型会转换为左边类型,若右边类型长度更长则会丢失精度
隐式转换优先级 (从低到高):
char / bool → int → long long → double
float → double
隐式转换示例
cpp
// 示例1:字符与整数运算(char自动转为int)
char ch1 = 'A'; // ASCII值65
int ch2 = 5;
cout << ch1 + ch2; // 65+5=70,输出:70
// 示例2:赋值时的类型转换(long long→char)
char ch1 = 'A';
long long ch2 = 2;
ch1 = ch1 + ch2; // 65+2=67,对应字符'C'
cout << ch1; // 输出:C
// 示例3:精度丢失(double→int)
int a = 5;
double b = 3.14;
a = b; // 浮点数直接截断小数部分,a=3
cout << a; // 输出:3
// 示例4:浮点运算自动转double
float f = 3.14f;
double d = 2.718;
cout << f + d; // f先转为double,再计算
(2)强制转换(显式转换)
通过语法主动指定转换类型,常用于需要明确控制类型的场景,核心语法:
cpp
// 语法1:C语言风格
(目标类型) 变量;
// 语法2:C++推荐风格
static_cast<目标类型>(变量);
强制转换示例
cpp
// 示例1:浮点数转整数(截断小数)
double a = 3.14;
cout << int(a); // 输出:3
cout << (int)a; // 输出:3
cout << static_cast<int>(a); // 输出:3
// 示例2:整数转字符(按ASCII值映射)
int num = 66;
cout << (char)num; // 输出:B
// 示例3:高精度转低精度(主动丢失精度)
long long ll = 123456789;
int i = static_cast<int>(ll); // 若ll超出int范围会溢出
(3)类型转换核心坑点
| 场景 | 错误示例 | 结果/原因 |
|---|---|---|
| 浮点数转整数 | int(-123.123 / 10) |
-12(-123.123/10=-12.3123,截断小数) |
| 字符转数字 | '3' == 3 |
false('3'的ASCII值是51,不等于3) |
| 强制转换语法 | c = char 66; |
编译报错(正确:c=(char)66;) |
| 赋值语句语法 | x=3.16 int; |
编译报错(正确:x=int(3.16);) |
3. 赋值语句(必考)
赋值语句的核心是=(赋值),而非==(比较),合法/非法赋值对比:
| 合法赋值 | 非法赋值 | 非法原因 |
|---|---|---|
a = b = c = 100; |
c + b; |
无赋值操作,仅表达式计算 |
d = (c = 22) - (b++); |
a + c = b + c; |
左值必须是变量,不能是表达式 |
a -= 3;(等价a=a-3) |
- | - |
真题考点:
a -= 3(a=9时,执行后a=6);a *= 3(a=6时,执行后a=18)。
四、核心坑点与真题解析(必背)
1. 变量与命名
- ❌ 错误:
user-Name(含减号)、5Star(数字开头)、cin(标准库标识符)可做变量名 - ✅ 正确:
_可做变量名(如for (int _=0; _<10; _++)合法);break是关键字,不可做变量名
2. 输入输出
- ❌ 错误:
printf("%d*2",5)输出10(实际输出5*2);cin >> X; cout << X;总能原样输出(X为float时,输入2e-1=0.2,X<1输出1) - ✅ 正确:
printf("%d#%d&",2,3)输出2#3&;cout << boolalpha << (5>3)输出true(默认输出1)
3. 类型与转换
- ❌ 错误:
'3'是int类型;7.8/2是float类型;a = a + 3非法(合法,赋值后变量值更新) - ✅ 正确:
int(3.14)=3;7.0是double类型;(3 == 0) + 'A' + 1 + 3.0结果类型为double