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能用,不过这东西除了可读性变好外也没什么有点了。
不会有 OIer 看不懂 && 吧?

中文

C++对中文的支持一直是个谜,在 windows 下编译含中文(不包括注释)的文件有时会乱码、有时不会,linux下正常不会。
手持两把锟斤拷,口中疾呼烫烫烫。脚踏千朵屯屯屯,笑看万物锘锘锘。

罪魁祸首

文件编码!!!
Windows下若源代码保存为 GBK 格式,但终端用 UTF-8 显示,中文会乱码。

字节

在C++中,一个 英文字符 占一个 char 不错,但大部分中文会占两个 char,这容易引发编程陷阱。
比如我曾写过一道很简单的题,无非读入由 ”,” 和 ”.” 构成的地图深搜,结果本地测试时一直错误,最后发现自己造的测试数据把 “,” 和 ”.” 打成了 ”,” 和 “。”,然后 ”,” 和 “。” 都会占两个 char ……

📎 参考文章