type
status
date
slug
summary
tags
category
icon
password
回想了自己曾写出的编程陷阱和一些困惑
时效性
2025年适用
📝 主旨内容
NOI的语言标准
自2021年9月1日起,NOI Linux 2.0版(Ubuntu-NOI 2.0版)(基于Ubuntu 20.04.1版)作为NOI系列比赛和CSP-J/S等活动的标准环境使用,
系统情况简表
类别 | 软件/模块 | 版本 | 备注说明 |
系统 | Kernel | 5.4.0-42-generic | 64位 |
语言环境 | GCC | 9.3.0 | C编译器 |
ㅤ | G++ | 9.3.0 | C++编译器 |
ㅤ | FPC | 3.0.4 | Pascal编译器 |
ㅤ | Python | 2.7 | 非竞赛语言 |
ㅤ | ㅤ | 3.8 | 非竞赛语言 |
调试工具 | GDB | 9.1 | ㅤ |
ㅤ | DDD | 3.3.12 | ㅤ |
集成开发环境 | Code::Blocks | 20.03 | C/C++集成开发环境 |
ㅤ | Lazarus | 2.0.6 | Pascal集成开发环境 |
ㅤ | Geany | 1.36 | C/C++/Pascal(轻量级)集成开发环境 |
文本编辑工具 | VS Code | 1.54.3 | ㅤ |
ㅤ | Emacs | 26.3 | ㅤ |
ㅤ | Gedit | 3.36.2 | ㅤ |
ㅤ | Vim | 8.1 | ㅤ |
ㅤ | Joe | 4.6 | ㅤ |
ㅤ | nano | 4.8 | ㅤ |
ㅤ | sublime text | 3.2.2 | ㅤ |
其他软件 | Firefox | 79.0 | 网页浏览器 |
ㅤ | Midnight Commander (mc) | 4.8.24 | 终端 |
ㅤ | XTerm (UXTerm) | 3.5.3 | 终端 |
ㅤ | Arbiter-local | 1.02 | 程序评测工具单机版 |
直接说重点:G++ 9.3.0 是什么?
G++ 9.3.0 是 GNU 编译器集合(GCC)中的 C++ 编译器版本,属于 GCC 9 系列的一个维护版本,发布于 2020 年。这个版本的编译器对 C++ 标准支持较为全面:
- 完全支持 C++14 标准
- 对 C++17 标准的支持度超过 90%(大部分特性已实现)
- 开始提供对 C++20 标准部分特性的实验性支持
但是,NOI 的 C++ 语言标准还是 C++14,而且并不支持 C++17 和 C++20。
编译时如果未指明语言标准,默认采用 C++14 标准
所以,C++ 14。
C++14 有哪些不同?
新的特性支持:
不过用到特性的情况也不多,就不多说了。
编程漏洞
是什么?
编程漏洞(Vulnerability)是指软件或程序在设计、编码、测试等过程中存在的缺陷或错误,可能导致程序运行异常、功能失效,甚至被攻击者利用来获取非授权访问、篡改数据或破坏系统安全。
当然,这里说的没那么严重,最多只会让你的程序运行错误。
三字符组
是什么?
三字符组是早期为解决某些字符在特定键盘 / 编码中无法输入而设计的三字符序列。
三字符组 | 替代为 |
??= | # |
??( | [ |
??/ | \ |
??) | ] |
??' | ^ |
??< | { |
??! | | |
??> | } |
??- | ~ |
结论
C++14默认情况下不会启用也不能用,所以不用慌,就不多说了
双字符组
是什么?
双字符组 | 替代为 |
<: | [ |
:> | ] |
<% | { |
%> | } |
%: | # |
%:%: | ## |
例子
如
%:define arraycheck(a, b) a<:b:> ??!??! b<:a:>
将会在编译时被替换为:
#define arraycheck(a, b) a[b] || b[a]
不过:
同时,双字符组不同于三字符组。双字符组如果出现之字符串字面值、字符常量、程序注释中(如:"Symbol %:Used In Modulo Operation."
),则不会被替换。此外,双字符组替换仅在编译器对源程序的tokenization阶段(即识别出关键字、标识符等,类似于自然语言的“断词”)发生,仅当双字符组作为一个token或者token的组成部分时(如%:%:
被替换为预处理运算符##
)双字符组才会被替换。
结论
危害性不大,但最好不要用双字符组,因为你不知道它到底会不会被替换。
C++的增补关键字
C++除了支持上述的三字符组与双字符组外,还提供了下列内置的关键字:
关键字 | 等价于 |
and | && |
bitor | | |
or | || |
xor | ^ |
compl | ~ |
bitand | & |
and_eq | &= |
or_eq | |= |
xor_eq | ^= |
not | ! |
not_eq | != |
C++14能用,不过这东西除了可读性变好外也没什么有点了。
中文
C++对中文的支持一直是个谜,在 windows 下编译含中文(不包括注释)的文件有时会乱码、有时不会,linux下正常不会。
手持两把锟斤拷,口中疾呼烫烫烫。脚踏千朵屯屯屯,笑看万物锘锘锘。
罪魁祸首
文件编码!!!
Windows下若源代码保存为 GBK 格式,但终端用 UTF-8 显示,中文会乱码。
字节
在C++中,一个 英文字符 占一个 char 不错,但大部分中文会占两个 char,这容易引发编程陷阱。
比如我曾写过一道很简单的题,无非读入由 ”,” 和 ”.” 构成的地图深搜,结果本地测试时一直错误,最后发现自己造的测试数据把 “,” 和 ”.” 打成了 ”,” 和 “。”,然后 ”,” 和 “。” 都会占两个 char ……