| |
CodeWarrior 使用教程
课 程 目 录
Translated from CodeWarriorU.COM
第一课: 认识 CodeWarrior
第二课: 工程和目标文件的显示和定制
第三课: 编译
第四课: 链接
第五课: 调试
第六课: 定制
第七课: 库函数和 Microsoft Foundation Classes (MFC)
第八课: 总结
CodeWarrior 使用教程
第一课 认识 CodeWarrior
Translated from CodeWarriorU.COM
CodeWarrior 能做些什么? 当你知道自己能写更好的程序时,你一定不会再使用别人开发的应用程序。但是常常会发生这种情况,就是当你写了无数行代码后,却找不到使得整个程序出错的那一行代码,导致根本没法编译和链接整个程序。这可能更令人灰心丧气。
本文将告诉你如何使用 CodeWarrior 这一工具解决上述问题。
从现在开始,我们将集中精力学习如何在 CodeWarrior 中使用 C/C++ 进行编程。为了学习本课程,你必须已经能够比较熟练地使用上述两种语言之一。CodeWarrior 也可以支持 Java 开发,但那是另一门课程的内容。本课程仅限于在 Windows 平台上使用 CodeWarrior 进行的开发。一旦你精通了 CodeWarrior 编程后,你可以试试在其它平台上使用 CodeWarrior。本文中讨论过的大部分内容都可以应用到开发 Mac 应用程序中。
CodeWarrior 能够自动地检查代码中的明显错误,它通过一个集成的调试器和编辑器来扫描你的代码,以找到并减少明显的错误,然后编译并链接程序以便计算机能够理解并执行你的程序。你所使用过的每个应用程序都经过了使用象 CodeWorrior 这样的开发工具进行编码、编译、编辑、链接和调试的过程。现在你在我们的指导下,自己也可以去做这些工作了。
你可以使用 CodeWarrior 来编写你能够想象得到的任何一种类型的程序。如果你是一个初学者,你可以选择编写一个应用程序(比如一个可执行程序),比如象微软公司的文本编辑器 WordPad 这样的应用程序。
应用程序可能是最容易编写的程序了,而那些庞大的商业软件,比如象 Adobe Photoshop,Microsoft Word 以及 CodeWarrior 软件都是极其复杂的。其它类型的程序指的是控制面板(control panels),动态链接库(dynamic linked libraries,DLLs) 和插件(plug-ins)。我们先来简单的讨论一下这些类型的程序。
在 Windows 中,控制面板程序是一些(通常比较小的)存放在控制面板目录下的程序,可以在开始菜单的控制面板项中看到它们。控制面板实际上是设置系统功能的一个简单界面,比如可以在控制面板中完成诸如设置音量和鼠标移动速度这样一些参数。
动态链接库 (DLLs) 提供了一些很有用的被系统和应用程序共享的函数。通常它们都是没有用户界面的。
插件 (Plug-ins) 有点类似于 DLLs,插件也是可供其它软件使用的小程序,但插件只能被特定的软件使用。比如说,Photoshop 的插件允许程序员方便地扩展 Photoshop 的功能,而不需要去修改它的源代码。同样的,许多 Web 浏览器也使用插件来增加功能,或者为了让你能够看到页面上的新的内容类型。实际上,有许多程序,包括 CodeWarrior,都使用这种插件结构。
一旦你掌握了 CodeWarior 和你所使用的操作系统的编程接口时,你可以编写许多其它类型的程序。实际上,本课程也是你深入学习其它编程方法的基础课程。你已经找到了一个最优秀的地方开始你的编程之旅。好,现在请坐好,放松,去吸取这门课程的精华吧,你将踏上一条成为一个编程武士的道路!
CodeWarrior 入门
CodeWarrior 是一个复杂的应用程序,你必须花点时间来了解它的各种各样的组件和功能。第一课将讲述 CodeWarrior IDE 的安装。我们将学习菜单、窗口和其它的一些方面。建议你最好一边学习本课程,一边学习使用 CodeWarrior 的集成开发环境。我们从运行 CodeWarrior 开始,如果你按照默认方式安装的 CodeWarrior 软件,那么在 Windows 的桌面上将会有一个该软件的快捷方式图标。双击该图标启动 CodeWarrior 的集成开发环境。如果在 Windows 桌面上没有这个快捷图标(这种情况经常发生),你可以在 C:\Program Files\Metrowerks\CodeWarrior\Bin 中找到 IDE.exe 文件,然后运行它。
工具条
启动 CodeWarrior 后,你将会看到,在屏幕上方的菜单下面有一个工具条。这个工具条(见图1-1)包含了一些常用菜单项的快捷方式。在后面的章节中,你将学到如何设置这个工具条,甚至是整个 IDE 环境。现在,你应记住,这个工具条用于快捷使用 IDE 中的功能。
文件菜单
CodeWarrior IDE 的菜单是按照标准方式设置的。其中的文件菜单用于处理和文件相关的一些操作,比如创建、打开、保存和打印等等。
编辑菜单
CodeWarrior 的编辑菜单和其它的 Windows 应用程序也很相像。其中包括了剪切、复制和粘贴等操作,以及其它一些使得程序员能够更方便地管理源码版面布局的选项。在编辑菜单中还有一个 Preferences 项,我们在这一课的后面将提到它。
查看菜单
查看菜单(图1-2)用于安排工具条和其它窗口在 CodeWarrior 环境中如何显示的选项。所谓的“其它窗口”包括许多特殊的窗口,比如观察点(Watchpoints)窗口,表达式(Expressions)窗口,过程(Processes)窗口和全局变量(Global Variables)窗口等。
查找菜单
查找菜单用于在单个文件或硬盘的目录中查找指定的代码。你可以使用它来方便地替换文本块或在你的代码中搜索指定的项目。即使是在小工程中使用这个工具也非常方便。
工程菜单
工程菜单中的工具用于管理 CodeWarrior 工程。一个工程包括组成你正在编写的程序的所有的文件,包括头文件、源代码和库文件。工程窗口显示了所有这些文件的名称。我们将在第二课中深入讨论这部分内容。
调试菜单
这是在编制程序中最常用到的工具。我们将在第五课中详细介绍它的使用方法。
窗口菜单
用于在 CodeWarrior 环境管理窗口显示方式的菜单。
帮助菜单
通过帮助菜单可以到网上寻求关于 CodeWarrior 任何问题的在线解答。够酷的吧?
了解 CodeWarrior 集成开发环境的设置
CodeWarrior IDE 提供了许多设置以便让你定制你的工作环境。当你选择了编辑菜单中的 Preferences 项时,你将会看到一个设置对话框(如图1-3)。在该对话框中,有控制 CodeWarrior 编辑器、调试器和其它许多功能的界面和行为的选项。在这一节中,我们将学习这些设置的使用。
你可以在自己的 CodeWarrior 中试试上述这些设置项。你可以先点击问号标志,然后点击你感兴趣的项目,就可以得到一个有关该项目的用途的简短介绍,也可以从帮助菜单中得到更详细的信息。
通用设置
编译设置(Build Settings): 选择是否在执行编译之前保存已打开的源文件,以及有多少内存被用于编译工作;
IDE 之外(IDE Extras): 几个独立的设置。比如指定 CodeWarrior 是否使用一个第三方的文本编辑器——因为集成的编辑器并不是很完美,这可以通过指定一个你惯用的编辑器来替代它;
插件设置(Plug-In Settings): 供插件开发商调试他们的插件;
隐藏文件夹(Shielded Folders): 在这里指定的文件夹在工程设计期间,或执行查找和比较操作期间,将要被忽略掉。如果在你的工程级有一个巨大的“数据”文件目录,而你又不想让这些文件降低 CodeWarrior 的操作速度时,这个设置就很管用了;
资料树(Source Trees): 用于指定 CodeWarrior 在编译程序时用不着的目录。
编辑器设置
编辑器设置(Editor Settings): 几个用于定制编辑器显示、管理文本和窗口的设置项;
字体和制表符(Fonts and Tabs): 设置编辑器中的文本大小、字体、制表符和其它显示设置;
文本颜色(Text Colors): 用于指定特定语言元素(比如程序的注释)在编辑窗口中的显示的颜色。
调试器设置
显示设置(Display Settings): 几个用于定制调试器显示的设置项;
视窗化(Windowing): 设定调试器如何管理它的窗口(比如隐藏所有打开的编辑器窗口);
全局设置(Global Settings): 几个用于定制调试器在全局层次如何工作的设置。比如当一个包含了程序调试信息的文件被打开时,是否启动这个程序;
远程连接(Remote Connections): 允许通过 TCP/IP 进行远程调试。这样,你就可以在地球的另一边调试你的软件了;
Java 设置/Java 调试(Java Settings/Java Debugging): 允许你设置特定的 Java 编程语言选项。本课程不涉及这部分内容。
[size=+1]RAD 工具
layout 编辑器: 几个用于在 CodeWarrior 中定制快速应用程序开发工具的使用的设置。
正如你所见到的,CodeWarrior 有许多设置项和选项。设置完后点击“Save”按钮保存你所作的修改,点击“Close”按钮将忽略你所作的所有修改。在进入下一节课之前,多练习几次。最后请确认“默认的文本文件格式(Default Text File Format)”(在编辑器设置面板中)保持为 DOS 设置。
CodeWarrior 使用教程
第二课 显示和定制工程和目标文件(1)
Translated from CodeWarriorU.COM
本课将讲述 CodeWarrior 操作文件的方式以及介绍它的工程(Project)窗口。 [size=+1]什么是工程文件
为了使用 CodeWarrior 来创建一个应用程序,你必须创建许多文件来构成一个工程(Project)。该工程的设置和所有这些文件的指针都被存放在一个工程文件中。这些设置包括编译和链接设置、源文件、库文件以及它们之间用于产生最终程序的相互关系。你可以将这个工程文件看作该工程的大脑:它保存了所有文件相互依存的关系并知道如何将它们组合成为一个可用的应用程序。工程窗口依次显示了这些关于你的程序和该程序所包含的文件的信息,并允许你只需轻松点击就可以修改这个工程。图2-1显示了工程窗口的外观。
图 2-1: 显示工程信息的工程窗口(图示为空的情况)
大多数组成你的程序的文件都是原始的文本文件。这些文件包含了你在 CodeWarrior 的编辑器中键入的源代码。在某些情况下,你还将使用一些预编译的源码和头文件。在进行数学运算和 I/O 操作时,你还要使用到一些库文件,比如 Metrowerks 标准库(Metrowerks Standard Library,MSL)
通常,你都是使用 C 或 C++ 来编写源代码,但通过给 CodewWarrior 的集成开发环境加装相应的插件(plug-in),你也可以在 CodeWarrior 中使用其它语言来进行编程。别忘了,CodeWarrior 可是一个可扩展的集成开发环境。通过给它安装一些插件,你就可以扩展它的功能。比如说,加入有人开发了一种新的叫做 Z++ 的编程语言,你就可以为 CodeWarrior 创建一个相应的插件使之能够支持 Z++ 语言,而且你还可以拿这个插件卖好多钱,让所有使用 CodeWarrior 编程的人都使上 Z++ 语言。那该多好!:)
现在你知道了 CodeWarrior 是如何使用文件的了。下面我们来详细地学习有关工程窗口的知识。
[size=+1]工程窗口
当你启动 CodeWarrior 并打开或创建一个工程时,工程窗口就会显示出来。该窗口用于管理整个工程的所有文件以及这个工程将要产生的目标(targets)文件。一个工程包含了足够的信息来编译一个或多个目标文件。所谓的目标(target)文件就是当你编译程序时,由 CodeWariior 创建出来的(通常是)一个应用程序或库文件。一些程序可以编译产生多个目标文件。比如,你可以编写一个程序来创建一个 DLL 和一个调用该 DLL 的主应用程序。在 CodeWarrior 的工程中,你可以定义一个目标来产生 DLL,定义另一个目标来产生应用程序。通过这种方式,你的工程只需编译一次就可产生所有需要的目标文件或片断。图 2-2 显示了“Hello World”程序的工程窗口。
图 2-2: Hello World 程序的工程窗口(其中显示了所有包含于该程序中或用于编译该程序的文件)
你可以看到,在这个工程窗口中确实包含了一些项目。在窗口的顶端有三个标签(tab)页:文件标签(如图2-2显示)、链接顺序标签页和目标文件标签页(后两个标签页将在后续课程中讲述)。在这几个标签页的上方,有一个用于选择要编译的目标文件的下拉菜单。在本例中,我们选择的是 Hello World 工程的调试版本。在下拉菜单的右边有几个图标,它们的存在允许你不必使用菜单命令就可以方便地编译、链接和运行这个工程。
注意: 在某些版本的 CodeWarrior 中,链接标签被称为段(segments)标签。有些人可能在某些 X86 的处理器上编程时使用的是分段(segmented)代码。但使用 Windows 版的 CodeWarrior 工具时就不是这样,这是产生的 X86 代码使用的是"扁平的"(flat),或者叫做非分段的(unsegmented) 内存空间。
顾名思义,文件标签页列出了在工程中所有可能用到的文件。你可以通过创建一些组(用文件夹图标表示)来分门别类地管理这些文件,并可以帮助你方便地了解哪些文件将被使用。在本例中,我们将 C 程序(以.c为后缀名的文件)全都放到一个叫做 Source 的组中,同时将库文件放到另一个组中,以便整洁明了地管理这些文件。
在 Sources 组中有一个 main.c 文件。因为我们还没有编译这个工程,所以在每个文件对应的 Code 和 Data 栏中显示数字的都是零。一旦我们编译了这个工程,这些数字就将显示出来,表示源码转换为机器代码后实际的代码量和数据量。可是,库文件 ANSICX86.LIB 和 MWCRTL.LIB 后面显示的是 n/a 。这表示索虽然这些文件被显示在这里,但是它们并不是 Hello World 目标文件的一部分。这两个文件是用于不可调试(non-debugging)开发的,而本例不是这种情况。如果我们从菜单中修改本例的目标文件为 Release(发布) 版本时,这两个文件就用得上了。这时这些文件后面的 Code 和 Data 栏目就会显示相应的数值。
注意 : 在 Data 和 Code 栏右端的 Target 栏目中的小子弹头也是用来表示该文件是否被当前编译生成的目标文件使用到。
再往右边去,是 Debug 栏(用一个绿色的小虫子表示),它是用于告诉你对应的文件在编译时是否要产生调试信息。我们将在第五课中详细论述这部分内容。最后,我们来看看在每一行最右端的弹出菜单,它是用于打开文件、更新源码、打开包含的头文件等等操作的快捷方式,具体是什么才作,要看它所代表的项目的类型而定。
现在让我们来编译这个 Hello World 工程并看看编译后的工程窗口的情况。我们从 Project 菜单中选择 Make 命令来编译该工程。这将更新所有需要编译的文件并产生相应的输出文件——在本例中是 Hello World 这个应用程序。
从图2-3中我们可以看到,工程窗口发生了一些变化。Code 和 Data 栏都显示了当前工程中对应项的相应的数字。如果你打算看看编译前后存放这些文件的目录的话,你会发现编译后在该目录下产生了一些新的文件
在本例中,编译工程后在工程目录中产生了一个新的文件。这就是 X86 目标文件输出——生成一个叫做 Hello World x86 的应用程序。其它一些一直存在于这个目录中的文件是: .mcp 文件—工程文件本省,以及 .c 源文件—包含了应用程序源码的文件。Hello World Data 目录中还包含了由 CodwWarrior 生成的各种各样的支持文件。现在你还不必去关心这些文件。如果你正在编译目标文件的调试版本,你会看到更多的文件被产生出来,这些文件中可能包含着符号(symbolic)调试信息。集成开发环境的调试器使用这些符号信息来记录在高层次源码中的操作轨迹。我们将在第五课中详细讲述这方面内容。
现在你已经了解了这些文件是如何结合在一起被编译生成一个目标文件的。让我们来运行这个目标文件并看看它的运行结果是什么样。你双击 Hello World x86 应用程序,就会有如图 2-5所示的结果显示出来。
[size=+1]你来试试看
总有一天,你自己也能编写出象 Hello World 这样充满激情和意义深远的程序来。这是完全有可能的。只要你有决心努力工作,学完本课你就可以编写这个程序了。下面我们给出该程序的源代码:
#include
void main(void) {
int c;
printf("Hello World on Windows!\n");
c = getchar();
}
就这么多!你没想到会这么简单吧?你可以试试看将 "Hello World on Windows!" 这句话换成一句别的什么内容。要不了多久,你就能自己编写一些不仅能显示文本而且还能执行你指定的其它任务的应用程序了。但在此之前,你还需要学习第四课,有关链接的知识。
[size=+1]关于[size=+1]getchar()[size=+1]函数
那些有经验的 C 程序员可能会问,上述代码中使用的 字符输入函数 getchar() 用在这里是什么意思。通常地,当一个应用程序执行完毕后,它就会终止,然后操作系统就会立即清除该应用程序输出。这样,当上述应用程序显示完“Hello World on Windows!”后,为了避免系统立即将该程序地输出清除,我们在程序中添加了一个 getchar() 函数,使程序在此处暂停,直到有键盘输入时整个程序会终止。这样我们才有足够的时间来看清楚该程序的输出。
这是一个正常的操作,而不是一个 bug。实际上,CodeWarrior 也提供了一个适用于此处的库函数,这个库函数中的 C 控制台 I/O 函数步不仅可以在程序显示完毕后锁定应用程序,而且还可以让你将输出的文本信息存储到一个文件中去。
CodeWarrior 使用教程
第三课 编 译
Translated from CodeWarriorU.COM
第一步:理解编译阶段 我们的前面的课程中已经学到,源程序输入完之后的工作就是要编译它。编译源程序就是计算机把你所写(通常是用C 或 C++编写的)的源代码进行分解、分析,然后转化为机器语言。机器语言是一种计算机能够理解阿语言,而且它运行起来比 C 或 C++ 也要快得多。编译的大致过程如下:
1. 用 C 或 C++ 编写代码:
#include
void main(void) {
int c;
printf("Hello World on Windows!\n");
c = getchar();
}
2. 进行编译。 CodeWarrior 编译上述代码并把它翻译成机器语言,结果如下:
符号名:
1: _main 2: _@8 3: _printf 4: ___files 5: _fwide 6: ___get_char =============================================================== SECTION SIZE = 0x0000003C; NAME =?.text DEFINED SYMBOLS: name = _main ffset = 0x00000000; type = 0x0020; class = 0x0002 00000000: 68 00 00 00 00 push offset _@8 00000005: E8 00 00 00 00 call _printf 0000000A: 59 pop ecx 0000000B: 6A FF push -1 0000000D: 68 00 00 00 00 push offset ___files 00000012: E8 00 00 00 00 call _fwide 00000017: 85 C0 test eax,eax 00000019: 59 pop ecx 0000001A: 59 pop ecx 0000001B: 7D 1E jge $+32 ; --> 0x003b 0000001D: 83 2D 2C 00 00 00 sub dword ptr ___files+44,1 00000023: 01 00000024: 72 0A jb $+12 ; --> 0x0030 00000026: FF 05 28 00 00 00 inc dword ptr ___files+40 0000002C: EB 0D jmp $+15 ; --> 0x003b 0000002E: 89 C0 mov eax,eax 00000030: 68 00 00 00 00 push offset ___files 00000035: E8 00 00 00 00 call ___get_char 0000003A: 59 pop ecx 0000003B: C3 ret near ============================================================= SECTION SIZE = 0x00000019; NAME = .data 00000000: 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 6F 6E 20 57 Hello World on W 00000010: 69 6E 64 6F 77 73 21 0A 00 indows! DEFINED SYMBOLS: name = _@8 ffset = 0x00000000; type = 0x0000; class = 0x0003 ==============================================================
上述机器代码难于阅读,不要去管它。机器代码相比 C 或 C++ 而言,要难理解多了。但是,计算机只能理解机器语言。只有将你的程序编译—或翻译—成机器代码,然后再执行它,这样运行起来才能快一些,而不是每次运行时才去翻译它,那样运行速度就很慢了。
你只需选定一个源文件,然后从工程菜单中选择反汇编项,你就能看到该文件的机器语言清单。实际上上面我们看到的机器语言清单就是这样得到的。如果你仔细地对照阅读一下你的 C 或 C++ 源代码和它编译后的机器代码,不难发现它们之间的关系。
CodeWarrior 中编译选项的详细设置
在正式开始编译源代码之前,CodeWarrior 还要对其做预处理。在这个阶段,是对 C 或 C++ 代码进行编译前的一些准备工作。在编写程序的过程中,往往会有很多相同的P代码输入,于是程序员使用一些快捷方式,比如所谓的宏(macros)来代替这些相同的输入。例如,你可以使用 APPNAME 作为一个宏,来表示“Metrowerks CodeWarrior”,以此来减少输入的工作量。预处理就是要把这些宏转换为它们实际表示的代码,此外还要替换一些定义符号(比如 #define THREE 3)为实际的源代码。为了更好地理解预处理所做的工作,你可以查看一下预处理结果的清单。首先在工程窗口中选中一个源文件,然后从工程菜单中选择预处理项,你就可以看到源代码进行了预处理之后,编译之前的结果清单了。.
[size=+1]定制[size=+1] [size=+1]CodeWarrior [size=+1]的编译方式
在第二课中,我们已经了解了一些控制 CodeWarrior 编译代码的选项对话框。现在我们再来详细地看看一些标准 C 和 C++ 编译器的设置。请你按照下面所学内容在你的 CodeWarrior 上进行实际的操作练习。
图 3-1: 控制 CodeWarrior 进行 C/C++ 编译的语言设置
从编辑菜单中选择 Hello World X86 setting 项来打开设置窗口。现在,点击图3-1中语言设置类(Language Settings category)下面的 C/C++ 语言标签(C/C++ Language label),你就可以看到C/C++ 语言设置对话框中的许多选项。我们逐个来学习这些选项,以便了解它们是如何影响编译的过程的。
激活 C++ 编译器(Activate C++ Compiler): 这个选项允许你把所有后缀名为 .c 的源文件当作 C++ 文件来进行编译。如果你想在 C 源码中使用一些 C++ 语言的特色时,这个功能就很有用了;
arm 一致性(ARM Conformance): 编译器要求你的代码遵循 ANSI C++ 的标准。但你可以通过选中这个选项来指定你的编译器遵循“注释 C++ 参考手册”(Annotated C++ Reference Manual,ARM) 中的标准;
允许 C++ 例外(Enable C++ Exceptions): 选中这个选项将允许你在 C++ 代码中使用 try/catch/throw 等块(blocks)。这些方法用于书写错误管理器(writing error handlers);
允许 RTTI(Enable RTTI): RTTI 表示 Run Time Type Information(运行类型信息)。这个选项运息编译器判定一个 C++ 对象在运行中的类型。这是 C++ 的高级特色,在很多情况下都是很有用的。如果你想了解更多关于 RTTI 的信息,请查阅你的 C++ 手册;
内联深度/自动内联/延期内联(Inline Depth/Auto-Inline/Deferred Inlining): 这些是关于源代码中使用的内联函数的一些设置项。所谓内联函数,就是在编译时该函数的源代码将被直接插入到程序体中,而不是产生这个函数的调用。在某些情况下,使用内联函数可以提高代码的性能。这是编译器的一个高级设置项;
字符串池(Pool Strings): 通常,编译器将编译后代码中的所有字符串对象存储到它们自己的数据空间中。如果你想将所有的这些字符串存放到一个数据空间中,就应该选中此项。如果你的源代码中有非常多的字符串(比如上面我们提到的 APPNAME 宏),那么你就应该选中此项来节省内存空间。这个功能只能在使用 PowerPC 的 Mac OS 平台上编程时使用;
不重用字符串(Don't Reuse Strings): 所谓“重用字符串”,就是指当你的程序中有几个完全一样的字符串时,编译器会将它们全都存放到同一个数据空间里。但是,有时你可能想修改某个字符串,这就会造成其它和要修改字符串共享数据空间的字符串也要被修改了。如果你想避免这种情况,就要选中这个选项。这样,即使程序中有完全一样的字符串,它们也将存放到不同的数据空间中;
要求有函数原型(Require Function Prototypes): 建议最好选中此项。使用函数原型可以帮助编译器在检查传递给函数的参数类型时发现代码中的错误。所谓函数原型就是在程序的前端对函数进行声明。也就是说,你应当在使用一个函数之前,定义或声明这个函数。既然这个选项这么好,那么什么时候应该关掉它呢?通常是,当你使用一些老版本的 C 进行编程时,并不需要对函数进行事先声明,这时你就应该关掉这个选项来检查整个程序代码。你一定愿意在程序前端书写函数原型,并选中此选项,因为它能帮助你解决这么多的编码错误;
 /1
 /1 