C语言多个函数

到目前为止,这些程序只使用了标准的printf()函数。程序清单说明除了main()函数之外,怎样把您自己的函数加入到程序中。

程序清单two_func.c程序


/*two_func.c--在一个文件中使用两个函数*/

#include<stdio.h>

void butler(void); /*ISO/ANST C函数原型*/

int main(void)

{

printf("I will summon the butler function.\n");

butler();

printf("yes.Bring me some tea and writeable CD-ROMS.\n");

return 0;

}

void butler(void) /*函数定义的开始*/

{

printf("you rang, sir?\n");

}

输出应像下面这样:

输出应像下面这样


butler()函数在程序中出现了3次。第一次出现在原型中,通知编译器要用到的该函数。第二次是在main()函数中以函数调用的形式出现的。最后,程序给出了函数的定义,即函数本身的源代码。让我们依次看一下它在程序中的第一次出现。

C90标准添加了原型,以前的编译器可能并不认识它们(稍后我们将告诉您使用这种编译器时应该怎样做)。原型是一种声明的形式,用于告诉编译器您正在用一个特殊的函数。它也指明了函数的属性。例如butler()函数原型的第一个void说明bulter()不返回值(通常,一个函数可以给调用它的函数返回一个值以供使用,但是butler()函数不返回值)。第二个void,也就是butler(void)中的void,意思是butler()函数没有参数。因此,当编译到达main()函数中butler()的调用处时会检查butler()的使用是否正确。注意void的意思是“空的”,而不是“无效的”。

void butler();

早期的C代码使用的函数声明就像前面这个一样,而不是使用函数原型。C90和C99标准可识别这种旧版本的形式,但它会逐渐被淘汰,所以不要用这种形式。如果您沿用以前的C代码,您需要把旧形式的声明转换成原型。本书以后的章节中会继续介绍原型。如果您沿用以前的C代码,您需要把旧形式的声明转换成原型。本书以后的章节中会继续介绍原型、函数的下一个语句。

内容略

调试

现在您已经可以编写一个简单的C语言程序了,但是您可能会犯一些简单的错误。程序的错误通常叫做bugs,而发现和修正这些错误的过程叫做调试(debugging)。程序清单2.4出了一个带有一些错误的程序,看看您能找出多少。

程序清单2.4 nogood.c程序


/*nogood.c--含有错误的程序*/

#include<stdio.h>

int main (void)

(

int n, int n2, int n3;

/*该程序含有几个错误

n = 5;

n2 = n * n;

n3 = n2 * n2;

printf("n = %d, n squared = %d\n", n, n2, n3)

return 0 ;

)


语法错误

程序清单2.4包含了几个语法错误。如果您不遵循C语言规则就会犯语法错误。它类似于英语中的语法错误。

程序nogood.c中到底出现了什么错误呢?首先,它使用圆括号而不是花括号来包围函数体,这是正确的C符号用错了位置的情况。第二,声明应该采用以下形式:

int n, n2, n3:

或者采用以下形式:

int n;

int n2;

int n3;

第三,示例程序中忽略了必须用一个*/符号来结束注释(当然也可以用新形式//来替代/*)。最后,程序漏掉了结束printf()语句所必需的分号。

如何检测程序的语法错误?首先,在编译前浏览程序的源代码看看是否有明显的错误。其次。可以查看由编译器发现的错误,因为它的工作之一就是检测语法错误。在编译器报告所找到的任何错误,同时指出每一个错误的性质和位置。

然而编译器也会发生错误。某位置上一个真正的语法错误可能导致编译器误认为它发现了其他错误。

语义错误

语义错误

语义错误就是在意思上的错误。例如,考虑下面的句子:Furry inflation thinks greenly。句子中形容词、名词、动词和副词的位置都很正确,所以语法没有错,但是句子却什么意思也没表达出来。在C中,当您正确遵循了C语言的规则,但是结果不正确的时候,那就是犯了语义错误。示例程序中有这样一个错误:

n3=n2*n2;

此处,原本是希望n3代表n的三次方,但是代码把它设置成了n的四次方。

这样的语义错误编译器是检测不到的,因为它并没有违反C语言的规则。编译器无法了解您的真正意图,只好留给您自己去找出这类错误。方法之一是比较程序实际得到的结果和您预测的结果。例如,假设您已经修正了示例程序中的语法错误,现在程序应该程序清单2.5所示。

程序清单2.5 stillbad.c程序


/*stillbad.c--修正了语法错误的程序*/

#include <stdio.h>

int main (void)

{

int n, n2, n3;

/*该程序有语义错误*/

n = 5;

n2 = n * n;

n3 = n2 * n2;

printf ("n = %d, n squared = %d, n cubed = %d\n", n, n2, n3);

return 0;

}

stillbad.c程序

如果您懂得立方的话,就会知道结果625是错误的。下一步要跟踪程序是如何得出这个答案的。对于本例,通过观察您 可能会发现其中的错误,但您需要采取更为系统的方法。方法之一就是把自己想像成计算机,跟着程序的步骤一步一步地执行。现在让我们试一下这种方法。

程序体一开始是声明3个变量:n、 n2 和 n3。 您可以画3个盒子,并用3个变量的名称作为每个盒子的标签来模拟这种情况。

程序状态

通过手工方式一步一步报跟踪程序,并记录每个变量,这样就可以监视程序状态。

s

关键字和保留标识符

关键字是C语言中的词汇。因为它们对C来说比较特殊,所以您不能将它们用作标识符,例如作为变量名。许多关键字用于指定不同的类型,比如int。其他的关键字,比如if,用来控制程序中的语句的执行顺序。在表中所列的C语言关键字中,粗体显示的关键字是由ISO/ANSI C90标准新增的,斜体显示的关键字是由C99标准新增的。

C语言的关键字列表


ISO/ANSIC关键字

auto enum restrict unsigned
break extern return void
case float short volatile
char for short volatitle
const goto sizeof _Bool
continue if static _Imaginary
do int switch
double long typedef
else register union

如果试图把一个关键字用作变量名,编译器把它作为一个语法错误捕获到。还有一些您不该用的其他字符,称为保留标识符(reserved identifier)。因为它们是合法的名字,所以并不引起语法错误。然而,C语言已使用它们或者保留使用它们的权利,所以如果您用这些标识符表示其他意思就可能引起问题。保留标识符包括那些以下划线字符开始的标识符和标准库函数的名字,例如printf()。

关键概念

计算机编程是一件富有挑战性的事情。它需要抽象的、概念性的思考并细致地对待细节问题。您会发现编译器强迫您注意细节问题。当您跟朋友谈话时,您可以用错几个字,犯一两个语法错误,可能还有几个没有结束的句子,但朋友能明白您 想说什么。而编译器却不允许这样做;对编译器来说,几乎正确仍然等于错误。

总结

C语言程序是由一个或者多个函数组成的。每一个C程序都必须包含一个名为 main()的函数,因为当程序开始时要调用该函数。一个简单的函数结构如下:函数头后面紧跟着一个开始花括号,后面是构成函数体的语句,然后是起终止作用的结束花括号。

每个C语句都是一个针对计算机的指令,并以一个分号作为结束标志。声明语句为变量指定一个名字并指明该变量中存储的数据类型。变量名是标识符的例子。赋值语句把值赋给变量,或者更一般地说,是把值赋给存储区域。函数调用语句会导致所指定函数的执行。当被调用执行完毕之后,程序会返回到函数调用之后的语句继续进行。

printf()函数用于输出语句和变量的值。

一门语言的语法是一套规则,用于管理这种语言中的合法语句组织在一起的方式。语句的语义就是它所表达的意思。编译器可以帮助您发现语法上的错误,但是程序里的语义错误只有在编译完之后才能从程序的行为中表现出来。检测语义错误可能包括跟踪程序的状态,即程序每执行一步之后所有变量的值。

关键字是C语言的词汇。

访问 生活导航

在本例中,我们改变超链接的文本和 URL。我们也改变 target 属性。target 属性的默认设置是 "_self",这意味着会在相同的窗口中打开链接。通过把 target 属性设置为 "_blank",链接将在新窗口中打开。