1.函数的定义
函数的调用
请参看以下程序:
#include <iostream>
using namespace std;
//return the GCD(greater common divisor)
int gcd(int v1, int v2)
{
while(v2)
{
int temp = v2;
v2 = v1 % v2;
v1 = temp;
}
return v1;
}
int main()
{
int a, b;
cin>>a>>b;
cout<<gcd(a,b)<<endl;
}
上述程序实现了求两数最大公约数的功能。
C++需使用调用操作符来实现函数的调用,如上程序中的gcd(a,b)中的"("和")"符号。该运算返回的结果就是函数的返回值。
当我们在调用gcd()函数时,第一件事是创建v1和v2的int型变量,并将这两个变量初始化为调用gcd时传递的实参值。上例中,v1的初值为i,而v2则初始化为j的值。
1.形参和实参
形参为函数提供了已经命名的局部存储空间。它们之间的差别在于形参是在函数的形参表中定义的,并由调用函数时传递给函数的实参初始化。
实参是一个表达式,它可以是变量或者字面值常量,甚至是包含一个或者几个操作符的表达式。在调用函数时,所能传递的实参个数必须与函数的形参个数完全相同。实参的类型也要与其对应的形参的类型完全匹配
请注意:
1.实参必须要与形参类型相同;
2.实参或者可以与形参隐式转换。
2.函数返回类型
bool is_present(int *, int); //returns bool
int count(const string &, char); //returns int
Date &calnedar(const char*); //returns reference to Date
void process(); //process does not return a value
请注意:
1.函数不能返回另一个函数或者内置数组类型,但是可以返回指向函数的指针或者指向数组元素的指针的指针:
如:
//pointer to first element of the array
int *foo_bar()
{
/*...*/
}
2.函数必须指定返回类型(缺乏返回类型的函数将被假定为int型,仅限早期C++)。
3.函数形参表
如第一例中,gcd函数:
gcd("hello","world");//wrong argument type
gcd(24312);//too few arguments
gcd(12,1,1);//too many arguments
都是不合法的。
而如下代码:
gcd(3.1,6.2);
却是合法的。编译器会把它变为:
gcd(3,6);
2.参数传递
非引用形参
//return the GCD(greater common divisor)
int gcd(int v1, int v2)
{
while(v2)
{
int temp = v2;
v2 = v1 % v2;
v1 = temp;
}
return v1;
}
如上例中的v1和v2。如果如下调用:gcd(i,j);
i和j的值不受gcd内执行的赋值操作的影响。1.指针形参
#include <iostream>
using namespace std;
void reset(int *ip)
{
*ip = 0; // changes the value of the object to which ip points
ip = 0; // changes only the local value of ip; the argument is unchanged
}
int main()
{
int i = 42;
int *p(&i);
cout << "i: " << *p << '\n'; // prints i: 42
reset(p); // changes *p but not p
cout << "i: " << *p << endl; // ok: prints i: 0
}
上述程序实现了如下功能:
1.新建一个指针p,把它的值初始化为i的地址,即让p指向i;
2.输出p指针指向的地址的值;
3.reset函数的目的是,让p指针指向的地址的内容归零,并让p指空;
4.输出指空之后的p指针指向的地址的值。
复制实参的局限性
复制实参并不是在所有的情况下都适合,不适宜复制实参的情况包括:
• 当需要在函数中修改实参的值时。
• 当需要以大型对象作为实参传递时。对实际的应用而言,复制对象所付出的时间和存储空间代价往往过大。
• 当没有办法实现对象的复制时。
对于上述几种情况,有效的解决办法是将形参定义为引用或指针类型。
请再看以下程序:
#include <iostream>
using namespace std;
void swap(int v1, int v2)
{
int tmp = v2;
v2 = v1; // assigns new value to local copy of the argument
v1 = tmp;
} // local objects v1 and v2 no longer exist
int main()
{
int i = 10;
int j = 20;
cout << "Before swap():\ti: "
<< i << "\tj: " << j << endl;
swap(i, j);
cout << "After swap():\ti: "
<< i << "\tj: " << j << endl;
return 0;
}
它并没有实现交换两个量的值的目的,为什么呢?因为它在swap函数进行时,只是交换了形参的值,对实参并无影响。
要想实现如何操作?
请如下更改:
#include <iostream>
using namespace std;
void swap(int &v1, int &v2)
{
int tmp = v2;
v2 = v1;
v1 = tmp;
}
改变v1,v2的地址来实现交换。
ps,如下语句也可以交换。。。
#include <iostream>
using namespace std;
int main()
{
int i = 10;
int j = 20;
cout << "Before swap():\ti: "
<< i << "\tj: " << j << endl;
i ^= j ^= i ^= j;
cout << "After swap():\ti: "
<< i << "\tj: " << j << endl;
return 0;
}
2.使用引用形参返回额外的信息
#include <iostream>
#include <vector>
using namespace std;
// returns an iterator that refers to the first occurrence of value
// the reference parameter occurs contains a second return value
vector<int>::const_iterator find_val(
vector<int>::const_iterator beg, // first element
vector<int>::const_iterator end, // one past lastelement
int value, // the value we want
vector<int>::size_type &occurs) // number of times it occurs
{
// res_iter will hold first occurrence, if any
vector<int>::const_iterator res_iter = end;
occurs = 0; // set occurrence count parameter
for ( ; beg != end; ++beg)
if (*beg == value)
{
// remember first occurrence of value
if (res_iter == end)
{
res_iter = beg;
}
++occurs; // increment occurrence count
}
return res_iter; // count returned implicitly in occurs
}
int main()
{
vector<int> vec;
//input data
int n;
cin>>n;
while(n--)
{
int i;
cin>>i;
vec.push_back(i);
}
int a;
cin>>a;//the value you want to find
vector<int>::const_iterator it;
vector<int>::size_type occurence;
it = find_val(vec.begin(),vec.end(),a,occurence);
cout<<*it<<"\t"<<occurence<<endl;
}
说明:调用 find_val 时,需传递四个实参:一对标志 vector 对象中要搜索的元素范围的迭代器,所查找的值,以及用于存储出现次数的size_type 类型对象。
如果出现了:
1.it返回的值是其第一次出现的数组位置
2.occurence的值是出现次数。
3.使用 const 指针避免复制操作
// compare the length of two strings
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}