函数

来源:互联网 发布:linux网络接口详解 编辑:程序博客网 时间:2024/05/22 04:36

在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。




形参与实参


        函数的形参类似于局部变量,为函数提供了已命名的局部存储空间。形参是在函数的形参表中定义的,并由调用函数时传递给函数的实参初始化。实参则是一个表达式,可以是变量或字面值常量,甚至是包含一个或几个操作符的表达式。




参数传递


        每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参。形参的初始化与变量的初始化一样:如果形参具有非引用类型,则复制实参的值;如果形参为引用类型,则它只是实参的别名。

        普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。

        与其它非引用类型的形参一样,指针形参的任何改变也仅作用于局部副本。如果函数将新指针值赋给形参,主调函数使用的实参指针的值没有改变。事实上被复制的指针只影响对指针的赋值。如果函数形参是非const类型的指针,则函数可通过指针实现赋值,修改指针所指向对象的值。


引用形参

  • 有时候,函数有不止单个内容需要返回,这是可使用引用形参返回额外的信息;
  • 在向函数传递大型对象或遇到某些无法复制的类类型时,使用引用参数可直接访问实参对象,无须进行复制;
  • (不需要修改的引用形参应定义为const引用,普通的非const引用形参在使用时不太灵活。这样的形参既不能用const对象初始化,也不能用字面值(literal)产生右值的表达式实参初始化。)
  • 指向指针的引用形参,其定义应从右至左理解。




可变参函数


C/C++中提供了三个宏定义,用于处理函数参数列表中的可变参数,在头文件stdarg.h中定义:

#define va_start _crt_va_start

#define va_arg _crt_va_arg

#define va_end _crt_va_end


上述三个宏定义的进一步实现在头文件vadefs.h中:

typedef char *  va_list;

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define _crt_va_end(ap)      ( ap = (va_list) 0 )


具体解释可参考下列博客,其中第一篇博客中有关va_start的理解好像有点错误,是取“最后一个非可变参数的地址”,而不是“第一个参数的地址”。

References:

http://www.cnblogs.com/justinzhang/archive/2011/09/29/2195969.html

http://www.cnblogs.com/cylee025/archive/2011/05/23/2054792.html





返回非引用类型


函数的返回值用于初始化调用函数处创建的临时对象(temporary object)。




局部对象


        在C++中,每个名字都有作用域,而每个对象都有生命期lifetime)。名字的作用域指的是知道该名字的程序文本区,对象的生命期则是在程序执行过程中对象存在的时间

        默认情况下,局部变量的生命期局限于所在函数的每次执行期间。只有当定义它的函数被调用时才存在的对象称为自动对象automatic object),自动对象在每次调用函数(结束)时创建(撤销),形参也是自动对象。

        一个变量如果位于函数的作用域内,但生命期却跨越了这个函数的多次调用,这种变量往往很有用,应该将其定义为静态的(static)。静态局部对象static local object)确保不迟于在程序第一次执行该对象的定义语句时进行初始化。这种对象一旦被创建,在定义它的函数结束时(或者说在程序结束前),都不会被撤销。在调用它的函数被多次调用的过程中,静态局部对象会持续存在并保持它的值。




内联函数


        内联说明(inline specification)对于编译器来说只是一个建议,编译器可以选择忽略这个建议。一般来说,内联机制适用于优化小的、只有几行的而且经常被调用的函数,大多数的编译器都不支持递归函数的内联。

        内联函数的定义对编译器而言必须是可见的,以便编译器能够在调用点内联展开该函数的代码,此时仅有函数原型是不够的。内联函数可能要在程序中定义不止一次,其定义在某个源文件中只出现一次,且在所有源文件中必须完全相同。所以不同于其它函数,内联函数应该在头文件中定义。PS:在头文件中加入或修改内联函数时,使用了该头文件的所有源文件都必须重新编译。

        编译器隐式地将在类内定义的成员函数当作内联函数。




指向函数的指针


        函数指针是指向函数而非指向对象的指针。在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针

        函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。将函数指针初始化为0,表示该指针不指向任何函数;指向不同函数类型的指针之间不存在转换。




Hunger:C++中函数可以嵌套调用,但是不可以嵌套定义

0 0
原创粉丝点击