• 第3章 C++中的C
    • 3.1 创建函数">3.1 创建函数
      • 3.1.1 函数的返回值">3.1.1 函数的返回值

    第3章 C++中的C

    因为C++是以C为基础的,所以要用C++编程就必须熟悉C的语法,就像要解决微积分问题必须要对代数十分了解一样。

    如果读者以前从没有接触过C,本章将会提供在C++中使用C风格的一个很好的背景知识。如果读者对Kernighan&Ritchie所著的C语言书(经常称之为K&R C)第1版中描述的C风格比较熟悉的话,就会发现在C++以及在标准C中有一些新的、不一样的特征。如果读者对标准C熟悉的话,则应当通览本章找出C++中与众不同的特点。注意这里介绍的是C++的一些基本特征,这些特征和C的特征很相似或者是对C进行的一些修改。C++的更为复杂的特征将会在后面各章中介绍。

    本章结合读者对其他语言编程的经验,对C的构造和C++的一些基本结构作了简要介绍。更为详细的介绍参见本书的附带光盘,“Thinking in C:Foundations for Java&C++”(Chuck Allison著,MindView公司出版,也可以在www.MindView.net上得到)。这是一个在光盘上的讲座,其目的是让读者仔细地浏览C语言的基础知识。它着重于从C转向使用C++或Java语言所必需的知识,而不是试图让读者成为懂得C的所有细节的专家(使用C++或Java这样的高级语言的一个原因正是由于它们可以避免涉及许多这样的细节)。它也包括练习和解答指南。记住,光盘的内容不能代替本章,而只能作为本章和本书的准备知识,因为本章超出了这张光盘所包含的内容。

    3.1 创建函数

    在旧版本(标准化之前)的C中,我们可以用带任意个数和类型的参数调用函数,编译器都不会报告出错。运行程序之前每一件事情似乎都很好,但当运行时,我们却会得到一些奇怪的结果(更糟的是程序崩溃),并且没有说明为什么会这样的任何提示。缺乏对参数传递的协助以及会导致高深莫测的故障,可能是C被称为“高级汇编语言”的一个原因。在C标准化之前,程序员只能去适应这种情况。

    标准C和C++有一个特征叫做函数原型(function prototyping)。用函数原型,在声明和定义一个函数时,必须使用参数类型描述。这种描述就是“原型”。调用函数时,编译器使用原型确保正确传递参数并且正确地处理返回值。如果调用函数时程序员出错了,编译器就会捕获这个错误。

    实际上,在前一章中已经学习了函数原型(但并没有这样命名),因为在C++中函数声明的形式需要正确的原型。在函数原型中,参数表包含了应当传递给函数的参数类型和参数的标识符(对声明而言可以是任选的)。参数的顺序和类型必须在声明、定义和函数调用中相匹配。下面是一个声明函数原型的例子:

    第3章 C++中的C - 图1

    在函数原型中声明变量时,不能使用和定义一般变量同样的形式。就是说不能用float x, y,z。必须指明每一个参数的类型。在函数声明中,下面的形式是可以接受的:

    第3章 C++中的C - 图2

    因为在调用函数时,编译器只是检查类型,所以使用标识符只是为了使别人阅读代码时更加清晰。

    在函数定义中,因为参数是在函数内部引用的,所以需要命名。

    第3章 C++中的C - 图3

    这条规则只应用于C。在C++中,函数定义的参数表中可以使用未命名的参数。当然,因为它没有被命名,所以不能在函数体中使用它。允许不命名参数是为了给程序员提供在“参数列表中保留位置”的一种方式。不管谁调用函数都必须使用正确的参数。但是,创建函数的人将来可以使用这个参数,而不需要强制修改调用这个函数的代码。即使给出命名,在参数表中忽略这个参数也是可能的,但每次编译函数时,会得到这个值没有被使用这样一条令人讨厌的警告消息。如果删除这个名字,这个警告也会消除。

    C和C++有两种其他声明参数列表的方式。如果有一个空的参数列表,可以在C++中声明这个函数为func(),它告诉编译器,这里有0个参数。应该意识到这只意味着在C++中是空参数列表。在C中,它意味着不确定的参数数目(这是C中的漏洞,因为在这种情况下不能进行类型检查)。在C和C++中,声明func(void)都意味着空的参数列表。在这种情况下void这个关键词意味着“空”(在本章的后面将会看到,就指针而言它也可以表示“没有类型”)。

    在不知道会有多少个参数或什么样类型的参数时,参数表的另一种选择是可变的参数列表。这个“不确定参数列表”用省略号(……)表示。定义一个带可变参数列表的函数比定义一个带固定参数列表的函数要复杂得多。如果(因为某种原因)不想使用函数原型的错误检查功能,可以对有固定参数表的函数使用可变参数列表。正因为如此,应该限制对C使用可变参数列表并且在C++中避免使用(正如我们将会看到的,在C++中有更好的选择)。在你的C指南的库部分对使用可变参数列表做了描述。

    3.1.1 函数的返回值

    C++函数原型必须指明函数的返回值类型(在C中,如果省略返回值,表示默认为整型)。返回值的类型放在函数名的前面。为了表明没有返回值可以使用void关键字。如果这时试图从函数返回一个值会产生错误。下面有一些完整的函数原型:

    第3章 C++中的C - 图4

    要从一个函数返回值,我们必须使用return语句。return语句退出函数返回到函数调用后的那一点。如果return有参数,那个参数就是函数的返回值。如果函数规定返回一个特定类型的值,那么每一个return语句都必须返回这个类型。在一个函数定义中可以有多个return语句。

    第3章 C++中的C - 图5

    第3章 C++中的C - 图6

    在函数cfunc()中,第一个值为真的if语句,通过return语句退出函数。注意函数声明不是必须的,因为函数在main()使用它之前定义,所以编译器从函数定义中知道它。