1 - 外观

调整小熊猫C++的字体、图标、颜色等外观元素

1.1 - 整体外观

调整小熊猫C++主窗口的整体外观

对于每一个人来说,视力都是需要认真去保护的。无论你使用何种工具编程, 在开始敲代码前都首先应该将其外观调整到眼睛看起来最舒服的状态。

通过“工具”→“选项”对话框中的“外观”页,可以调整小熊猫C++的整体外观。

主题

主题决定着小熊猫C++主窗口中除编辑器外其他部分显示时的使用颜色。

小熊猫C++自带三种主题,用户可以根据自己的习惯选择:

  • 深色:深色背景,浅色文字
  • 浅色:浅色背景,深色文字
  • 高对比度:黑色背景,白色文字

字体

“外观”页中的字体和大小选项控制着小熊猫C++主窗口中除编辑器外其他部分显示时所用的字体。

图标

图标集

“图标集”是当前显示时所用的图标集合。深色主题默认使用“高对比度”图标集;浅色主题默认使用“新外观”图标集。

图标缩放

小熊猫C++使用SVG格式的图标,其显示时的大小通过下列公式计算得到:

图标大小=外观字体实际大小*缩放比例

通过“图标缩放”选项,可以改变图标的缩放比例。

1.2 - 编辑器外观

调整编辑器的字体、配色和图标等视觉元素

对于每一个人来说,视力都是需要认真去保护的。无论你使用何种工具编程, 在开始敲代码前都首先应该将其外观调整到眼睛看起来最舒服的状态。

配色

通过配色设置,可以调整小熊猫C++的编辑器在显示不同内容时所用的颜色和字体样式。

通过菜单"工具"→“选项”,用户可以打开选项对话框。 在选项对话框左侧选中"编辑器"→“配色”,即可打开相应的设置页。

小熊猫C++预置了多套配色方案。用户可以根据自己的喜好,通过配色设置页顶部的下拉框选择合适的配色方案。

配色方案管理

点击配色方案下拉框旁边的"…“按钮,即可弹出配色方案管理菜单。通过其中的菜单项可以对配色方案进行管理。

菜单项 作用
复制 生成一个当前配色方案的副本
导出 将当前配置方案导出保存到指定的文件
导入 从指定的文件导入配色方案
删除自定义修改 丢弃对当前预置配色方案的修改
重命名 修改当前配色方案的名称(预置方案无此选项)
删除 删除当前配色方案(预置方案无此选项)

修改配色方案

如果对预置的配色方案不是完全满意,可以对其进行修改。

类别 项目 说明
编辑器 活动断点 在调试时,程序暂停所在的行
当前行 光标所在的行
断点 被设置了断点的行
当前高亮单词 启用"高亮光标所在的单词"时,光标所在的单词
编辑器缺省 编辑器的缺省前景和背景色
代码折叠线 代码折叠线的颜色
侧边栏 编辑器左侧边栏(行号和断点标记所在的栏)
当前行侧边栏 光标所在行的侧边栏
选中文字 被用户选中的文字内容

字体

通过菜单"工具”→“选项”,用户可以打开选项对话框。 在选项对话框左侧选中"编辑器"→“字体”,即可打开相应的设置页。

用户可以对小熊猫C++的编辑器的下列字体设置进行修改:

  • 英文字体
  • 非英文字体
  • 字体大小
  • 启用合字显示支持

英文字体

小熊猫C++使用该字体来显示编码介于0x00-0xFF之间的Unicode字符。

非英文字体

小熊猫C++使用该字体来显示所有编码大于0xFF的Unicode字符。

快速调整字体大小

在编辑器打开的状态下,按住Ctrl键的同时转动鼠标的滚轮按钮,就可以调整编辑器的字体大小。

显示合字

部分字体,如Fira Code,可以将多个字符 作为一个整体来显示,如->显示成→,<=显示成≤,等等。这种特性被称为合字(ligatures)。

在启用该选项后,就可以启用字体的合字显示特性。该选项仅对英文字体生效

下面的两张图展示了同一段代码使用Fira Code字体,不启用合字和启用合字后的显示效果。

不启用合字:

启用合字:

高亮显示

小熊猫C++提供了一系列高亮(突出)显示功能,来帮助用户在编辑时聚焦到重要的内容上。

语法高亮

小熊猫C++在显示C/C++等支持类型的文件内容时,会用不同的颜色区分显示文件中的关键字、标识符、运算符、字符串和注释等不同语法元素。

用户可以在"选项"对话框的"编辑器"→“配色"页中设置每一种语法元素显示所用的颜色。

语法高亮增强

在"代码补全"功能被启用的情况下,小熊猫C++会进一步用不同的颜色区分显示变量、函数和类等不同的标识符。

符号匹配高亮

当光标移动到括号或引号等符号上时,小熊猫C++会高亮显示和它配对的另一个括号或者引用。

选中词高亮

当光标移动到单词(标识符)上时,小熊猫C++会高亮显示文件中所有该单词出现的位置。

彩虹括号

小熊猫C++会用不同的颜色区分显示嵌套的括号。

用户可以在"选项"对话框的"编辑器”→“配色"页中设置不同嵌套层次括号所用的颜色;也可以通过勾选"彩虹括号"选项来启用/禁用彩虹括号显示功能。

2 - 代码编辑

小熊猫C++的各项编辑功能

2.1 - 基本功能与快捷键

基本编辑功能和快捷键的使用介绍

基本文件操作

新建文件

通过"文件"菜单中的"新建"→“新建源代码文件”,或者直接点击工具栏上的"新建源代码文件"按钮,就可以在小熊猫C++ 的编辑区自动新建一个标题为"无标题+数字"的文件编辑窗口。

缺省状态下,新建文件的快捷键是Ctrl+N

保存文件

通过"文件"菜单中的"保存",或者直接点击工具栏上的"保存"按钮,就可以保存当前正在被编辑的文件。如果要被保存的文件是新建的, 在保存前会弹出对话框,让用户设置要保存的文件名。

缺省状态下,保存文件的快捷键是Ctrl+S

文件另存为

通过"文件"菜单中的"另存为",或者直接点击工具栏上的"另存为"按钮,就可以使用新的名字保存当前正在被编辑的文件。保存前会弹出对话框,让用户设置要使用的新文件名。

关闭文件

通过"文件"菜单中的"关闭",就可以关闭当前正在被编辑的文件窗口。如果小熊猫C++认为被关闭的文件中存在尚未被保存的改动,则它会弹出对话框询问是否需要保存被关闭的文件。

缺省状态下,关闭文件的快捷键是Ctrl+W

打开文件

通过"文件"菜单中的"打开…",或者点击工具栏上的"打开…“按钮,就会显示"打开"对话框。在打开对话框中,选择一个或多个文件(在按住Shift或者Ctrl不放的同时,点击鼠标,可以选择多个文件)后, 点击"打开"按钮,小熊猫就会逐一打开选中的所有文件。如果某个文件之前已经被小熊猫C++打开了,则它会被忽略。

缺省状态下,打开文件的快捷键是Ctrl+O

基本编辑操作

只读模式

只读模式被用来避免用户不小心修改重要的文件。下列文件在打开时会自动进入只读模式:

  • 当前编译器的C/C++包含文件夹(include文件夹)中的文件

文件以只读模式打开时,会在在编辑区的文件标题栏增加[只读]标记。只读模式无法取消或者改变。如果您确实需要用小熊猫C++修改某个被只读的文件,可以将它复制到别的位置,修改后再复制回原处。

光标

在处于编辑状态的文件窗口中,可以看到一条闪烁的线或者方块,它就是光标(caret)。光标所在的位置就是内容将会被输入的位置。

Insert状态与覆写状态

文件在编辑时,有两种状态:

  • Insert状态:这是文件新建或打开时缺省的状态,在此状态下,新输入的字符会添加到光标所在位置,光标后原有的内容会自动向后移动。
  • 覆写状态:在此状态下,新输入的字符会复写光标所在位置原有的内容。

按下Insert键,会自动从当前状态切换到另一种状态:如果当前是Insert状态,会变为覆写状态;如果当前是覆写状态,则会变为Insert状态。

小熊猫C++在状态栏的右下角用”Insert(中文)“或”覆写“显示编辑器当前的编辑状态。

基本键盘操作

按下Backspace键,删除所在位置的前一个字符并移动到被删除字符所在的位置;按下Delete键,就会删除光标所在位置的字符。

按下←、↑、→、↓键可以向左、上、右、下移动光标。

按住Ctrl键的同时按下←、↑、→、↓键,则窗口中的内容向左、上、右、下滚动,但是光标位置保持不变。

按下Home键,光标会移动到该行的第一个非空白字符处;如果光标已经位于第一个非空白字符处,则它会移动到该行的第一个字符处;

按下End键,光标会移动到该行的最后一个非空白字符处;如果光标已经位于最后一个非空白字符处,则它会移动到该行的最后一个字符处。

按下Ctrl键的同时按下Home键,光标会移动到文件的起始(第一行第一列);按下Ctrl键的同时按下End键,光标会移动到文件的末尾(最后一行最后一列)。

按下Page Up键,向前翻一页,同时光标移动到前一页对应的行和列;按下Page Down键,向后翻一页,同时光标移动到下一页对应的行和列。

按住Ctrl键的同时按下Page Up键,光标会移动到窗口中的第一行;按住Ctrl键的同时按下Page Down键,光标会移动到窗口中的最后一行。

在按住Shift键的同时使用上述键盘操作移动光标,则会自动选中操作前光标所在位置和操作后光标所在位置中间区域的内容。

常用编辑快捷键

快捷键 作用
Ctrl+C 将选中的内容复制到剪贴板
Ctrl+X 将选中的内容剪贴到剪贴板
Ctrl+V 将剪贴板中的内容复制到光标处
Ctrl+A 选中当前文件的全部内容
Ctrl+Z 撤销最近一次编辑操作
Ctrl+Y 恢复上一次撤销的操作
Ctrl+Alt+← 光标移动到前一次编辑开始位置
Ctrl+Alt+→ 光标移动到后一次编辑开始位置

特殊编辑快捷键

快捷键 作用
Ctrl+E 删除(Erase)光标所在的行
Ctrl+D 复制(Duplicate)并Insert光标所在的行
Ctrl+Shift+D 删除光标所在处的单词
Ctrl+Shift+B 从光标所在位置向前删除到单词开头(Begin)
Ctrl+Shift+E 从光标所在位置向后删除到单词结尾(End)
Ctrl+Enter 在光标所在行的下一行Insert新行

基本鼠标操作

双击任意单词可以选中该单词

在任意位置按下鼠标左键,光标会移动到鼠标箭头所在的位置。


滚动鼠标滚轮,窗口内容会跟着上下滚动(光标保持不变)。

按住Alt键的同时,滚动鼠标滚轮,窗口内容会跟着左右滚动(光标保持不变)。

按住Ctrl键的同时,滚动鼠标滚轮,编辑窗口中的字体大小会随之改变。

在按住Shift键的同时使用上述滚轮操作移动光标,则会自动选中操作前光标所在位置和操作后光标所在位置中间区域的内容。


在未选中内容的情况下,按下鼠标左键在编辑器中拖动,可以选中内容。

选中部分内容后按下鼠标左键,可以将选中的内容拖动到指定位置;在拖动的同时按下Ctrl键,可以将选中的内容复制到指定位置。

右键菜单

在编辑器标题栏或者编辑区右键单击,会弹出右键菜单。根据用户鼠标右键点击的位置不同,小熊猫C++的编辑窗口会弹出两种不同的右键菜单:

  • 标题区域右键菜单
  • 编辑区域右键菜单

标题区右键菜单

右键单击被编辑文件的标题区域,会弹出标题区右键菜单。各菜单项的作用如下表所示。

菜单项 作用
关闭 关闭当前文件
全部关闭 关闭所有打开的文件
打开所在的文件夹 在Windows文件管理器中打开当前文件所在文件夹
打开命令行窗口 以文件所在的文件夹作为当前工作文件夹,打开Windows控制台
在文件视图中定位 将当前文件所在的文件夹设置为工作文件夹,打开小熊猫C++左侧的文件视图,并在视图的文件列表中选中和突出显示当前文件
移动到其他视图 将当前文件移动到另一个编辑视图中
文件属性… 在文件属性对话框中显示当前文件的属性信息

编辑区右键菜单

右键单击被编辑文件的正文编辑区域,会弹出编辑区右键菜单。部分菜单项的作用如下表所示。

菜单项 作用
编译运行 编译当前程序文件,然后运行编译得到的可执行文件
调试 编译当前程序文件,然后调试编译得到的可执行文件
跳转到声明处 跳转到光标所在处C/C++标识符的声明处。如果其所在的文件尚未打开,会自动打开该文件。
跳转到定义处 跳转到光标所在处C/C++标识符的定义处。如果其所在的文件尚未打开,会自动打开该文件。
查找符号的引用 在当前文件/项目中查找所有对光标所在处C/C++标识符的使用。查找结果会显示在小熊猫C++下方的查找面板中。
打开所在的文件夹 在Windows文件管理器中打开当前文件所在文件夹
打开命令行窗口 以文件所在的文件夹作为当前工作文件夹,打开Windows控制台
在文件视图中定位 将当前文件所在的文件夹设置为工作文件夹,打开小熊猫C++左侧的文件视图,并在视图的文件列表中选中和突出显示当前文件
对代码重新排版 使用自带的asytle程序对当前编辑的文件重新排版。可在"选项"对话框的"代码排版”→“通用"中设置排版使用的格式。
文件属性… 在文件属性对话框中显示当前文件的属性信息

2.2 - 高级编辑功能

介绍自动缩进、注释切换、代码折叠和重新排版等高级编辑功能

自动缩进

保持良好和统计的缩进,是提升代码代码可读性的重要手段之一。为了帮助用户编写缩进良好的代码,小熊猫C++提供并缺省启用了编辑器的自动缩进功能。

在开启该功能的情况下,用户在输入C/C++代码时,每次换行时,小熊猫C++会自动计算并在新一行的行首Insert合适数量的空格或者制表符,以形成合适的缩进。

如果希望自己输入缩进,可以通过"工具"菜单→“选项"打开选项对话框,在"编辑器”→“通用"页中找到并取消勾选"自动计算缩进"选项。

注释切换

在编程和调试时,经常需要暂时禁用程序中的一段代码。要实现这一点,最简单的方法就是使用小熊猫C++的注释切换功能。

选中你希望暂时禁用的代码,然后通过菜单"编辑”→“切换注释”(或者直接通过快捷键ctrl+/),即可将这段代码变为注释;当需要启用这段代码时,再次选中它然后"切换注释",就可以将其重新变为普通代码。

代码折叠

在调试和维护逻辑较为复杂的代码时,可以通过代码折叠功能来把整段复合语句显示成一行。

直接点击编辑器左侧边栏的代码折叠按钮即可:

匹配当前括号

当光标位于括号前时,匹配当前括号功能可以让光标直接移动到此左(右)括号对应的右(左)括号处。

通过菜单"代码"→“匹配当前括号"或者快捷键Ctrl+[即可使用这一功能。

重新排版

如果代码本身的缩进格式较为散乱,可以通过"代码"菜单→“对代码重新排版”,或者点击工具栏上的"对代码重新排版"按钮来对代码文件重新进行排版。

2.3 - 代码补全与符号补全

使用代码补全和符号补全功能,提升开发效率

代码补全

如下面的动画所示,小熊猫C++可以根据用户当前已经输入的内容,推测用户可能要输入的标识符,并以弹出下拉列表(以下称为代码补全列表)的形式展现给用户。

当代码补全列表弹出时,用户可以继续输入,也可以通过键盘上的下列按键进行操作:

按键 作用
选中列表中的上一个标识符
选中列表中的上一个标识符
Page Up 列表翻到上一页
Page Down 列表翻到下一页
Esc 关闭列表
Tab 使用列表中当前选中的标识符替换用户当前的输入,并关闭列表
Enter 和Tab键作用相同

代码补全可以显著的减少用户输入时的拼写错误,也可以帮助用户在使用不熟悉的库时,快速找到自己想要的API函数或者其他符号,因此可以显著的提升代码输入的效率。

有部分教师认为代码补全会影响学生对重要函数和关键字的记忆,对此我个人的看法是:

  1. 编程教育的核心应该是让学生掌握编程的基本思维范式和问题解决模式,语法并不是最核心的内容。(因为大部分学生将来不一定会使用课程上教授的语言来进行实际的编程工作)

  2. 以笔者个人这些年最终结课考试的实际结果来看,让学生使用带代码补全功能的IDE,并不会影响学生最终书面考试编程的分数;笔者未发现有学生在考试中程序整体思路和步骤正确,但是关键字写错的情况。

因此,笔者认为,并不应该以锻炼学生的基本功为理由,而不让学生使用代码补全功能。

如果需要关闭代码补全功能,可以通过"工具"菜单→“选项"打开"选项"对话框,在"编辑器”→“代码补全"页中取消勾选"启用代码补全”:

符号补全

符号补全是指用户在输入括号、引号等成对出现的符号时,小熊猫C++自动进行的编辑处理。小熊猫C++提供的符号补全功能可以分为三类:

  • 成对符号补全
  • 已成对符号跳过
  • 符号成对删除

成对符号补全

用户在输入左括号(包括圆括号、方括号、花括号)和单双引号时,小熊猫C++会自动Insert和其匹配的右括号或者引号;

此功能可以显著的减少在输入复杂公式时由于忘记输入括号而产生的括号不匹配错误。

符号成对删除

用户在删除左括号(包括圆括号、方括号、花括号)和单双引号时,如果和它匹配的右括号或者引号与它之间没有内容,则小熊猫C++会自动将两个符号一起删除:

已成对符号跳过

用户在输入右括号(包括圆括号、方括号、花括号)和单双引号时,如果当前光标位置上存在要输入的符号,且该符号之前存在和其匹配的左括号或者单双引号,那么此次输入会自动以覆写模式进行。

此功能的主要作用是减少成对符号补全自动引入的符号对于输入流畅性的干扰。

如果需要关闭符号补全功能,可以通过"工具"菜单→“选项"打开"选项"对话框,在"编辑器”→“代码补全"页中取消勾选"启用代码补全”:

2.4 - 代码导航

介绍结构浏览器和书签等代码导航功能

结构浏览器

点击小熊猫C++左侧面板的"结构"页,即可打开结构浏览器。该浏览器以树形列表的形式显示了当前文件中的全局变量、函数、宏和类定义等全局定义的标识符。

在结构浏览器中双击某个标识符,可以将光标跳转到该标识符声明所在的行。

右键单击某个标识符,然后在右键菜单中选择"跳转到定义处",就可以将光标跳转到该标识符定义所在的行。

代码跳转

在编辑器中,按住Ctrl键的同时用鼠标点击某个标识符,就会将光标跳转到该标识符声明所在的行。如果当前行就是该标识符的声明,则光标会跳转到该标识符定义所在的行(如果定义和声明不在一行的话)。

也可以通过在编辑器中右键点击某个标识符,然后在右键菜单中选择"跳转到定义处"/“跳转到声明处"进行跳转。

查找符号引用

在在编辑器中右键点击某个标识符,然后在右键菜单中选择"查找对符号的引用”,小熊猫C++就会在当前文件/项目中查找所用使用了该标识符的地方,并在"查找"面板中显示查找结果。

该功能和"在文件中查找"的区别在于,“在文件中查找"在查找时只比较两个单词是否相同;而"查找对符号的引用"会考虑作用域。在不同作用域里定义的重名标识符,会被"查找对符号的应用"当作不同标识符进行处理。

书签

小熊猫C++中的"书签"就是指定文件的某一行。在书签面板中可以浏览和管理小熊猫C++当前的所有书签。

通过"代码"菜单或编辑器右键菜单,可以设置和管理文件中的书签。

2.5 - 编码

使用不同的编码打开和编辑文件

不同的用户可能需要用不同的文件编码编写程序。虽然未来编程的大趋势是统一使用UTF-8编码编写程序,但由于windows下gcc对UTF-8编码支持还不够完善,会导致诸如中文文件夹中的C/C++程序里面的__FILE__宏出错等奇怪的bug,所以目前还是建议普通用户使用操作系统的缺省编码来编写程序。

默认文件编码

通过"工具"菜单→“选项"打开"选项对话框”,在"编辑器"→“杂项"页中可以选择小熊猫C++在新建和保存文件时使用的默认文件编码。当"自动识别文件编码"未启用时,该编码也被用作打开文件时的默认编码。

自动识别编码

当该选项被启用时,小熊猫C++会自动判断被打开的文件内容是以UTF-8还是系统默认字符集编码。在简体中文环境下,如果用UTF-8或者系统默认字符集打开失败,还会尝试以gbk和gb18030打开文件。

由于作者本人对于其他语言所使用的字符集了解有限,所以暂时未实现其他语言环境下的非UTF-8及系统默认字符集自动识别支持。欢迎有兴趣的用户提供相关的信息或者实现。

强制使用指定的编码打开文件

如果小熊猫C++打开文件时所使用的编码不正确,用户可以在"编辑"菜单→“文件编码"子菜单中强制指定使用特定的编码来重新打开文件。该操作不会改变磁盘上的文件内容。

转换文件编码

用户可以在"编辑"菜单→“文件编码"子菜单中将文件转换为指定的编码。

注意:该操作会改写磁盘上的文件的内容,所以用户在操作前最好先做好文件的备份。

建议文件编码和实际文件编码

小熊猫C++打开的每个文件编辑器都有两个参数,(建议)编码和实际编码。文件打开保存时会根据文件内容和(建议)编码来计算实际编码:

  • 当文件中不包含非ascii字符时,文件的实际编码是ASCII;
  • 否则,文件的实际编码与编码一致。

小熊猫C++在编译程序时,会根据文件的实际编码来生成相应的gcc编译参数。

2.6 - 代码模板

快速生成文件内容

小熊猫C++提供了两种不同的代码模板来帮助用户快速生成代码:

  • 新文件模板 在新建文件时,小熊猫C++会用模板中的内容创建新文件。
  • 代码段模板 在输入内容时,可以快速插入指定代码模板的内容。也可通过“代码”→“插入代码段”插入指定的代码段。

使用代码段模板输入

编辑插入的代码

使用代码模板插入代码段后,即进入代码段编辑模式,光标会停在第一个可编辑区域中。

在代码段编辑模式下:

  • 按TAB键跳转到下一个可编辑区域。
  • 按ENTER键退出代码段编辑模式。

编辑模板

在“选项”对话框→编辑器→代码模板 可以编辑代码模板。

代码段模板属性说明:

  • 代码补全前缀 代码模板在代码补全提示中显示的名称。为空的代码模板则不会显示在补全提示中。
  • 菜单节 代码模板在“代码”→“插入代码段”子菜单中的位置。为-1的代码模板不会出现菜单中。

特殊代码

在代码模板中,可以使用下列特殊代码:

代码 作用
%REPL_BEGIN% 可编辑区域开始
%REPL_END% 可编辑区域结束
%INSERT% 空可编辑区域
<SOURCENAME> 源文件名
<DATE> 当前日期
<DATETIME> 当前时间日期

2.7 - 自动保存

使用自动保存功能备份代码

通过"工具"菜单→“选项"打开"选项对话框”,在"编辑器"→“自动保存"页中勾选“启动自动保存"项,即可启用自动保存功能。

该功能会在指定的时间间隔经过后,自动保存指定的文件内容。

用户不管用什么IDE或者编辑软件来编写程序或书写文档,都应该养成编辑后及时存盘(保存)的习惯。因此,作者本人不建议一般用户依赖该功能来保存自己的工作。

3 - 查找与替换

使用查找与替换功能提升代码编辑和开发效率

小熊猫C++提供了两种查找和替换功能:

  • 查找/替换 在当前文件的指定区域中查找/替换指定的内容。查找结果直接以选中的形式显示在编辑窗口中。
  • 在文件中查找/替换 在当前文件/项目中查找/替换指定的内容。查找结果以树形列表形式显示在查找面板中。

在大多数情况下,被查找/替换的内容会在文件中多处出现,使用"在文件中查找/替换"要比"查找/替换"更加方便。下图展示了"在文件中查找"的结果:

在文件中查找

通过"查找"菜单→“在文件中查找…",即可直接打开"查找"对话框的"在文件中查找"页。

查找面板

在查找面板中,可以看到"在文件中查找"的结果。如果进行了多次查找,可以在查找面板左上方"历史:“下拉框选择查看每一次查找的结果:

查找的结果在面板中以树形列表显示,包括存在被查找关键字的文件路径,关键字在其中出现的次数,以及文件中每一个关键字出现的位置。当被查找的关键字在不止一个文件中出现时,用户可以很方便的查看查找结果。

双击树形列表中的某一行,就可以在编辑器中跳转到该行对应的位置。

在文件中替换

再"在文件中查找"对话框中,点击到"替换"按钮,即可使用批量"在文件中替换"功能。

注意:此操作无法撤销,在替换前请做好文件的备份!

在文件中替换操作由三个步骤组成:

  1. 在文件中查找
  2. 在查找面板中勾选要替换的行
  3. 完成替换

查找与替换

最后简单说一下查找与替换。在完成了一次查找之后,通过快捷键F3,或者"查找"菜单→“查找下一个”,可以查找关键词在文件中的下一个出现的位置;通过快捷键Shift+F3,或者"查找"菜单→“查找前一个”,可以查找关键词在文件中的前一次出现的位置。

4 - 编译与执行

(以单文件方式)编译和执行程序代码

在小熊猫C++中,可以直接将一个包含main函数的程序文件编译链接成可执行文件,然后执行或者调试。

4.1 - 编译器配置

通过使用合适的"编译器配置",来编译符合需要的可执行文件

小熊猫C++通过调用外部的gcc编译器来编译和链接程序。通过不同的参数设置,gcc可以将同样的源程序编译成不同的可执行文件。因此,为了方便用户的使用,小熊猫C++与其他大多数的IDE一样,以"编译器配置"的形式来管理编译器的设置。

每个"编译器配置"都是一套gcc相关的编译参数设置,包括:

  • gcc和其他相关程序的路径
  • gcc在编译时用的相关文件夹位置
  • gcc编译参数
  • gcc链接参数等等

通过工具栏上的编译器设置下拉框,用户可以切换当前使用的编译器配置(见下图)。

小熊猫C++在第一次运行时,会自动寻找自带的和系统PATH中的gcc程序,并生成相应的编译器配置。

在之后每次运行时,会自动检查当前编译器配置中的gcc程序是否存在;如果不存在,会自动提示用户重新寻找gcc编译器。

Release和Debug

小熊猫C++为每个自动找到的gcc创建两个编译器配置:Release配置和Debug配置。

在缺省情况下,小熊猫C++会将Debug配置设置为当前编译器配置。

配置类型 作用
Release 生成优化、静态链接的可执行文件。其执行速度最快(-O2优化),可以脱离gcc环境独立运行
Debug 生成调试用的可执行文件;其中包含了调试信息和符号,运行速度相对较慢(-Og优化);脱离gcc环境运行时会提示缺少dll文件

管理编译器配置

用户可以通过"选项"对话框中的"编译器"→“编译器配置集"来创建、编辑和管理编译器配置。

自动搜索编译器

当用户需要恢复缺省的编译器设置,或者在系统PATH中加入了新的gcc兼容编译器时,可以通过"编译器配置集"页上部工具栏的"自动搜索编译器"按钮(见下图)来重新搜索和生成编译器配置。

注意:自动搜索编译器会自动删除原有的全部编译器配置!

在指定文件夹中搜索编译器

通过"编译器配置集"页上部工具栏的"在指定文件夹中搜索编译器"按钮(见下图),可以为指定的文件夹中的gcc兼容编译器建立相应的编译器配置。

添加空白编译器设置

通过"编译器配置集"页上部工具栏的"添加空白编译器设置"按钮,可以创建空白的编译器设置。用户需要自行填写设置中的相关参数。

编译器配置参数

编码转换

对于使用printf或者std::cout输出的程序,如果要输出的字符串常量(字面量)中包含非ascii字符,且程序文件本身的编码和操作系统控制台的编码(中文windows缺省为gbk)不一致,就会导致程序运行时输出的内容显示为乱码。

另外,gcc内部使用UTF-8来分析和处理程序。如果程序文件编码不是UTF-8,并且在标识符里使用了非ascii字符,那么编译就会失败。

因此,当程序中包含非ascii字符时,就需要在gcc编译程序时,对字符串进行转码,包括两个转码操作:

  1. 编译前,将程序文件内容转换为gcc内部处理使用的UTF-8编码;
  2. 链接时,将gcc生成的机器代码中的字符串内容转换为主控台所用的编码,最终得到可执行文件。

在缺省情况下,小熊猫C++生成的编译器配置中会自动勾选”将可执行文件中的字符串转码为"选项,在编译时自动添加相关的转码参数。

静态链接

C/C++的库文件(实现的机器代码)通常有两种提供方式:

  • 静态库。程序直接将库里面的机器代码整合到可执行文件中。
  • 动态库。机器代码位于.dll(或者.so)文件中,库里面只包含调用.dll的相关信息。可执行文件在执行时需要载入.dll文件调用相应的代码。

链接时使用动态库的好处在于,多个程序可以共用同一个动态库.dll文件,减少程序本身可执行文件的大小、启动速度和内存占用。但这也要求程序在启动时能够找到相应的.dll文件。

windows系统在安装时自带了众多的.dll文件,使用这些.dll开发的程序不需要特殊的配置就可以直接在windows下正常运行。而使用gcc开发环境(mingw-w64)编译和动态链接的程序,就必须要进行相关的设置,否则在运行时就会因为找不到.dll文件而出错。

如果在编译器配置中勾选了"静态链接所有库”,小熊猫C++就会在编译时尝试使用静态链接的方式链接所有用到的库。这样得到的程序可以脱离小熊猫C++环境直接运行。

缺省情况下,小熊猫C++生成的Release配置中自动勾选了"静态链接所有库";其他配置都没有勾选该选项。

4.2 - 编译和运行

使用编译和运行的相关功能

通过"运行"菜单,或者工具栏上的相关按钮,即可编译和运行当前打开的程序文件。

4.3 - 自动链接

根据程序中包含的头文件,自动生成对应的库文件链接参数

大多数C/C++库使用声明和实现分离的形式发行,把相关函数等的声明放在.h头文件中,而把实现编译成.a或者.lib库文件。我们的程序在使用这些库时,除了需要使用#include语句包含相关的头文件外,还需要通过编译参数告诉gcc需要链接的库文件。

Visual C++通过引入#pragma语法,可以在头文件中直接指明对应的库文件;而gcc编译器尚不支持该语法,这就导致用户在使用gcc编译程序时,必须通过自定义链接参数来指定要链接的库,否则就会编译链接失败。如果用户需要在不同的程序中链接不同的库,反复修改自定义链接参数就成了一件很繁琐的事情。

针对这个问题,小熊猫C++提供了一个解决方法:自动链接。在编译单文件程序时,小熊猫C++会根据程序中直接或者间接包含的头文件信息,在自动链接表中查找对应的链接参数。其在"选项"对话框中的配置页如下图所示:

注意:自动链接仅对单文件程序编译生效

小熊猫C++缺省提供了ege、海龟作图、raylib、freeglut等的自动连接配置。因此,用户在小熊猫C++中使用这些库时,不需要手工设置自定义链接参数,非常方便。

4.4 - 输入重定向

利用输入重定向功能在运行时自动输入数据,减少测试运行时的工作量

我们为学习C/C++语言和算法编写的练习程序,经常需要在运行时输入一些数据。例如下题(来自洛谷):

在运行时需要输入:

4 3
3 7 12 19

在解决这个题目的过程中,必然需要反复输入这些数据。即使是通过复制粘贴来输入,这也是一件繁琐的事情。小熊猫的输入重定向功能可以帮助我们自动在运行程序时输入数据。

首先,我们用记事本软件,把要输入的数据保存在一个文本文件中(这里假设它的路径是f:/data.txt)。接下来我们会让程序在运行时自动从这个文件中读入内容。

启用输入重定向

通过"运行"菜单→“运行参数…",或者工具栏上的对应按钮,可以直接打开"选项"对话框的"程序运行”→“通用"选项页(以下简称"程序运行选项"页)。

在"程序运行选项"页中勾选"将程序的标准输入重定向到下面的文件”,并填写文件所在的路径,即可启用输入重定向功能。

启用后,程序中的scanf或者cin语句就会从f:/data.txt中读入数据。

5 - 调试

使用调试功能定位和解决程序中的缺陷

5.1 - 基础知识和准备

介绍调试的基础知识和使用调试功能前需要的准备工作

在为刚开始学习编程的同学们具体介绍小熊猫C++的调试功能之前,让我们先来看一下调试的基本方法(了解调试的同学可以直接转下一节):

1 调试的基本方法

调试就是找出并修正程序中的缺陷(bug)的过程。其实,即使没有学习过编程,我们也早就做过很多次的“调试”了,只不过调试的对象不是程序,而是数学、物理试题的解题步骤罢了。是的,我们调试程序的过程,和我们检查一道数学或者物理题的解题过程是否正确其实是类似的。

我们在解数学或者物理计算题时,从已知条件出发,每一步会进行一项处理或者计算从而得到一个(中间)结果,后面的步骤在前面的步骤的计算结果上继续进行计算,最后得到结果。所以,检查的过程主要就是看:

每一步计算的逻辑是否正确(根据已经计算出来的结果,是不是该用这个定理来进行下一步计算)? 计算的结果有没有错? 想一想你就会发现,我们在用C或者C++这类命令式编程语言编写的程序其实也是如此。除了输入(cin或者scanf)和输出(printf或者cout)外,程序中的每一条语句要么就是在做计算并保存计算结果(赋值),要么就是在根据某个变量的值来决定下一步该干啥(if、while、for等)。所以,我们在调试程序时主要关注的就是:

计算的逻辑是否正确(if、while、for等语句的条件表达式写的对吗)? 计算的对吗,是否使用了正确中间结果(计算的表达式写错了没有,变量名是否写错了)? 所以,我们调试时最基本的操作就是:

对于if/while/for语句:检查程序在执行这条语句之前,条件表达式的计算结果 对于其他语句:检查程序在执行这条语句前后,相关变量或者内存中的值(或者值的变化) 显然,我们可以直接在相关的语句前后使用printf或者cout等语句输出想要检查的内容,从而进行调试。

但调试工具给了我们更多(很多时候也更加方便)的选择。

2 小熊猫的调试功能

小熊猫C++的调试功能主要可以分为两类:

  • 控制程序的执行:包括断点、单步执行系列工具等,通过“运行”菜单或者调试工具栏来访问
  • 查看程序和内存的状态:包括局部变量面板、内存面板、监视面板、调用栈面板、CPU信息窗口(对话框)等
运行菜单中的调试命令

运行菜单中的调试命令

调试工具栏

调试工具栏

监视面板

监视面板

调试面板

调试面板

3 调试前的准备

在后面的系列文章中,我们将以下面这个程序为例,介绍小熊猫的调试功能。(此程序是正确的,我们只是用它来演示调试功能的使用)

/**
 * 找出整数n的所有质因数
 */
#include <stdio.h>
#include <stdbool.h>

//判断n是否为质数
bool isPrime(int n) {
	if (n<2)
		return false;
	for (int i=2;i<n;i++) {
		if (n%i==0)
			return false;
	}
	return true;
}

int main() {
	int n;
	scanf("%d",&n);
	for (int i=2;i<n;i++) {
		if (n%i==0) { //如果i能整除n
			if (isPrime(i)) { //并且i是质数
				printf("%d\n",i);
			}
		}
	}
	return 0;
} 

绝大多数的调试工具都需要程序在编译时嵌入必要的调试信息,才能够正常工作。小熊猫C++内部所使用的gdb工具也是如此。因此,如果想让程序能被正常调试,必须要使用Debug类型的编译器配置集来编译程序,如下图所示:

选择Debug编译

选择Debug编译

注意:改变编译器配置集后,必须使用“运行”菜单中的“全部重编译”功能强制使用新编译器配置重新编译一遍程序,小熊猫C++目前不会在程序内容本身没有改动过的情况下自动重新编译程序。

5.2 - 控制程序执行

在调试时控制程序的执行

要查看程序执行到特定位置时的状态,最好当然是能够让它执行到那个位置的时候暂停下来。我们想看什么,就可以看什么。为此,小熊猫C++提供了一系列控制程序执行的功能。

1 启动调试

通过“运行”菜单或者调试工具栏,点击“调试”,就可以让当前程序以调试模式启动运行。当前程序中如果没有断点,则程序启动后会自动停在main()函数的第一条语句处(变量声明除外),如下图所示(注意当前暂停位置所在行左侧的小箭头):

调试按钮

调试按钮

启动调试后,程序暂停在main函数入口处

启动调试后,程序暂停在main函数入口处

2 退出调试

在程序调试过程中,通过“运行”菜单或者调试工具栏,点击“停止执行”按钮,即可停止调试。

停止按钮

停止按钮

3 断点

断点(Breakpoint)就是程序中预设的暂停点。程序在调试运行到断点位置时,就会暂停。

在小熊猫C++中,单击编辑器左侧边栏区域即可设置/取消断点:

点击编辑器左侧栏设置、取消断点

点击编辑器左侧栏设置、取消断点

设置断点后点击”调试“按钮启动调试,程序就会在断点所在的第22行暂停。注意:程序在运行第20行的scanf语句时,会等待用户输入一个整数,这是scanf语句本身的行为特性,和调试没有任何关系

程序暂停在第23行断点处

程序暂停在第23行断点处

4 单步执行

顾名思义,单步执行就是让程序执行一步后暂停。问题在于,到底多少程序算”一步“?在小熊猫C++的运行菜单中,有这么几种单步执行:

  • 单步跳过(Step Over):一行程序算一步。执行完当前行后暂停。
  • 单步进入(Step Into):如果当前行不包含函数调用,则一行程序算一步;如果这行程序中包含对函数的调用,会在进入函数后暂停;如果找不到该函数的符号信息,则在执行完该函数后暂停。
  • 单步跳出(Step Out):退出当前函数后暂停。
单步跳过、单步进入和单步跳出按钮

单步跳过、单步进入和单步跳出按钮

4.1 单步跳过

在上一节中,程序在我们输入300后,暂停在了第23行断点处。注意这一行中包含了对函数isPrime()的调用。并且注意此时变量i的值为2(2是质数)

如果此时(程序暂停在23行时)点击”单步跳过“,程序会在执行完23行后,停在第24行

单步跳过

单步跳过

4.2 单步进入

让我们退出再重新开始调试,输入300后程序再次暂停在了23行断点处。如果此时(程序暂停在23行时)点击”单步进入“,程序会停在第9行isPrime()函数的入口处:

单步进入

单步进入

4.3 单步跳出

我们现在暂停在了函数isPrime()中。现在点击”单步跳出“按钮,程序会返回第23行(isPrime(i)函数执行完了,但是if判断还没执行)

单步跳出

单步跳出

在小熊猫C++的CPU窗口中,还有两个单步执行按钮:”单步执行一条机器指令“和”单步进入一条机器“指令。有兴趣的同学可以猜一猜,然后自己试试它们的作用是什么?

5 继续执行

程序暂停后,通过”运行“菜单或者调试工具栏选择”继续执行”,程序就会继续以调试方式运行,直到遇到下一个断点,或者程序运行结束为止。

接上一节的例子,点击“继续执行”,程序又会停在第23行断点处。但注意此时i的值已经变成了3

继续运行后再次暂停

继续运行后再次暂停

6 GDB Server调试模式

为了支持在Linux下使用终端调试程序,从0.12.5版本开始,小熊猫C++中新增了gdb server调试模式(在Linux下自动缺省启用,目前在Windows下缺省关闭)。可以通过工具菜单的“选项”菜单项打开选项对话框,然后在选项对话框的“调试器”“通用"页中设置是否启用gdb server调试。

使用gdb server调试选项

使用gdb server调试选项

7 中断(仅gdb server模式下支持)

在gdb server模式下,运行菜单和调试工具栏中会多出一个“中断”按钮。此按钮可以暂停运行中的程序。但是由于此时程序可能正在执行某个运行库中的指令(比如,输出内容到控制台窗口),所以小熊猫C++无法在编辑器窗口中获取和显示程序当前暂停的位置。

在Linux操作系统下可以通过调用栈视图了解程序当前的状态。但是Windows下小熊猫C++后台使用的gdb程序尚无法在中断后获取完整的调用栈信息。

Linux系统下程序中断(暂停)时的状态显示

Linux系统下程序中断(暂停)时的状态显示

5.3 - 查看程序状态

在程序暂停时查看程序的状态

通过小熊猫C++的控制程序执行功能,可以帮我们准确将程序暂停到指定的位置。然后,我们就需要去查看程序的状态了。小熊猫C++提供了一系列工具来帮助我们查看程序的状态

1 局部变量视图

在调试时,调试面板的局部变量视图会自动显示当前函数作用域中的所有局部变量(包括函数参数)。

局部变量视图

局部变量视图

2 监视和监视面板

局部变量视图可以自动显示局部变量的状态,这很好。但是如果某个函数里面的局部变量太多,找我想看的变量很麻烦;或者我想看某个全局变量的状态;或者我想看某个表达式的值,怎么办呢?这时就需要使用监视功能了。

2.1 添加监视

比如,我们想在调试过程中监视&n的值(n的地址)。可以在调试工具栏中点击“添加监视”按钮

添加监视按钮

添加监视按钮

然后在对话框中输入我们要监视的表达式:

添加监视按钮

添加监视按钮

在左侧的监视面板中就可以看到我们要监视的表达式了。因为此时我们没有开始调试程序,所以&n的值中显示“执行以求值”。

gdb(小熊猫C++使用的调试器)支持监视任何C、C++表达式。但请保证在表达式中不会出现无穷递归、无限循环等错误,否则gdb调试器会卡死无法正常使用

2.2 查看监视

在程序调试的过程中,小熊猫C++会在程序暂停时自动更新监视的值。请注意示例程序在main函数中暂停,和在isPrime函数中暂停时,&n的变化(main和isPrime中的n虽然同名,但是是两个作用域不同的变量,在内存中的地址不同)

程序在main函数中暂停

程序在main函数中暂停

程序在isPrime函数中暂停

程序在isPrime函数中暂停

3 调用栈视图

我们按照自顶向下或者模块化的思路设计程序时,会以函数为单位来组织和实现的程序的功能。在调试程序时,我们经常需要知道,函数现在正被谁调用?调用者的状态是怎样的?

调试面板中的调用栈视图为我们提供了程序调用栈(Call Stack)的信息。从下图中我们可以看出,当前程序执行到isPrime函数中,它是在main函数的第30行被调用的。

调用栈信息

调用栈信息

在调用栈视图中双击某一行,小熊猫C++就会自动跳转到对应的程序位置。

点击调用栈视图第二行,跳转到isPrime函数被调用的位置

点击调用栈视图第二行,跳转到isPrime函数被调用的位置

4 内存视图

调试面板的内存视图允许我们在调试时,查看程序进程指定内存位置的值。在地址表达式栏中输入任意返回内存地址的表达式,就可以查看指定位置的内容。例如,下面是我们输入“&n"后的显示结果

5 求值工具

除了监视和局部变量之外,我们还可以使用求值工具来快速计算某个表达式。

注意,求值工具可以执行任意C/C++表达式,包括赋值表达式!其效果和在程序中执行该表达式的作用是相同的。例如,我们在求值输入框中输入n=500,就可以将变量n的值改为500。

6 CPU窗口

CPU窗口让我们可以查看程序对应的机器和汇编指令,以及CPU中各寄存器的状态。通过”运行“菜单的”打开CPU窗口“菜单项即可打开CPU窗口。对于学生和初中级用户而言,这个窗口中的信息可以帮助他们更深入的理解C语言程序的实际工作机理。

5.4 - 修改变量或内存

在调试时修改变量或内存中的内容

从小熊猫C++ 0.13.2版本开始,我们可以在调试程序时直接修改变量的值或者内存中的数据。初学者可以使用这个功能,更好的理解C语言的变量、数据类型和字符串机制等知识。

1 直接执行表达式

在调试面板的求值框中,我们可以输入任意表达式,包括赋值表达式。通过这一点我们可以对任意变量或者内存地址进行赋值,从而改变它们的值。

在下例中,我们直接在求值框中输入n=10后回车

输入n=10

输入n=10

n的值被修改了

n的值被修改了

2 改变监视变量

在监视面板中,双击要修改的值,就可以对其进行修改。

双击要修改的值

双击要修改的值

进入修改状态

进入修改状态

修改完成

修改完成

可以看到,修改完成后,局部变量视图也同步进行了更新。

3 改变内存的值

和监视面板类似,我们在调试面板的内存视图中,双击要修改的内容,即可直接对其进行修改:

双击要修改的值

双击要修改的值

进入修改状态

进入修改状态

完成修改,注意监视面板中的信息更新

完成修改,注意监视面板中的信息更新

6 - 项目管理

使用项目管理、编辑和构建包含多个代码文件的程序

我们在编写复杂的C/C++程序时,会将代码拆分到多个源文件中。这么做有很多好处:

  1. 便于组织和管理代码;
  2. 便于在不同的程序(项目)之间共用代码和利用已有的代码
  3. 减少程序修改后编译的工作量,提高编译速度

小熊猫C++提供了项目功能,可以对多文件程序进行管理、编译运行和调试。

6.1 - 多文件程序构建基础

介绍C/C++语言构建可执行文件的基本原理和术语

编译(构建)过程

计算机并不能直接执行C或者C++语言指令,因此C/C++程序必须被翻译(translate)成计算机(CPU)认识的指令(机器语言指令),并按照特定的格式保存在可执行文件(Executable)中之后,才能被计算机载入执行。在C++11(ISO/IEC 14882:2011)标准中,将从C/C++源程序文件到可执行文件的过程称为"translation"。在很多C/C++教材中,也将这个过程称为**“Compilation”(编译)**。

由于compilation/compile在不同的情境下有不同的含义,为了便于的区分,很多工具软件将这个过程称为build(构建)

下图展示了C/C++编译(构建)程序的一般过程:

graph TD
  subgraph 构建
  Source1{{源文件}} -- 预处理 --> TranslationUnit1[编译单元]
  Header1[[头文件]] -.-> TranslationUnit1[编译单元]
  Source2{{源文件}} -- 预处理 --> TranslationUnit2[编译单元]
  Header2[[头文件]] -.-> TranslationUnit2[编译单元]
  Source3{{源文件}} -- 预处理 --> TranslationUnit3[编译单元]
  Header3[[头文件]] -.-> TranslationUnit3[编译单元]
  TranslationUnit1 -- 编译 --> TranslatedUnit1([目标文件])
  TranslationUnit2 -- 编译 --> TranslatedUnit2([目标文件])
  TranslationUnit3 -- 编译 --> TranslatedUnit3([目标文件])
  end
  subgraph 链接
  TranslatedUnit1 & TranslatedUnit2 & TranslatedUnit3 -- 链接 --> Executable[/可执行文件/]
  end

预处理和编译单元

编译的第一步是对源文件(source file)进行预处理(preprocess)。预处理包括转码、标记切分(tokenize)、宏替换等很多工作,但其中最重要的工作是把源文件中#include语句包含的头文件(header)的内容和源文件合并在一起成为一个整体,也就是所谓的"编译单元"(translation unit)。

每一个源文件经过预处理后都会得到一个"编译单元"。

在gcc编译时加入"-E"参数,就可以将源文件预处理后得到的编译单元保存到指定的文件中。

编译和目标文件

编译过程的下一步是将编译单元转换为机器代码,这个步骤一般叫做"编译"(compilation),编译得到的机器代码被称为"translated unit"(“被编译单元”)。 当被编译单元保存到文件中时,我们会将该文件称为"目标文件"(object file),通常以.o或者.obj作为目标文件的后缀名。

因为"被翻译单元"这个说法在中文中比较别扭,所以我们一般用"目标文件"来代替它,即使"目标文件"并没有被实际存到文件里。

说明:很不幸,编译这个词被在不同的地方表示了不同的含义。不过根据上下文,我们一般都能够理解"编译"到底是指从源文件到目标文件,还是从编译单元到目标文件。

链接

链接是整个编译过程中的最后一步,将一个或者多个目标文件整合成一个可执行文件。这是多文件编译时最容易出问题的步骤。

下图是一个典型的链接错误提示(首先,错误提示显示的文件名是个目标文件"xxxx.o";其次,ld(gcc的链接程序)程序错误退出"ld returned 1 exit status"):

常见的错误问题有:

  • 多个目标文件中存在同名的标识符。(在多个源文件中定义了同一个全局变量或者函数)
  • 找不到某个函数的定义。(某个源文件中调用了某个函数,但是在所有的目标文件中都找不到这个函数的定义)

库文件

在链接时我们可能会需要用到.a或者.lib结尾的库文件(library file),这些文件实际上是由多个预先生成的目标文件组成的包。链接某个库文件实际上就是链接包里面的目标文件。

在gcc编译时,指定-lxxx参数,实际是让gcc链接libxxx.a库文件。

使用gcc工具集里的ar命令可以管理和查看.a文件中的内容。下图显示了libstdc++.a库文件中包含的目标文件:

在编译C/C++程序时,缺省gcc会自动链接标准库的库文件。因此,我们不需要告诉gcc怎么找到printf等标准库函数的定义,gcc就能够正确编译和链接普通的程序。

Make与Makefile

gcc一次运行只能进行单个文件的编译,单个文件的编译链接,或者多个文件的链接;无法完成多个文件的编译和链接。因此,需要按照一定的顺序多次运行gcc,才能完成一次完整的多文件编译链接。

此外,我们在维护和修改维护软件时,往往需要在只更新了一两个源文件的情况下重新生成可执行文件。显然,此时只需要对那些修改过的源文件重新编译得到更新的目标文件;没有修改过的源文件没有必要重新编译一遍。

为了方便这个过程,大家使用make工具来管理和执行这个过程。它的核心功能就是检查相关的源文件和头文件和对应的目标文件相比是否有更新,重新编译那些受到变化影响的源文件得到更新的目标文件,然后重新链接所有的目标文件最终得到新的可执行文件。

一般我们会用一个配置文件用来告诉make工具,生成可执行性文件需要哪些目标文件,每个目标文件又对应哪个源文件以及涉及哪些头文件,应该如何编译等等信息。这个配置文件被称为makefile,一般使用Makefile或者Makefile.win作为它的文件名。

小熊猫C++在编译单文件时,会直接调用gcc;在多文件编译(编译项目)时,会根据项目信息,自动生成makefile,然后调用make程序来完成编译。

下面是小熊猫C++自动生成的一个项目makefile:

# Project: 项目23
# Makefile created by Red Panda C++ 1.0.0

CPP      = g++.exe
CC       = gcc.exe
WINDRES  = windres.exe
RES      = 项目23_private.res
OBJ      = main.o glmatrix.o $(RES)
LINKOBJ  = main.o glmatrix.o $(RES)
CLEANOBJ  =  main.o glmatrix.o $(RES)
LIBS     =  -lwinmm -mwindows -lm -lfreeglut.dll -lopengl32 -lwinmm -lgdi32  
INCS     =  
CXXINCS  =  
BIN      = 项目23.exe
CXXFLAGS = $(CXXINCS)  -Wall -Wextra -g3 -pipe -D__DEBUG__
CFLAGS   = $(INCS)  -Wall -Wextra -g3 -pipe -D__DEBUG__
RM       = del /q /f

.PHONY: all all-before all-after clean clean-custom

all: all-before $(BIN) all-after

clean: clean-custom
	${RM} $(CLEANOBJ) $(BIN) > NUL 2>&1

$(BIN): $(OBJ)
	$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)

main.o: main.c glmatrix.h
	$(CPP) -c C:/Users/royqh/Documents/projects/项目23/main.c -o main.o $(CXXFLAGS) 

glmatrix.o: glmatrix.c glmatrix.h
	$(CPP) -c C:/Users/royqh/Documents/projects/项目23/glmatrix.c -o glmatrix.o $(CXXFLAGS) 

项目23_private.res: 项目23_private.rc 
	$(WINDRES) -i 项目23_private.rc --input-format=rc -o 项目23_private.res -O coff 

从中我们可以看到,"$(BIN)"(也就是"项目23.exe")依赖于"$(OBJ)"(main.o、glmatrix.o等目标文件);而main.o依赖于main.c和glmatrix.h。make程序会根据这些信息来自动判断应该执行哪些操作来生成项目23.exe文件。

6.2 - 项目及其使用

使用小熊猫C++的项目功能

创建项目

通过"文件"菜单→“新建”→“新建项目…",可以打开新建项目对话框。

项目视图

新建项目文件

加入项目文件

新建类

6.3 - 自定义Makefile

通过自定义Makefile来实现包含复杂步骤的编译过程

7 - 试题集

使用试题集快速测试程序的正确性

7.1 - 试题和案例

使用试题集快速测试程序的正确性

小熊猫C++使用“试题”(Problem)来实现对使用标准输入输出的程序的自动测试。

  • 试题集是由试题组成的集合。
  • 每个试题就是一道竞赛或者练习题目,包括题目和试题内容,以及多个试题案例
  • 每个试题案例对应一组测试数据,由输入数据期望输出数据组成。
  • 运行当前案例就是将当前案例的输入数据作为标准输入运行当前程序,并将程序的输出保存到输出框中。程序运行结束后,自动比较实际输出和案例的期望输出是否一致。
  • 运行所有案例就是将当前试题的所有案例逐一作为当前案例执行“运行当前案例

通过小熊猫C++主窗口左侧的试题集视图可以管理当前试题集中的试题。通过下方的试题视图可以管理和运行当前试题的案例。

7.2 - 从OJ网站下载试题

使用CompetitiveCompanion浏览器插件下载OJ试题

作者:超能少年飞 (2310646553@qq.com)

1. 安装插件

在使用这个可以节约时间的功能之前,请确定你有安装以下的东西:

  1. 小熊猫C++(废话)
  2. 一个名为Competitive Companion 的插件

你不知道第二个是什么?
Competitive Companion 简单来讲就是将你所在的浏览器页面(如果是OJ)上的所有测试点都扒下来。 而这个牛逼的插件是和浏览器绑定的。所以说,不同的浏览器有不同的解决方法:

Google Chrome

由于Chrome的应用商店被一股神奇的力量封锁在了中国大陆之外~~(应该不会有人用梯子吧)~~,所以说,我们要安装的是.crx格式的文件。这个文件可以在神奇的Bing或是百度以 Competitive Companion下载 的关键词搜到。用Google Chrome下载完之后,他会告诉你,这玩意可能危险。此时请不要点放弃!那样就前功尽弃了! 在你点下“保留”之后,它就会保存在你的电脑里了。
现在,请点右上角的三个点,选择“更多工具——扩展程序”,然后将刚刚下载的文件拖到页面里,再确认一下,就OK了!

Microsoft Edge

Edge的应用商店可以访问,但是并没有这款插件。由于Edge的插件与Chrome的插件相通,所以安装步骤与Chrome同理。

Mozila Firefox

FireFox的扩展商店可以访问,且有这款插件。所以可以直接搜索扩展商店,然后安装插件。

其它浏览器

换一个浏览器吧 绝大多数基于Chrome的核心开发,所以和Chrome浏览器有异曲同工之处。

2. 实际使用

可以使用Competitive Companion的情况下

此处以Mozila Firefox为例。
我想要复习一下dfs,于是打开了这道远古题目:NOIP远古老题
然后将数据导入到小熊猫C++里:我们要先点击下图中被红框框起来的图标
然后很快啊,小熊猫就会“咻”的一下蹦出来,然后下面会出现一些神奇的玩意儿:
下面绿框圈起来的,可以分成三个部分来讲解:

  1. 左上角的那个部分,是这道题的名字,应该很好理解吧
  2. 左边那个部分,上面五个按钮从左到右分别是:添加试题案例,删除试题样例,打开答案源代码文件,运行试题集,设置试题集。全部都是字面意思,在此不做说明。
  3. 右边那占了一大半的部分,字面意思,就是从OJ上爬下来的输入输出样例,还有你程序实际输出的答案。

然后经过一番操作,我们把代码写了出来,接下来就要运行了:
点击下面五个按键中的“运行试题集”,然后可能会跳出 “文件未保存” “源代码未编译” “程序文件比执行文件新” 等等提示。与平常编译文件同理,你只要都选 “保存”和“编译”就可以了。
经过万人瞩目的运行时刻,你可能会发现下面那不起眼的“试题样例1”之类的玩意,前面戴上了一个√或是×。这就代表着你的程序是否通过这些测试样例了。如果有些没过,不好意思,请继续去调代码!

在不能使用Competitive Companion的情况下

但是!Competitive Companion这个插件不是万能的!在部分没有被开发者纳入支持名单的OJ(比如本校OJ),你运行Competitive Companion是不会有效果的!
所以说,这种情况下该怎么办呢?这种情况下,请点击下图中的那个被红框圈起来的加号按钮,那是“添加试题集”的意思 然后,就会出现一个全新的试题集,等着你赐予它测试样例。这个时候,你要点“添加试题样例”这个按键,然后一个空白的试题样例就出现了!
现在这个测试样例还是一个空壳子,我们要从OJ上复制下来输入样例和输出样例,让它变成一个有灵魂的测试样例!
Ctrl-C和Ctrl-V应该不用讲吧 将你复制下来的输入和输出分别粘贴到“输入”和“期望输出”里。
然后重复以上两步,就可以达到直接使用Competitive Companion的效果了!

注意:每个测试点要单独增加一个试题样例。

这就是小熊猫C++的试题集功能的简单玩耍方法了。

8 - 文件视图

通过文件视图管理和组织代码文件

9 - 重构

使用重构功能优化和改善代码

重命名符号

在“重构”或者编辑器的右键菜单中,可以找到“重命名符号”菜单项。其作用是在程序中将指定的符号所有出现的地方全部统一改为新的名称。该功能会自动区分不同作用域的重名符号。

例如,程序中分别存在全局变量text和函数process()中的局部变量text。将局部变量text重命名为text1后,全局变量text仍然保持不变。

该功能可以解除用户修改变量、函数等符号名称时的顾虑,帮助用户编写可读性强的程序。

10 - 汇编语言支持

编辑、编译、运行和调试GNU汇编语言程序。

小熊猫C++支持编辑、编译、运行和调试GNU汇编语言程序。

  • 支持GNU汇编语言程序的 语法高亮 显示。
  • 在使用x86 CPU的系统中,支持 常用指令和寄存器名的补全提示
  • 在使用x86 CPU的系统中,光标停留在指令上时,显示该指令的作用
  • 光标停留在立即数上时,显示该数的十六进制和十进制值。
  • 和C/C++语言程序一样,小熊猫C++可以直接编译、运行和调试汇编语言程序。
  • 对于C/C++程序,可通过 “运行”菜单→“生成汇编” 生成对应的汇编程序文件。

11 - SDCC支持

编辑和使用SDCC编译器编译单片机程序

从2.24版本开始,小熊猫C++支持编辑SDCC C语言语法的单片机程序,以及使用SDCC编译器生成二进制文件。

  • 在选项对话框→“编译器”→“编译器配置集”页中,点击左上角第二个按钮,选择SDCC编译器所在的文件夹即可添加SDCC编译器配置。
  • 当前编译器配置为SDCC时,代码编辑器支持SDCC程序文件的语法高亮和补全提示。
  • 当前编译器配置为SDCC时,可使用“编译”和“全部重编译”功能生成二进制文件。
  • 在选项对话框→“编译器”→“编译器配置集”页的输出页中,可选择生成的二进制文件类型。

12 - 版本管理

使用内置的Git功能对代码文件进行版本管理

从2.24版开始,小熊猫C++发行版中不再提供git版本管理相关功能。强烈推荐windows用户使用tortoisegit进行程序的版本管理。