您的位置:首页 > 编程语言 > C语言/C++

C++ primer 读书笔记系列——(4)函数

2010-08-31 21:06 204 查看
可能是以前用了45天时间没昼没夜的玩了一趟MFC,敲了2万行代码。现在一看到VC IDE就有点厌烦的感觉,再一想到敲代码。。。。。真的连打开VC的兴趣都没了。晚上洗了个澡,逼着自己往进看,但看着看着还真认真起来了,学习的兴趣也就上来了。 不多说了,直接开始笔记!

(一)函数的定义

函数必须制定返回类型。

在定义或声明函数时,没有显示指定返回类型是不合法的:

max(int a,int b)

{

......

}

早期的C++版本(如VC6)可以接受这样的程序,将会把函数的返回值隐式定义为int型,但在标准C++中,上述程序则是错误的。

(二)参数传递

函数形参的初始化与变量的初始化一样:如果形参为非引用类型,则复制实参的值,如果为引用类型,则它只是实参的别名。

1.引用形参

事实上,从C语言转化为C++的程序员更习惯利用传递指针来实现对实参的访问。在c++中,使用引用形参更加安全和自然。

#include<iostream>

void swap(int v1,int v2)

{

int t=v1;

v1=v2;

v2=t;

}

int main()

{

int num1=1200;

int num2=2100;

swap(num1,num2);

return 0;

}

对于上述swap函数,它无法交换实参本身,而只是交换了实参在函数内部的局部副本。传递给swap的实参并没有被修改。

void swap(int &v1,int &v2)

{

int t=v1;

v1=v2;

v2=t;

}

与所有其它引用一样,引用形参直接关联到其所绑定的对象,而非这些对象的局部副本。上述函数能很好的达到交换实参的值。

2.引用形参的作用

a.与指针形参类似,使用引用形参返回额外信息。

#include<iostream>

void max(int a,int b,int &imax)

{

imax=a>b?a:b;

}

int main()

{

int a=1200;

int b=2100;

int abmax;

std::cout<<max(a,b,abmax)<<std::endl;

return 0;

}

在上述max函数中,imax用来返回a,b中较大的值。

b.利用const引用避免复制。

在向函数传递大型对象时,利用非const引用效率非常低下,因为函数的形参均为局部副本。

bool isShorter(const string &s1,const string &s2)

{

return s1.size()<s2.size;

}

因为形参是引用,所以不复制实参,又因为形参是const类型的,所以不可改变实参的值。

事实上,如果使用引用形参的唯一目的是为了避免复制形参,则应该使用const引用形参。

3.传递指向指针的引用

#include<iostream>

void sswap(int *&a,int *&b)

{

int *c=a;
a=b;
b=c;

}

int main()

{

int a=1200;
int b=2100;
int *c=&a;
int *d=&b;

std::cout<<"交换前:"<<std::endl;

std::cout<<*c<<" "<<*d<<std::endl;

std::cout<<a<<" "<<b<<std::endl;
sswap(c,d);

std::cout<<"交换后"<<std::endl;
std::cout<<*c<<" "<<*d<<std::endl;

std::cout<<a<<" "<<b<<std::endl;

return 0;

}

此段代码输出的结果为:

交换前:

1200 2100

1200 2100

交换后:

2100 1200

1200 2100

可以看出并不是a和b的值交换了,而是指针c和d所指的对象交换了。未交换前,c指向a,d指向b,交换后,c指向b,d指向a。

4.主函数main()返回值

当主函数成功执行时,主函数返回0,若没写出显示返回值,则编译器会隐式的插入返回0的语句:return 0; 返回其它值则代表函数执行失败。

5.返回值为引用

const string &manip(const string &s)

{

string ret=s;

return ret;

}

这个函数会在运行时出错,因为它返回了局部对象ret,当函数执行结束时,局部对象ret所占用的内存已被释放。

同样的,不能返回指向局部对象的指针,否则函数执行完后,此指针已变成了未指向任何内存空间的悬垂指针。

6.static局部对象

一个函数如果位于函数的作用域内,但应用范围确超出了函数的界限,这种变量往往很有用,则应该将这种对象定义为static。

#include<iostream>

using std::cout;

using std::endl;

size_t cout_count()

{

static size_t strnum=0;

return strnum++;

}

int main()

{

for(size_t i=0;i<=10;i++)

cout<<cout_count()<<" ";

cout<<endl;

return 0;

}

代码运行结果为:

0 1 2 3 4 5 6 7 8 9 10

7.this 指针的引入

在类中的每个成员函数(除static成员函数)都有一个隐含的形参this,在调用成员函数时,this隐含为调用函数的对象的地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: