第二章 C语言基本概念
2.1 编写一个简单的 C 程序
2.1.2 集成开发环境
到目前为止,我们一直通过在操作系统提供的特殊窗口中键入命令的方式来调用“命令行”
编译器。事实上, 还可以使用集成开发环境(integrated development environment, IDE)进行编译。集成开发环境是一个软件包,我们可以在其中编辑、编译、链接、执行甚至调试程序。组成集成开发环境的各个部分可以协调工作。
2.2 简单程序的一般形式
即使是最简单的C程序也依赖3个关键的语言特性:指令(在编译前修改程序的编辑命令)、
函数(被命名的可执行代码块,如main函数)和语句(程序运行时执行的命令)。
2.2.1 指令
在编译C程序之前,预处理器会首先对其进行编辑。我们把预处理器执行的命令称为指令。
第14章和第15章会详细讨论指令,这里只关注#include指令。
程序 pun.c 由下列这行指令开始:
#include <stdio.h>
这条指令说明,在编译前把 <stdio.h> 中的信息“包含”到程序中。 <stdio.h> 包含了关于 C 标
准输入 / 输出库的信息。 C 语言拥有大量类似于 <stdio.h> 的 头 ( header )( 15.2 节),每个头都包含一些标准库的内容。 这段程序中包含<stdio.h>的原因是:C语言不同于其他的编程语言,它没有内置的“读”和“写”命令。输入/输出功能由标准库中的函数实现。
所有指令都是以字符 # 开始的。这个字符可以把 C 程序中的指令和其他代码区分开来。指令
默认只占一行,每条指令的结尾没有分号或其他特殊标记。
2.2.2 函数
函数类似于其他编程语言中的“过程”或“子例程”,它们是用来构建程序的构建块。事实上,C程序就是函数的集合。函数分为两大类:一类是程序员编写的函数,另一类则是作为 C 语 言实现的一部分提供的函数。我们把后者称为库函数 ( library function ),因为它们属于一个由编译器提供的函数“库”。
虽然一个C程序可以包含多个函数,但只有main函数是必须有的。main函数是非常特殊的:
在执行程序时系统会自动调用main函数。
main前面的int表明该函数将返回一个整数值。圆括号中的void表明main函数没有参数。
语句
return 0;
有两个作用:一是使 main 函数终止(从而结束程序),二是指出 main 函数的返回值是 0 。在后面我们还将详细论述main 函数的返回值( 9.5 节)。但是现在我们始终让main 函数的返回值为0 ,这个值表明程序正常终止。
如果 main 函数的末尾没有 return 语句,程序仍然能终止。但是,许多编译器会产生
一条警告信息(因为函数应该返回一个整数却没有这么做)。
2.2.3 语句
语句是程序运行时执行的命令。程序pun.c只用到两种语句。一种是返回(return)语句,另一种则是函数调用(functioncall)语句。要求某个函数执行分派给它的任务称为调用这个函数。C 语言规定每条语句都要以分号结尾。(就像任何好的规则一样,这条规则也有一个例外:
后面会遇到的复合语句( 5.2 节)就不以分号结尾。(就是用{}括起来,后面不用跟";"。)
2.4 变量和赋值
2.4.1 类型
每一个变量都必须有一个类型(type)。类型用来说明变量所存储的数据的种类。
float (即 floating-point 的简写)型变量可以存储比 int 型变量大得多的数值。而且,float型变量可以存储带小数位的数,如379.125。但float型变量也有一些缺陷。进行算术 运算时float 型变量通常比 int 型变量慢;更重要的是, float 型变量所存储的数值往往只是实际数值的一个近似值。如果在一个float 型变量中存储 0.1 ,以后可能会发现变量的值为0.099 999 999 999 999 87,这是舍入造成的误差。
2.4.4 显示变量的值
%d仅用于int型变量。如果要显示float型变量,需要用%f来代替%d。默认情况下,%f会显示出小数点后 6 位数字。如果要强制 %f 显示小数点后 p 位数字,可以把 . p 放置在 % 和 f之间。例如,为了显示信息 Profit: $2150.48
可以把 printf 写为如下形式:
printf("Profit: $ % .2f\n", profit);
C语言没有限制调用一次printf可以显示的变量的数量。
2.4.5 初始化
当程序开始执行时,某些变量会被自动设置为零(static,全局变量),而大多数变量则不会( 18.5节)。没有默认值并且尚未在程序中被赋值的变量是未初始化的(uninitialized)。
我们当然可以总是采用赋值的方法给变量赋初始值,但还有更简便的方法:在变量声明中
加入初始值。例如,可以在一步操作中声明变量 height 并同时对其进行初始化:
int height = 8;
按照C语言的术语,数值8是一个初始化器(initializer)。
在同一个声明中可以对任意数量的变量进行初始化:
int height = 8, length = 12, width = 10;
注意,上述每个变量都有属于自己的初始化器。 在接下来的例子中,只有变量width拥有初始
化式 10 ,而变量 height 和变量 length 都没有(也就是说这两个变量仍然未初始化):
int height, length, width = 10;
2.5 读入输入
为了获取输入,就要用到scanf函数。它是 C 函数库中与 printf 相对应的函数。 scanf 中的
字母 f 和 printf 中的字母 f 含义相同,都是表示“格式化”的意思。 scanf 函数和 printf 函数都
需要使用 格式串 ( format string )来指定输入或输出数据的形式。 scanf 函数需要知道将获得的输入数据的格式,而printf 函数需要知道输出数据的显示格式。
scanf("%f", &x); /* reads a float value; stores into x */
%f 只用于 float 型变量,因此这里假设 x 是一个 float 型变量。字符串 "%f" 告诉 scanf 函数去寻
找一个 float 格式的输入值(此数可以含有小数点,但不是必须含有)
2.6 定义常量的名字
注意,宏的名字只用了大写字母。这是大多数C程序员遵循的规范,但并不是C语言本身的
要求。(至今,C程序员沿用此规范已经几十年了,希望读者不要打破此规范。)
2.7 标识符
在编写程序时,需要对变量、函数、宏和其他实体进行命名。这些名字称为 标识符 (identifier )。在 C 语言中,标识符可以含有字母、数字和下划线,但是必须以字母或者下划线开头。( 在C99中,标识符还可以使用某些“通用字符名”, 25.4 节。)
关键字