第1章初识C程 序 主要内容 .开发环境 .简单的C程序 贝尔实验室是人们熟悉的著名实验室之一,C语言就诞生于该实验室,主要发明人是该实验室的 DennisRitchie。1972年,DennisRitchie和同事KenThompson为了编写UNIX操作系统设计了一种新的 实用语言,并使用该语言完成了UNIX操作系统的设计。DennisRitchie在设计该语言时借鉴了同事Ken Thompson开发命名的B语言,由于B语言的名字来自当时的BCPL(BasicCombinedProgrammingLanguage)语言的第一个字母,为此,DennisRitchie将其发明的新语言命名为C语言(取BCPL语言的第二 个字母)。1978年,DennisRitchie出版了第一部C语言著作TheCProgrammingLanguage。1983年,美 国国家标准化组织(ANSI)根据DennisRitchie的著作确定出了第一个C语言标准———C89,习惯上将C89 称为ANSIC(标准C)。 C语言高效、灵活,被广泛应用于科学计算,可以在许多软件开发中看到C语言的影子,在TIOBE定期 公布的语言排行榜上,C语言经常和Java语言一起处于前二位(也曾多次处于第一位)。C语言是非常适合 用于编写操作硬件设备的编程语言,特别是随着信息时代的不断进步,嵌入式系统的开发越来越流行,比如 人们使用C语言为汽车、飞行器、机器人、照相机、冰箱、DVD播放机和其他许多现代化设备中的微处理器 编写程序,以便控制这些设备,简言之,嵌入式领域更加注重代码的效率,因此C语言在嵌入式领域独领 风骚。 C语言也是进一步学习其他高级语言,如C++、Java和C#(读作se-sharp),以及相关的课程,如数据 结构、操作系统、微机原理等课程的基础语言。 1.1 开发环境 1.1 基础知识 1. 学习任何一门编程语言都需要选择一种针对该语言的开发工具。针对C语言的开发工具的核心任 务之一就是将人们按照该语言编写的代码(称为源文件)转变成操作系统能够识别执行的指令(也称为机 器指令)。 ulC+本书简称VC+6.VC+0是比较流行和成熟的集成开发 本书将采用Visa+( +)0来开发C程序,+6. 环境,集成开发环境习惯上称为IDE(negaeeeopmnnioet)。VC+0不仅是适合开发C+ ItrtdDvletEvrnmn+6.+程 序的开发工具,同时也适合用来开发C程序,而且国内有关C语言的二级认证考试已经开始使用VC++6.因 此,使用VC+0有利于学生更好地熟悉认证考试环境。 0, +6. 1.2 基础训练———安装VC+0 1.+6. 训练的能力目标是安装、配置VC+0, +6. +6.能启动VC+0。 1.训练的主要内容 .安装VC++6. 0 .配置Includefiles .配置Libraryfiles 2 2.训练步骤 (1)安装VC++6.0 双击MSDEV.EXE,将VC++6.0安装到某个目录,这里将默认的安装目录修改为D:\VC6.0(也可以使 用默认的安装目录)。安装完毕后,单击“开始”→“程序”→“VC++6.0”命令启动VC++6.0,出现如图1.1所 示的开发界面。 图1.1 VC++ 6.0的开发界面 (2)配置Includefiles 接下来配置Includefiles(如果使用默认安装目录,安装时已经由系统自动配置过,可不必重新配置)。 在图1.1所示的开发界面上选择“工具”→“选项”命令,在弹出的图1.2(a)所示的对话框中选择“目录”选项 卡来配置Includefiles。如果安装VC++6.0时修改了安装目录,只需将Includefiles重新配置为新的目录 即可。比如,修改后的目录是D:\VC6.0,那么将目录列表中的Includefiles选项对应的“路径[D]:”做如下 更改: D:\VC6.0\VC98\INCLUDE D:\VC6.0\VC98\MFC\INCLUDE D:\VC6.0\VC98\ATL\INCLUDE 图1.2 配置设置 (3)配置Libraryfiles 然后配置Libraryfiles(如果使用默认安装目录,安装时已经由系统自动配置过,可不必重新配置)。在 图1.1所示的开发界面上选择“工具”→“选项”命令,在弹出的图1.2(b)所示的对话框中选择“目录”选项卡, 并在“目录”下拉列表中选择Libraryfiles来配置Includefiles。图1.2(b)所示的对话框显示的是默认配置。 如果安装VC++6.0时修改了安装目录,只需将Libraryfiles重新配置为新的目录即可。比如,修改后的目 录是D:\VC6.0,那么将目录列表中的Libraryfiles选项对应的“路径[D]:”做如下更改: 3 D:\VC6.0\VC98\LIB D:\VC6.0\VC98\MFC\LIB 3.训练小结与拓展 学习配置Includefiles和Libraryfiles的目的是能使用VC++6.0中的库函数。另外,尽管学习C语言 可以选择任意一个成熟的开发工具,但VC++6.0是目前比较流行的开发工具之一。 1.1.3 上机实践———启动VC++6.0 除可以单击“开始”→“程序”→VC++6.0命令启动VC++6.0外,也可以执行MSDEV.EXE来启动VC ++6.0。假如安装目录是D:\\VC6.0,那么可以双击D:\VC6.0\COMMON\MSDEV98\BIN 目录中的 MSDEV.EXE文件启动VC++6.0。 1. 2 简单的C 程序 1.2.1 基础知识 无论C程序的规模大小,开发一个C程序都需经过如下4个基本步骤。 1.源文件 编写源文件,也称为编写源代码文件。所谓源文件就是按C语言的语法规则,使用文本编辑器编写的 扩展名为.c的文本文件,如first.c、second.c等,也就是说,C程序的源代码存放在扩展名为.c的文本文件中。 2.编译 操作系统不能直接运行源代码文件,因此必须把源代码文件转化为操作系统能够识别的机器指令。编 译器将检查源代码文件中是否有语法错误,如果有语法错误,将提示有关错误;如果没有语法错误,编译器 就会将源代码文件转化为二进制文件,该二进制文件被称为源代码文件的目标文件。目标文件的名字与源 代码文件的名字相同,但扩展名为.obj。 3.链接 目标文件是供链接器使用的文件(操作系统不能直接运行目标文件),也就是说,目标文件中含有待确 定的链接信息,链接器必须把这些信息替换成真正的链接代码,形成一个完整的可执行的代码。即链接器 将程序使用的库函数以及其他函数链接在一起(比如printf()函数就是库函数),并向可执行文件中加入操 作系统的启动代码,形成一个完整的可执行的文件(扩展名是.exe)。没有启动代码操作系统就无法运行可 执行文件,启动代码相当于程序和操作系统之间的接口。所以C程序得到的可执行文件依赖于操作系统, 即在Window操作系统下编译得到的可执行文件,可能无法在Linux操作系统上正确运行或不能在Linux 操作系统上运行(需要在Linux操作系统上重新编译、链接得到可执行文件)。 需要注意的是,如果不小心将库函数printf()函数的名字误写为qrintf,那么在编译阶段可能无任何错 误,但在链接阶段就可能报错,其原因是找不到库函数qrintf()或用户自己定义的qrintf()函数。 4.运行 产生可执行文件后,就可以把该文件交给操作系统去执行。 开发一个C程序的基本步骤如图1.3所示。 1.2.2 基础训练———程序开发步骤 训练的能力目标是能够编写一个简单的C程序的源文件,并编译该源文件、链接目标文件得到可执行 文件,然后运行可执行文件,即运行程序。 1.训练的主要内容 编写一个简单程序,该程序输出两行文字:“很高兴学习C语言”和“Wearestudents”。 4 图1.3 C 程序的开发步骤 2.训练步骤 训练的6个基本步骤是:创建工程、向工程中添加源文件、编写源文件、编译、链接和运行。 (1)创建名字是project1_1的工程 VC++使用一个工程对应一个C程序,也就是说,在VC++ 环境中,通过创建一个工程来创建一个C 程序。创 建工程的步骤如下。 ① 在VC++开发界面上单击“文件”菜单,选择其中的“新建”命令,在弹出的“新建”对话框中选择“工 程”选项卡。 ② 在当前对话框左侧的选项列表中选中Win32ConsoleApplication(注意,不可以选择Win32 Application)。 ③ 在当前对话框右侧的“位置”文本框中输入存放工程的位置,比如C:\C_program。 ④ 在当前对话框的“工程名称”文本框中输入工程的名称,比如project1_1。 ⑤ 在弹出的“选择工程类型”对话框中选择“空工程(Anemptyproject)”。 ⑥ 在工作空间界面(VC++开发界面的左侧)的下方选择FileView视图。 (2)向工程中添加名字是example1_1.c的源文件 向工程中添加源文件的步骤如下。 ① 在VC++开发界面上单击“文件”菜单,选择“新建”命令。 ② 在弹出的“新建”对话框中选择“文件”选项卡。 ③ 在当前对话框左侧的选项列表中选中C++ SourceFile。 ④ 在右侧的“文件名称”文本框中输入源文件的名称,比如example1_1.c(必须带扩展名.c)。 ⑤ 选中“添加到工程”复选框,即把源文件添加到工程中。 (3)编写源文件example1_1.c 在程序代码编辑区(VC++6.0开发环境提供的一个文本编辑器)输入如下源代码。 example1_1.c源文件的内容如下: #include int main() { printf("很高兴学习C 语言\n"); //输出“很高兴学习C 语言”,并回行 printf("We are students\n"); //输出We are students,并回行 system("pause"); //命令行提示按任意键继续 return 0; } 5 (4)编译源文件example1_1.c 在VC++开发界面上单击“组建”(某些VC++6.0版本单击“编译”)菜单,选择“编译”命令对源文件进 行编译,如果源文件没有错误,将产生目标文件,目标文件的名字是example1_1.obj(因为源文件的名是 example1_1.c)。如果源文件有错误,编译器将提示有关错误,这时必须改正错误,然后重新编译源文件。也 可以单击界面上的“编译”快捷按钮编译源文件。 (5)链接目标文件和库函数 在VC++开发界面上单击“组件”菜单,选择“组建(链接)”命令(有的版本是选择“构建”命令)对目标文 件以及所用的库函数进行链接,生成可执行文件。VC++6.0将链接操作称为链接工程,生成的可执行文件 的名是project1_1.exe(因为工程名是project1_1)。也可以单击界面上的“组建(链接)”快捷按钮进行链 接操作。 图1.4 编译的快捷按钮 图1.5 链接的快捷按钮 (6)运行可执行文件 在VC6.0++开发界面上单击“组建”菜单,选择“执行”命令,运行可执行文件project1_1.exe。也可以 单击界面上的“运行”快捷按钮运行可执行文件。 可执行文件的运行结果如图1.7。 图1.6 执行的快捷按钮 图1.7 运行结果 注 程序运行后,要及时关闭弹出的控制台,按回车键即可关闭,通常为命令行窗口,以免影响VC++6.0 继续编译其他源文件或运行其他C程序。 在VC++6.0开发中运行程序属于调试运行,只有脱离VC++6.0环境,运行程序才是软件意义的运行。 3.训练小结与拓展 (1)main()函数 C程序的基本结构就是函数,有时C程序可以只有一个函数,比如只有main()函数(称为主函数)。除 main()函数外,C程序还可以有多个其他函数,main()函数可以调用如printf()库函数等。现在只需知道: 一个C程序(工程)必须有且仅有一个main()函数,操作系统从main()函数开始执行C程序。按ANSIC 标准,main()函数的格式如下: int main(){ ... return 0; } main()函数前面的int称为它的类型(要求main()函数使用return返回一个整数值,通常返回0即 可),main后面的一对小括号表明这是一个函数,紧接着的一对大括号及其所包含的内容是它的函数体。 如果工程中没有main()函数,将无法进行链接操作,也就无法生成可执行文件。 (2)printf()函数 printf()函数是库函数,其作用是可以输出数据到终端设备,比如输出一行文本,输出的文本中如果包含 换行转义符\n,那么printf()函数在输出文本时将\n输出为换行。为了使用printf()函数,需要在源文件中 6 使用#include命令包含stdio.h函数库。 (3)大括号的使用风格 源代码的许多地方都使用一对大括号,比如main()函数的函数体。“行尾”风格是左大括号在上一行的 行尾,而右大括号独占一行。“独行”风格是左、右大括号各自独占一行。下列是“行尾”风格: int main() { 其他代码 } 下列是“独行”风格: int main() { 其他代码 } (4)注释 编译器会忽略注释内容,注释的目的是便于代码的维护和阅读,因此必须养成给代码注释编程的习惯。 C编译器支持两种格式的注释:单行注释和多行注释。 单行注释使用“//”表示单行注释的开始,即该行中从“//”开始的后续内容为注释。多行注释使用“/*”表 示注释的开始,以“*/”表示注释的结束。示例如下: /* 以下是main()方法,操作系统首先执行该方法*/ int main() { printf("你好"); //在控制台(通常是命令行)输出“你好” return 0; } (5)关于编译 C语言是面向过程的编程语言,简单地说,编程人员只需按照C语言的语法编写解决问题的过程,C语 言使用函数封装这样的过程(在第6章将还会详细讲述)。过程语言的源文件的特点之一是更接近人类的 “自然语言”,比如,C语言源程序中的如下函数: int max(int a,int b){ if(a>b) return a; else return b } 该函数负责计算两个整数间的最大值。使用面向过程的语言,人们只需按自己的意图编写各个函数, 语言的语法更接近人们的自然语言,所以,习惯上也称过程语言是高级语言。但是,无论哪种高级语言编写 的源文件,计算机中的操作系统都不能直接执行,因为计算机的操作系统只能直接识别、执行机器指令。因 此,必须把源文件转换成机器指令,然后再由计算机去执行相应的机器指令。所谓机器指令是指可以被 计算机操作系统直接识别、执行的一种由0、1组成的序列代码。每种操作系统都会形成自己独特的机器 指令,比如,某种操作系统可能用8位序列代码10001111表示一次加法操作,以10100000表示一次减 法操作,而另一种计算机可能用8位序列代码10101010表示一次加法操作,以10010011表示一次减法 操作。因此,必须把源代码转化为操作系统能够识别的机器指令来执行。 编译器将检查源文件中的代码是否有语法错误,如果有语法错误,将提示有关错误;如果没有语法错 误,编译器就会将源文件转化为二进制文件,该二进制文件被称作源文件的目标文件。目标文件的名字与 7 源文件的名字相同,但扩展名为.obj(某些编译器得到的目标文件的扩展名为.O)。目标文件是供链接器使 用的文件(不是可执行文件),也就是说,目标文件中含有待确定的链接信息,链接器必须把这些信息替换成 真正的链接代码,形成一个完整的可执行的代码。 (6)console控制台 因为用户建立的是Win32ConsoleApplication,所以C程序在console控制台(通常是命令行窗口)运 行。用户双击C程序的可执行文件,比如project1_1.exe(不是在编程环境VC++6.0中执行),C程序在控制 台(命令行窗口)显示结果后,控制台就消失了,导致用户无法看到程序的运行结果。因此,可以在main()函 数结束前,即return语句之前添加如下语句: system("pause"); 该语句的作用是,等待用户按回车键后才结束程序,即在用户没有按回车键之前,控制台始终对用户 可见。 (7)关闭与打开工程 单击VC++6.0开发界面上的“文件”菜单,选择“关闭工作空间”命令关闭当前工程。选择“打开工作 空间”命令,在弹出的对话框中选择扩展名是.dsw 的工程文件,即通过打开工程文件打开之前建立的 工程。 (8)注意逗号、分号等符号 编写源文件时,初学者需要特别注意,要在英文输入法状态下输入源文件中用到的逗号、分号和小括号 等符号。 1.2.3 上机实践———工程与源文件 1.控制回行(\n) 将example1_1.c中的代码:printf("很高兴学习C语言\n");更改为:printf("很高兴\n学习C语言\ n");观察程序的输出结果会有怎样的变化。 2.可执行文件 如果工程project1_1建立在C:\\C_program 目录中,那么在C:\\C_program\\project1_1目录下的 Debug子目录中可以看到名字为project1_1.exe的可执行文件,运行该文件(双击该文件)也称运行工程。 可以将project1_1.exe可执行文件复制给其他Window系统平台的用户,用户双击project1_1.exe就可以运 行这个C程序。 3.多个源文件的工程 一个C程序(工程)中可以有多个源文件,这些源文件中包含C程序所需要的函数。 (1)建立名字为project1_2的空工程 在VC++6.0开发界面上单击“文件”菜单,选择“新建”命令,在弹出的“新建”对话框在该对话中选择 “工程”选项卡,输入工程名project1_2,工程的位置是C:\\C_program,如图1.8所示。要特别注意,在当前 对话框左侧的选项列表中应选择Win32ConsoleApplication选项,不可以选择“Win32Application”。 (2)向工程添加add.c源文件 在VC++6.0开发界面上单击“文件”菜单,选择“新建”命令。在弹出的“新建”对话框中选择“文件”选 项卡,并在当前对话框左侧的选项列表中选择C++ SourceFile,在右侧的“文件名称”文本框中输入源文件 的名称add.c(注意必须带扩展名),选中“添加到工程”单选按钮,即将add.c添加到project1_2工程中,然后 在add.c的编辑区输入如图1.9所示的内容。 (3)向工程添加example1_2.c源文件 在VC++6.0开发界面上单击“文件”菜单,选择“新建”命令,在弹出的“新建”对话框中选择“文件”选项 卡,并在当前对话框左侧的选项列表中选择C++ SourceFile,在右侧的“文件名称”文本框中输入源文件的 名称example1_2.c(注意必须带扩展名),选中“添加到工程”单选按钮,即将example1_2.c添加到project1_2 8 图1.建立名字是pj_2的工程 8 roect1 图1.编辑源文件adc 9 d. 工程中,然后在example1_2.10 所示的内容。 c的编辑区输入如图1. 图1.编辑源文件expe_2. 10 ml1c (4)分别编译ac和eampe_2. dd.xl1c dd.xample12. 让ac和ec的编辑区处于活动状态,然后分别编译它们。如果没有语法错误,将产生名字 为add.obj和eampe1_oj的目标文件;如果有语法错误,编译器将提示有关错误,这时必须修改错误再 xl2.(_) b 重新编译。 (5)链接 单击“组建”菜单,选择“组建(链接)”命令,对目标文件和所用的库函数进行链接,生成可执行文件。 (6)运行 +6.roect1_2. 链接成功后,在VC+0开发界面上单击“组建”菜单,选择“执行”命令,运行可执行文件pj 9 exe( 也可以到C:rgrrjet1_eug目录下双击pojc1_2.xe运行C程序), 运行结果如 11 所示。 \C_poam\poc2\Dbrete 图1. 创建具有多个源文件的工程的步骤如图1. 12 所示。 图1.程序运行结 果 图1.有多个源文件的工程的创建步骤 11 12 注 一个工程里,需要有一个源文件含有main() 函数(相关细节将在第6章中讨论)。 小结 .C语言不仅是学习其他计算机课程的基础,而且本身也是很强大的一门编程语言,有着自己独特的 语言特性,尤其在嵌入式领域有着很重要的应用地位。 .本章中读者只需大致了解C程序的基本结构,重点掌握开发C程序的基本步骤:编写源文件、编译 源文件、链接目标文件、运行可执行文件。 . +6.+6.+6. 学会配置VC+0,熟练使用VC+0创建工程、向工程添加源文件,以及使用VC+0进行编 译、链接等操作。 习题 1 1. 判断题(题目叙述正确的,在后面的括号里打√,否则打×) (1)C语言的发明人是DennisRitchie和KenThompson。( ) (2)C语言是非常适合用于编写操作硬件设备的编程语言。() (3)C语言的源文件是扩展名为. c的源文件。 () c的文本文件。 (4)操作系统可以直接运行扩展名是 . () (5)编译器将C语言的源文件编译成扩展名是.e的可执行文件 。 () ex (6)编译器将C语言的源文件编译成扩展名是. b () ( oj的目标文件。 7)链接器将目标文件、库函数进行链接,并加入操作系统的启动代码产生一个可执行文件。() (8)一个C程序(工程)必须有且仅有一个main() 函数,操作系统从main() 函数开始执行C程序。 () (9)一个C程序(工程)中可以有多个源文件 。 () (10)编译器得到的目标文件是可执行文件 。 () 2. 单项选择题 (1)下列选项中叙述正确的是( )。 10 A.一个C程序(工程)由若干个函数构成,这些函数必须在同一个源文件中 B.一个C程序(工程)由若干个函数构成,这些函数可以在一个源文件中,也可以分布在若干个源 文件中,其中必须有一个源文件含有main()函数 C.一个C程序(工程)的源文件必须含有main()函数 D.一个C程序(工程)中可以有多个main()函数 (2)编译器编译源文件得到的目标文件的扩展名是( )。 A..obj B..cpp C..exe D..dsw (3)连接器得到的可执行文件的扩展名是( )。 A..obj B..dsp C..bat D..exe (4)下列选项中叙述错误的是( )。 A.一个C程序(工程)中可以有多个源文件 B.C语言的发明人是BillGates C.编译器将C语言的源文件编译成扩展名是.obj的目标文件 D.C语言的源文件是扩展名为.c的文本文件 (5)下列选项中叙述正确的是( )。 A.操作系统可以直接运行扩展名是.c的文件 B.操作系统可以直接运行扩展名是.obj的文件 C.操作系统可以直接运行扩展名是.exe的文件 D.操作系统可以直接运行扩展名是.txt的文件 3.阅读程序 (1)写出下列main()函数中【代码1】、【代码2】的输出结果。 #include int main() { printf("how are you"); //【代码1】 printf("你好"); //【代码2】 system("pause"); return 0; } (2)写出下列main()函数中【代码1】、【代码2】的输出结果。 #include int sub(int x,int y){ return x-y; } int main(){ int result =0; result =sub(100,2); printf("%d",result); //【代码1】 result =sub(7,2); printf("%d",result); //【代码2】 system("pause"); return 0; }