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隐含为调用函数的对象的地址。
(一)函数的定义
函数必须制定返回类型。
在定义或声明函数时,没有显示指定返回类型是不合法的:
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隐含为调用函数的对象的地址。
相关文章推荐
- 读书笔记:C++ Primer系列(14)—— C++函数及参数传递
- 读书笔记——Windows核心编程(8)Interlocked系列函数
- C++ primer 读书笔记(第6章)函数
- 读书笔记:C++ Primer系列(13)—— break、continue、goto语句
- C++ primer 读书笔记 第七章 --函数
- C++ Primer 读书笔记——函数
- C++ primer 读书笔记系列——(1)标准库string类型
- C++ primer 读书笔记系列——(8)类和数据抽象
- 读书笔记:C++ Primer系列(3)—— 关于变量
- 读书笔记:C++ Primer系列(9)—— 数组与指针(1)
- 读书笔记:C++ Primer系列(5)—— 标准库类型之string
- 读书笔记:C++ Primer系列(8)—— 标准库类型之bitset
- 《C++ Primer》读书笔记-第六章 04 函数重载
- C++ primer 读书笔记系列——(7)关联容器
- 《C++ Primer》读书笔记第六章-3-特殊特性 And 函数匹配 And 函数指针
- C++ primer 读书笔记系列——(2)标准库vector类型
- 读书笔记:C++ Primer系列(7)—— 标准库类型之iterator
- C++ primer 读书笔记系列——(3)C++中的数组和指针
- 《C++ Primer》读书笔记-第六章 01 函数基础
- C++ primer 读书笔记系列——(6)顺序容器