c++primer之函数(函数基础和参数传递)

来源:互联网 发布:编程证明哥德巴赫猜想 编辑:程序博客网 时间:2024/05/16 04:58

1、函数基础

  • 一个典型的函数包括:返回类型(return
    type)、函数名字、由0个或多个形参组成的列表以及函数体。其中形参列表位于一对括号内,以逗号隔开。

形参和实参

  • 实参是形参的初始值。实参初始化形参要一一对应,并且类型也需要匹配。

函数的返回值

  • 大多数类型都能够用作函数的返回类型,一种特殊的返回类型是void,它表示函数不返回任何值。函数的返回类型不能是数组类型或函数类型。
    但是可以是指向数组或者函数的指针。

局部静态对象

  • 局部静态对象在程序执行第一次经过对象定义语句时初始化,之后再次进入到这个函数将不再进行初始化,并且还是保留着上一次退出时的值。可以将局部变量定义成static类型来获取这样的对象。
 - 例: - // 这个程序输出从1到10的数字 size_t count_calls() {     static size_t ctr = 0;     return ++ctr; } int main() {     for(size_t i=0; i!=10; ++i)        cout << count_calls() <<endl;     return 0; }

函数声明

  • 函数的名字必须在使用之前声明,类似于变量,函数只能定义一次,但是可以声明多次。
  • 因为函数的声明不包含函数体,所以也就无须形参的名字。

2、参数传递

  • 形参的类型决定了形参和实参的交互方式。如果实参是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝后赋给形参。

传值参数

  • 当初始化一个非引用类型的变量时,初始值被拷贝给变量。此时,对变量的改动不会影响初始值。
 - 例: int n = 0;  //int类型的初始变量 int i = n;  //i是n的值的副本 i =42;      //i的值改变;n的值不变

传值参数的机理完全一样,函数对形参做的所有操作都不会影响实参

指针形参

  • 指针的行为和其他非引用类型一样。当执行指针拷贝操作时,拷贝的指针的值。拷贝之后,两个指针时不同的指针。因为指针使我们可以间接地访问它所指的对象,所以通过指针可以修改它所指对象的值。
 - 例: int n = 0, i = 42; int *p = &n, *q = &i;  //p指向你,q指向i *p = 42;   // n的值改变;p的值不变  p = q;   // p现在指向了i; 但是i和n的值都不变

指针形参的行为与之类似:

// 该函数接受一个指针,然后将指针所指的值置为0void reset(int *ip){    *ip = 0;  //改变指针ip所指对象的值    ip = 0;   //只改变了ip的局部拷贝,实参未被改变}调用reset函数之后,实参所指的对象被置为0,但是实参本身并没有改变:int i = 42;reset(&i);    //改变i的值而非i的地址cout << "i = " << i << endl;  // 输出 i = 0

传引用参数

例:int n = 0, i = 42;int &r = n;  // r绑定了n(即r是n的另一个名字)r = 42;  // 现在n的值是42r = i;  // 现在n的值和i的值相同 i = r;   // i的值和n的值相同
例:void reset(int &i){    i = 0;  // 改变了i所引用对象的值}int j = 42;reset(j);    //j采用引用方式,它的值被改变cout << "j = " << j << endl;  // 输出 j = 0

const形参和实参

例: // 不良设计,第一个形参的函数应该是 const string& string::size_type find_char(string &s, char c, string::size_type &occurs);则只能将find_char函数作用于string对象,类似下面调用将引发错误。find_char("Hello World", 'o', ctr);修改方法可以是:string s = "Hello World";find_char(s, '0', ctr);

数组形参

  • 因为数组是以指针的形式传递给函数的,所以一开始函数并不知道数组的确切尺寸,调用者应该为此提供一些额外的信息。
    管理指针形参有三种常用的技术。

使用标记指定数组的长度

例:void print(const char *p){    if(cp)   // 若cp不是一个空指针        while (*cp)   // 只要指针所指的字符不是空字符             cout << *cp++;   // 输出当前字符并将指针向前移动一个位置}//  这种方法适用于那些有明显结束标记且该标记不会与普通数据混淆。

使用标准库规范

  • 传递数组首元素和尾元素的指针
 - 例: void print(const int *beg, const int *end) {    //输出beg和end之间(不含end)的所有元素    while(beg != end)           cout << *beg++ <<endl; }int j[2] = {1,0};print(begin(j), end(j));

显式的传递一个表示数组大小的形参
- 专门定义一个表示数组大小的形参

- 例:- // 只有当函数确实要改变元素值的时候,才把形参定义成指向非常量的指针 void print(const int ia[], size_t size) {      for(size_t i=0; i!=size; ++i)      {           cout << ia[i] <<endl;      } }int j[] = {0,1};print(j,end(j)-begin(j));

数组引用形参

例:void print(int (&arr)[10]){     for(auto elem : arr)          cout << elem << endl;}
0 0
原创粉丝点击