NOI Linux 食用小记
sevenki
·
2024-08-22 21:30:23
·
科技·工程
还有两个月赛季就要开始了。
我觉得有必要重新温习一遍 Linux 的操作,并且 Linux 无论是哪个方面用起来真比 Windows 爽。
为什么要用 NOI Linux?因为比 Windows 好用。其次你不用担心变量重名、CE 这种 windows 查不出来的错误。
并且我并不喜欢使用 Dev_cpp(我唯一使用是在去年 CSP_js 因为不知道考场配置究竟怎么样)
本文尽可能的带您探索 NOI Linux 下的快速上手使用方法!如果有谬误,请您不吝指出。
本文可能会包含与本省份(广东省)环境配置有关的技巧。
本文参考了 jyy 的视频,在这里表示感谢,也墙裂推荐各位去看看。
至于 NOI Linux 的安装,网络上已经有不少的博客了。请注意,安装时断网。然后就没别的了。
Section1. Linux 命令行
bash 是 linux 里面的一个很重要的东西,能极大地提升效率。
一般情况下,您可以通过在某个文件夹右键,点击在终端中打开,以打开终端。
终端基本技巧:
运行文件时前面要加 ./。 e.g. ./test。因为 Linux 默认情况下不会从当前目录找寻可执行文件,而 ./ 就代表了 Linux 需要从当前目录找文件。
基本编译命令(不会有人这个都不知道吧)g++ xxx.cpp -o xxx -O2 -Wall -std=c++14。-O2 代表开启 O2 优化,-Wall 代表显示所有警告信息很重要(比如 int 函数没有返回值能编译但是会 RE,开启 Wall 后编译器会提出警告)。
mkdir xxx 在当前目录下创建新文件夹 xxx。
touch xxx 在当前目录下创建新文件 xxx。
ls 展现目录下所有文件与子目录名称。
cat xxx 输出文件 xxx 的内容。喵!
cd xxx 定位到某个目录。具体方法:
如果 xxx 是当前目录的子目录,您直接使用 cd xxx。
如果您想定位到这个目录的上一个目录(母目录),您可以使用 cd ..
可以串起来一起写。
比如当前目录是 /home/sevenki,您想定位到 /home/sevenki/test/foo/,您可以使用 cd test/foo/。
比如当前目录是 /home/sevenki,您想定位到 /home/Ying_keLu,您可以使用 cd ../Ying_keLu。
diff a.out b.out -ZB 可以忽略行末空格及文末换行地比较文件 a.out 和 b.out 非常好用!
如果你想使用脚本:脚本默认是没有运行权限的。假设您的脚本是 foo.sh,您需要使用 chmod +x foo.sh 赋予它可运行权限!
sudo <命令> 您可以理解为“以超级用户执行命令”。某些命令需要的权限比较高,这时就要用 sudo。不过赛场上也用不到应该是。
rm xxx 删除文件 xxx。(您最好还是使用图形界面的删除,免得不小心 rm 到一些重要的玩意导致系统崩溃了)
mv foo1.cpp foo2.cpp 将 foo1.cpp 移动到 foo2.cpp(实际上这样在同一个文件夹里,mv 的作用约等于重命名)
cp foo.cpp xxx.cpp 将 foo.cpp 复制一份,新文件叫 xxx.cpp。别输反了。(否则会喜提文件被覆盖)
无限栈空间 ulimit -s unlimited。注意每个终端之前互相独立。(也就是 A 终端开无限栈,只有 A 终端会起作用,另外的不会起作用)
time ./xxx 运行 xxx 并测量时间。一般会出现三个值,主要看的是 user 那一条。
常用的就这么多,还有一些进阶玩法(以一条命令的结果作为另一条命令的参数、管道、等等等等),这里不过多介绍,因为也基本用不到。
在使用 Linux 指令的时候有一个原则:没有消息就是好消息。
比如,你使用 diff 的时候,linux 如果做完之后看起来什么都没有,那就是成功了,反之,会输出报错信息。
只要您的指令执行正确,就不会存在任何输出信息。(当然这是对于一般情况)
另外,常用的快捷键有:Ctrl+C 杀死进程,Ctrl+D 输入 EOF。复制粘贴要多加个 shift。
使用上下箭头键可以使用之前输入过的命令,别傻傻每次重新敲一遍。
以下是常用命令演示。为大家专门演示了敲错会发生什么。好吧其实是我不小心敲错的
注:其中 echo 为输出指定内容,> 指将内容输出到文件。
Section2. 常用工具
Python
你可能会疑惑为什么要讲 Python?
因为 Python 支持命令行的交互,它可以成为我们的一个很方便的工具。
具体使用:终端输入命令 python3 进入 Python 交互模式。
您输入一个数学式子就可以获得结果。使用 ** 可以表示乘方。
按 Ctrl+D 可以退出。
Firefox / 文档查看器
可以看 pdf。另外,建议在 Windows 实体机上解压试题后再丢入共享文件夹。
Emacs/Vim
不会真的有人用这俩吧)当然命令行里如果突然想要极少量地编辑某个文档那用 Vim 还是挺方便的。
Arbiter
不推荐使用。首先你可能会和我一样根本不知道怎么操作,其次很浪费时间。
VS Code
很遗憾,考场的 VS Code 是被阉割的,没有 cpp 插件!当然如果你只想要一个涂涂颜色的编辑器也可以。你当然用不了 GDB 之类的东西。
Codeblocks
感觉界面类似于 devcpp?)
优点:可以使用 GDB(也是唯一一个能用的)\
缺点:不能创建单文件。
实际使用如果您想要 gdb 功能可以先用别的编辑器然后要用到 gdb 的时候再 copy 到这里)不然的话您也可以使用命令行 gdb。
Geany(比较推荐)
可以创建单个文件,编译运行,并且可以很方便地修改编译命令。界面简洁好看,比较推荐您使用这款。
好看的字体:Noto Mono。
缺点:没有 GDB
Sublime Text(比较推荐)
其实严格上说用 Sublime text 比用 Geany 稍微差一点。但是我之前比较喜欢用 Sublime,所以就来介绍一下。
程序的编译与运行
首先对于编译命令的话,Sublime Text 默认的编译可 DIY 性较低,建议使用 makefile,方法如下:
在文件夹里创建 makefile 文件。
编辑 makefile,以适合您的编译
<生成文件名> : <待编译文件>.cpp
g++ <待编译文件>.cpp -o <生成文件名> -O2 -Wall -std=c++14
然后回到 Sublime Text,在 Build System 里面选择 make 即可。后续要执行 make,可以使用 Ctrl+B。
有关 makefile 的更多,各位可以自行查阅 makefile 语法。
以上实现的是编译命令,如果您想要编译并运行,就可以改一下:
run : <生成文件名>
./<生成文件名>
<生成文件名> : <待编译文件>.cpp
g++ <待编译文件>.cpp -o <生成文件名> -O2 -Wall -std=c++14
makefile 默认执行第一条命令,而第一条命令又对第二条命令有依赖,此时就会先执行第二条命令再执行第一条命令。
当然,如果您的源代码文件没有任何变动,Makefile 就会很聪明地识别出来并且直接跳过编译部分,节省时间。
另外,Sublime 貌似是不支持命令行输入的。因此无论如何,建议使用文件输入输出。
使用 cerr 调试可以与 标准输出分离开,如果 您将 stdout 重定向到文件而 stderr 没有重定向,那么使用 cerr 输出的内容就会显示到编译的小窗里,方便分辨调试信息与输出。
常用的操作
分屏
菜单中 view/layout 可以分屏。也可以使用 Ctrl+shift+2。
模版
tools/developer/new snippet 新建一个
tabTrigger 是触发的文本。
在 CDATA 那个框里写你的模版。
然后保存。随意的命名就行。注意要在 sublime 的 user 文件夹 ~/.config/Sublime Text/Packages/user。(一般默认就是)
注意你得先把一个文件保存成 .cpp 才能使用模版触发,Untitled 未保存,用不了。
Build System->Make 设置编译,Developer->New Snippet 里可以自定义模版。
我的建议
无论您使用哪款 IDE 都推荐使用文件输入输出,stderr(cerr)辅助调试。
想要 gdb 可以复制进 codeblocks。
我今年打算使用 Geany+Sublime text,前者写代码,后者编辑查看输入输出文件,以及其他东西。
Section3. 技巧
调试工具_Sanitizer
sanitizer:是一种非常方便的,内置于编译器的查询运行时错误的工具。99% 的 RE 都能查出来。
sanitizer 有两种,一种 Address,能帮你查数组越界此类的地址错误。还有一种 Undefined,能帮你检查未定义行为。
sanitizer 的使用非常简单,只需要在你平常的编译指令后面加这么一句话:
-fsanitize=address,undefined
就可以了。非常方便有没有。而且这在考场是 NOI Linux 特色,那些用 Windows 环境写代码的同学可享受不到哦!
其实 Windows 系统下这个东西的支持非常的晚,并且 Mingw 中似乎是没有的。得手动装 Clang 的那个啥。当然啦我说的是自己用的时候,考场的 Windows 肯定是不会帮你装的啦。
光说不演示,各位同学无法领略它的强大恐怖。\
观察以下代码:
#include
#define MAXN
using namespace std;
using ll = long long;
int a[114];
int main(){