Conception
宏就是替换,功能很强大。但是尽量别用。用 inline function 内联函数代替最好。
1 2 3 4 5
| inline void swap(int* a, int* b) { int temp = *a; *a = *b; *b = *a; }
|
牺牲了代码的轻量,换来了内存。
Conception
Struct 结构体 ≈ Class,当类型用,和Java里的差不多。
通过指针访问结构体:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <cmath> using namespace std; struct Point { int x; int y; }; struct Rect { Point p1; Point p2; }; int area(Rect* p) { int width = abs(p->p1.x - p->p2.x); int height = abs(p->p1.y - p->p2.y); return width * height; }
|
File (Important)
Usage
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream> #include <fstream> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); cin >> ...; cout << ...; return 0; }
|
printf()
| 类别 |
格式/示例代码 |
说明 |
输出效果(假设变量值) |
| 基本格式符 |
|
|
|
%d / %i |
printf("%d", 123); |
有符号十进制整数 |
123 |
%u |
printf("%u", 123); |
无符号十进制整数 |
123 |
%o |
printf("%o", 10); |
无符号八进制(无前缀) |
12 |
%x / %X |
printf("%x", 255); |
无符号十六进制(小写/大写) |
ff / FF |
%c |
printf("%c", 'A'); |
单个字符 |
A |
%s |
printf("%s", "hello"); |
字符串 |
hello |
%f |
printf("%f", 3.14); |
浮点数(十进制,默认6位小数) |
3.140000 |
%e / %E |
printf("%e", 123.456); |
科学计数法(小写/大写 e) |
1.234560e+02 / 1.234560E+02 |
%g / %G |
printf("%g", 0.000123); |
自动选择 %f 或 %e(较短的表示) |
0.000123(或 1.23e-04) |
%p |
printf("%p", (void*)&x); |
指针地址(十六进制) |
0x7ffeeb4d5c |
%% |
printf("%%"); |
输出百分号 |
% |
| 宽度与对齐 |
|
|
|
%5d |
printf("%5d", 42); |
最小宽度5,右对齐 |
42 |
%-5d |
printf("%-5d", 42); |
最小宽度5,左对齐 |
42 |
%*d |
printf("%*d", 5, 42); |
宽度由参数指定 |
42 |
%05d |
printf("%05d", 42); |
宽度5,用0填充 |
00042 |
| 精度控制 |
|
|
|
%.2f |
printf("%.2f", 3.14159); |
浮点数小数点后2位 |
3.14 |
%.3s |
printf("%.3s", "abcdef"); |
字符串最多输出3个字符 |
abc |
%.5d |
printf("%.5d", 42); |
整数最少输出5位,不足补0 |
00042 |
%.*f |
printf("%.*f", 2, 3.14159); |
精度由参数指定 |
3.14 |
| 标志组合 |
|
|
|
%+d |
printf("%+d", 42); |
显示正负号 |
+42 |
% d |
printf("% d", 42); |
正数前加空格,负数前加负号 |
42 |
%#o |
printf("%#o", 10); |
八进制显示前缀 0 |
012 |
%#x |
printf("%#x", 255); |
十六进制显示前缀 0x |
0xff |
%#X |
printf("%#X", 255); |
十六进制显示前缀 0X |
0XFF |
%#f |
printf("%#f", 3.0); |
始终显示小数点 |
3.000000 |
| 长度修饰符 |
|
|
|
%hd |
printf("%hd", (short)123); |
short 整数 |
123 |
%ld |
printf("%ld", 123456L); |
long 整数 |
123456 |
%lld |
printf("%lld", 123456LL); |
long long 整数 |
123456 |
%hu |
printf("%hu", (unsigned short)123); |
unsigned short |
123 |
%lu |
printf("%lu", 123456UL); |
unsigned long |
123456 |
%llu |
printf("%llu", 123456ULL); |
unsigned long long |
123456 |
%lf |
printf("%lf", 3.14159); |
double(C99 中 %f 和 %lf 对 printf 等效) |
3.141590 |
%Lf |
printf("%Lf", 3.14159L); |
long double |
3.141590 |
| 常用特殊用法 |
|
|
|
%n |
int len; printf("abc%n", &len); |
将已输出字符数存入 len(不输出内容) |
输出 abc,len 变为 3 |
%m |
printf("%m"); |
GNU 扩展,打印 strerror(errno) |
上一次错误信息(如 Success) |
scanf()
| 类别 |
格式/示例代码 |
说明 |
输入示例 |
对应变量值 |
| 基本格式符 |
|
|
|
|
%d / %i |
scanf("%d", &n); |
有符号十进制整数(%i 可识别八进制/十六进制) |
123 |
123 |
%u |
scanf("%u", &n); |
无符号十进制整数 |
123 |
123 |
%o |
scanf("%o", &n); |
无符号八进制整数 |
12 |
10(八进制12=10) |
%x / %X |
scanf("%x", &n); |
无符号十六进制整数 |
ff |
255 |
%c |
scanf("%c", &ch); |
单个字符(不跳过空白) |
A(前有空格) |
' '(空格字符) |
%s |
scanf("%s", str); |
字符串(空白分隔,自动加 \0,可能溢出) |
hello world |
str = "hello" |
%f |
scanf("%f", &f); |
float 浮点数 |
3.14 |
3.14f |
%lf |
scanf("%lf", &d); |
double 浮点数(必须用 %lf) |
3.14159 |
3.14159 |
%Lf |
scanf("%Lf", &ld); |
long double 浮点数 |
3.14159 |
3.14159L |
%p |
scanf("%p", &ptr); |
指针地址(十六进制) |
0x7ffeeb4d5c |
对应地址值 |
%[ |
scanf("%[a-z]", str); |
扫描字符集合(非空白分隔) |
abc123 |
str = "abc" |
%[^] |
scanf("%[^\n]", str); |
扫描直到遇到指定字符(常用于读一整行) |
hello world |
str = "hello world" |
%% |
scanf("%%"); |
匹配一个百分号 |
% |
消耗掉 % 不存储 |
| 宽度限制 |
|
|
|
|
%5d |
scanf("%5d", &n); |
最多读取5位数字 |
123456 |
12345(只取前5位) |
%5s |
scanf("%5s", str); |
最多读取5个字符(不含 \0) |
hello world |
str = "hello" |
%2d%3d |
scanf("%2d%3d", &a, &b); |
按宽度截取数字 |
123456 |
a=12, b=345 |
| 长度修饰符 |
|
|
|
|
%hd |
scanf("%hd", &s); |
short |
123 |
(short)123 |
%ld |
scanf("%ld", &l); |
long |
123456 |
123456L |
%lld |
scanf("%lld", &ll); |
long long |
123456789012 |
123456789012LL |
%hu |
scanf("%hu", &us); |
unsigned short |
123 |
(unsigned short)123 |
%lu |
scanf("%lu", &ul); |
unsigned long |
123456 |
123456UL |
%llu |
scanf("%llu", &ull); |
unsigned long long |
123456 |
123456ULL |
%hhd |
scanf("%hhd", &c); |
signed char |
-12 |
-12 |
| 抑制赋值 |
|
|
|
|
%*d |
scanf("%*d %d", &n); |
读取但丢弃第一个整数 |
123 456 |
n=456 |
%*s |
scanf("%*s %s", str); |
丢弃第一个字符串,读取第二个 |
hello world |
str = "world" |
%*c |
scanf("%d%*c%d", &a, &b); |
跳过中间一个字符(如分隔符) |
12,34 |
a=12, b=34 |
| 字符集合示例 |
|
|
|
|
%[abc] |
scanf("%[abc]", str); |
仅包含 a/b/c 的字符序列 |
abczz |
str = "abc" |
%[^abc] |
scanf("%[^abc]", str); |
非 a/b/c 的字符序列(直到遇到 a/b/c) |
defabc |
str = "def" |
%[0-9] |
scanf("%[0-9]", str); |
数字序列 |
123abc |
str = "123" |
%[^\n] |
scanf("%[^\n]", str); |
读取一整行(包括空格,不包含换行符) |
hello world |
str = "hello world" |
| 返回值与用法 |
|
|
|
|
ret = scanf(...) |
int ret = scanf("%d %d", &a, &b); |
返回成功匹配并赋值的参数个数 |
输入 12 34 |
ret = 2 |
| 循环读取至文件尾 |
while (scanf("%d", &n) != EOF) { } |
读到文件尾返回 EOF(一般为 -1) |
文件结束 |
循环终止 |
| 循环读取至不匹配 |
while (scanf("%d", &n) == 1) { } |
匹配失败返回少于预期个数 |
输入非数字时退出 |
|
| 常见陷阱 |
|
|
|
|
| 残留换行符问题 |
scanf("%d\n",&n);(不要加 \n) |
格式字符串中的空白(空格、\n)会匹配任意空白 |
输入 123 后需额外输入 |
导致程序卡住 |
%c 跳过空白 |
在 %c 前加空格:scanf(" %c", &ch); |
空格格式指示跳过任何空白字符 |
输入 A |
ch = 'A' |
| 安全读取字符串 |
scanf("%9s", str); |
限制宽度防止溢出(数组大小为10) |
超长输入 |
只读取前9字符+\0 |