30.c/c++程序员面试宝典-函数的定义
函数可以看作是由程序员来定义的操作,是划分程序的各个程序块,与内置操作符相同的是,每个函数都会实现一系列的计算,然后(大多数时候)生成一个计算结果。但与操作符不同的是,函数有自己的函数名,而且操作数没有数量限制。与操作符一样,函数可以重载,这意味着同样的函数名可以对应多个不同的函数。
面试题116 什么是函数****
分析:把相关的语句组合在一起,并且赋予相应的名称,然后用这种方法来给程序分块,这种形式的组合就称之为函数,函数有时候也被称为例程或者过程。
由程序员来编写完成指定任务的函数是用户自定义的函数。标准函数库是c++提供的可以在任何程序中使用的公共函数,而程序总是从main主函数开始启动的。
函数由函数名以及一组操作数类型唯一地表示。函数的操作数,也即形参,在一对圆括号中声明,形参与形参之间以逗号进行分隔。函数执行的运算在一个称为函数体的块语句中定义。每一个函数都必须有一个相关联的返回类型,定义或者声明函数时,没有显示指定函数的返回类型是不合法的。一个简单函数的示例代码如下:
int gcd(int v1, int v2) //定义函数名,形参列表
{
while(v2)
{
int temp=v2;
v2=v1%v2; //求最大公约数
v1=temp;
}
return v1;
}
这个例子定义了一个求两个整型变量的最大公约数的函数,定义了一个名为gcd的函数,该函数返回一个int型值,并带有两个int型形参。调用gcd函数时,必须提供两个int型值传递给函数。然后将得到一个int型的返回值。
另外,函数体是一个语句块,定义了函数的具体操作。通常,这个块语句使包含在一对花括号中的,形成了一个新的作用域。和其他的块语句一样,在函数体中可以定义变量。在函数体中定义的变量只在该函数中才可以访问。这种变量称为局部变量,它们相对于定义它们的函数而言是局部的,变量名只能在该函数的作用域中可见。这种变量只在函数运行时存在。
【答案】函数由函数名、参数、返回值类型以及一组包含操作语句的语句块组成。函数可以支持重载,程序就是由函数组成的。
面试题117 形参与实参有什么区别****
分析:形参是函数定义时在形参表中定义的,并且由调用函数时传递函数的实参所初始化。形参为函数提供了已经命名的局部存储空间。
函数形参表可以为空,但不能省略。没有任何形参的函数可以用空形参表或含有单个关键字void的形参表来表示。示例代码如下:
void process() //空形参表
{... ...}
void process(void) //单个关键字void
{... ...}
形参表由一系列用逗号隔开的参数类型和(可选的)参数名组成。如果两个参数具有相同的类型,则其类型必须重复声明:
int manip(int v1,v2) //错误
{... ...}
int manip(int v1,int v2) //正确
{... ...}
实参是一个表达式。它可以是变量或字面值常量,甚至是包含一个或几个操作符的表达式。在调用函数时,所传递的实参个数必须与函数的形参个数完全相同。与初始化式的类型必须与初始化对象的类型匹配一样,实参的类型也必须与其对应形参的类型完全匹配,即实参必须具有与形参类型相同,或者能隐式转换为形参类型的数据类型。
【答案】形参是函数定义或声明时的函数形式参数,形参表制定了函数参数的个数和数据类型,实参是函数调用时传递给函数的参数,传递时要与形参一一对应。
分析:c++是可以支持函数参数个数不确定的,当不知道有多少个参数或类型只知道其中的一个或几个,那么可以用隐藏参数···代替,不知道的就用···代替,调用只需要处理所知道的参数。
使用隐藏参数支持个数不确定的参数示例代码如下:
int max(int num,...)
{
int m=-0x7FFFFFFF; //32系统中最小的整数
va_list ap;
va_start(ap,num);
for(int i=0;i<num;i++)
{
int t=va_arg(ap,int);
if(t>n)
{m=t;}
}
va_end(ap);
return m;
}
int main(int argc,char* argv[])
{
int n=max(5,5,6,3,8,5); //求5个数中的最大值
cout<<n;
return 0;
}
在上面代码中,函数max中首先定义了可变参数表指针ap,而后通过va_start(ap,num)取得了参数表首地址(赋给ap),其后的for循环则用来遍历可变参数表。这种遍历方式与编程者在数据结构教材中经常看到的遍历方式是类似的。
【答案】c++可以通过隐藏参数机制来支持参数个数不确定的函数。
面试题119 什么是内联函数***
分析:在类声明的内部声明或定义的成员函数叫做内联函数。引入内联函数的目的是为了解决程序中函数调用的效率问题。一般来说,内联机制适用于优化小的、只有几行的而且经常被调用的函数。
内联函数的定义示例代码如下:
(1)在类声明的内部声明,在类声明外部定义的叫做显示内联函数,代码如下:
class display
{
int i;
public:
void output(void) //在类的内部声明
};
display object;
inline void display::output(void) //在类外面定义的显示内联函数
{
cout<<"i is"<<i<<endl;
}
(2)在类声明的内部定义,叫做隐式内联函数。代码如下:
class display
{
int t;
public:
inline void output(void) //隐式内联函数
{
cout<<"i is"<<i<<endl;
}
}
注意:在内联函数内不允许用循环语句和开关语句。如果内联函数有这些语句,则编译器将该函数视同普通函数那样产生函数调用代码,递归函数是不能被用来做内联函数的。内联函数只适合用于只有1~5行的小函数。对一个含有许多语句的大函数,函数调用和返回的开销相对来说微不足道,所以也没必要用内联函数实现。内联函数的定义必须出现在内联函数第一次被调用之前。本例讲到的类结构中所有在类说明内部定义的函数都是内联函数。
【答案】在类声明的内部声明或定义的成员函数叫做内联函数。