5.1 理解函数
- 函数调用中实参与函数定义中指定的形参之间的关系
5.2.2 给函数传递指针实参
#include <iostream>
using std::cout;
using std::endl;
int incr10(int* num);
int main()
{
int num(3);
int* pnum(&num);
cout<< endl << "Adress passed = " << pnum ;
int result = incr10(pnum); //指针作为实参传递
cout<< endl << "num = "<< num << endl;
return 0;
}
int incr10(int* num)
{
cout << endl << "Adress received = " << num;
*num += 10;
return *num;
}
5.2.4 给函数传递引用实参
#include <iostream>
using std::cout;
using std::endl;
int incr10(int& num);// lvalue 表示一个内存位置
int main()
{
int num(3);
int value(6);
int result = incr10(num);
cout << endl <<"incr10(num)= "<< result
<< endl << "num = " << num;
result = incr10(value);
cout << endl <<"incr10(value)= "<< result
<< endl << "value = " << value;
return 0;
}
int incr10(int& num)
{
cout << endl << "Value received = " << num;
num += 10;
return num;
}
// 实参的值并没有传递给函数。函数的形参初始化为实参的地址,因此
// 函数中只要使用形参num,就将直接访问调用函数中的实参。
可以给函数的形参使用const 修饰符,以告诉编译器不想以任何方式修改这个形参。
int incr10(const int &num);
5.2.7 main()函数的实参
int main(int argc,char* argv[ ]
{// code for main ...}
// 第1个参数:包括程序名在内的命令行上出现的字符串的数量计数;
// 第2个参数:是个数组,包含指向这些字符串的指针,还有一位空值的附加元素
5.2.8 接受数量不定的函数实参
- 将函数定义成能够接受任意数量的实参:通过将省略号(…)写在函数定义中形参列表的最后,即可表示调用该函数时可以提供数量可变的实参。
int sumValues(int first,...)
{// code for the function...}
// 函数定义中至少有一个普通形参;
// ... 必须放在形参裂变的最后
#include <iostream>
#include <cstdarg> //va_list类型在此头文件中定义
using std::cout;
using std::endl;
int sum(int count,...)
{
if(count <= 0)
return 0;
va_list arg_ptr; //声明一个va_list类型的指针,用来依次指向各个实参
va_start(arg_ptr,count); //va_start宏用来初始化arg_ptr,使其指向列表中的第一个实参
int sum(0);
// for循环用来检索列表中各个实参的值
for(int i = 0;i < count ; i++)
sum += va_arg(arg_ptr,int);
// va_arg宏返回arg_ptr 指向的位置存储的实参值,并使arg_ptr递增,指向下一个实参值。
// 第2个参数:是第1个实参的类型,决定着得到的值和arg_ptr递增方式。
va_end(arg_ptr);
// va_end宏将传递给它的实参(va_list类型的指针)重置成空值
return sum;
}
int main(int argc,char*argv[])
{
cout << sum(6,2,4,6,8,10,12) << endl;
cout << sum(9,11,22,33,44,55,66,77,66,99) <<endl;
return 0;
}
5.3 从函数返回值
5.3.1 返回指针
- 返回地址的规则:永远不要从函数中返回局部自动变量的地址。
因为函数中的局部变量,在函数开始执行时创建,在函数退出时销毁。因此指针指向的内存不再包含原来的变量值。
#include <iostream>
using std::cout;
using std::endl;
double* treble(double data);
int main(void)
{
double num(5.0);
double* ptr(nullptr);
ptr = treble(num);
cout<< endl << "Three times num = " << 3.0*num;
cout << endl << "Result = "<< *ptr;
delete ptr; //不再使用treble()函数返回的指针时,立即释放内存
ptr = 0;
cout << endl;
return 0;
}
double* treble(double data)
{
double* result(new double(0.0));
//使用new 在空闲存储器中创建一个变量,该变量一直存在,直到最终被delete销毁,或程序结束
*result = 3.0*data;
return result;
}
5.3.2 返回引用
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::setw;
double & lowest(double values[],int length);
//返回值double&类型 即 double的引用类型
//第1个参数:double类型的一维数组;第2个参数:int类型的形参用来指定数组的长度
int main()
{
double array[] ={3.0,10.0,1.5,15.0,2.7,23.0,
4.5,12.0,6.8,13.5,2.1,14.0};
int len(sizeof array/sizeof array[0]); //初始化成该数组的长度
cout<<endl;
for(int i = 0; i < len; i++)
cout<< setw(6) << array[i];
lowest(array,len) = 6.9; //在赋值语句的左边使用函数
lowest(array,len) = 7.9;
cout<<endl;
for(int i = 0; i < len; i++)
cout<< setw(6) << array[i];
cout<< endl;
return 0;
}
double & lowest(double a[],int len)
{
int j(0);
for(int i=1; i<len; i++)
if(a[j]>a[i])
j=i; //j包含对应于具有最小值的那个数组元素的索引值
return a[j]; //返回数组元素a[j]的引用,a[j]的地址用来初始化将被返回的引用
}
5.3.3 函数中的静态变量
-
static int count(0);
函数内静态变量的初始化仅仅发生在第一次调用该函数的时候。
5.4 递归函数调用
- 当函数包含对自身的调用时,称之为递归函数。
#include <iostream>
using std::cout;
using std::endl;
double power(double x,int n);
int main(void)
{
double x(2.0);
double result(0.0);
for(int index = -3; index<=3 ; index++)
cout<< x << "to the power "<<index << " is "<<power(x,index) <<endl;
return 0;
}
double power(double x,int n) //x的整数和负数次幂
{
if(n<0)
{
x = 1.0/x;
n = -n;
}
if(n>0)
return x*power(x,n-1); //判断是否再次调用自身
else
return 1.0;
}
5.5 C++/CLI编程
- CLR程序中函数的形参和返回值可以是值类类型、跟踪句柄、跟踪引用、内布指针。
- 当某个形参是数组时,不需要另一个单独的形参来指定该数组的大小,因为C++/CLI数组的大小存储在Length属性中。
- 在C++/CLI 程序中,不能像在本地C++程序中那样对数组形参执行地址算术,因此必须使用数组索引。
- 返回在CLR堆上分配的内存的句柄并不是问题,因为垃圾回收器负责释放那些不再使用的内存。
- C++/CLI 中接收数量可变实参的机制与本地C++程序的机制不同。
- 在C++/CLI 程序中,main()函数访问命令行实参的机制与本地C++不同。
5.5.1 接受数量可变实参的函数
- C++/CLI 语言允许将形参列表指定为数组,数组说明前面加上省略号,从而提供数量可变的实参。
int sum (… array< int >^ args)
{
//code for sum
}
sum()函数可接受任意数量的int 类型实参。
#include "stdafx.h"
using namespace System;
double sum(... array<double>^ args)
{
double sum(0.0);
for each(double arg in args)
sum += arg;
return sum;
}
int main(array<System::String ^> ^args)
{
Console::WriteLine(sum(2.0,4.0,6.0,8.0,10.0,12.0));
Console::WriteLine(sum(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9));
Console::ReadLine();
return 0;
}
//输出
42
49.5
5.5.2 main()函数的实参
- 在C++/CLI 程序中main()函数只有一个形参,它是元素类型为String^的数组。故在C++/CLI 程序中访问并处理命令行实参简化为只访问该数组中的元素。
#include "stdafx.h"
using namespace System;
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"There were {0} command line arguments.",args->Length);
Console::WriteLine(L"Command line arguments received are: ");
int i(1);
for each(String^ str in args)
Console::WriteLine(L"Argument {0}: {1}",i++,str);
Console::ReadLine();
return 0;
}
5.8 本章主要内容
To be continue…