Visual C++ 2010 第5章 程序结构

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…

猜你喜欢

转载自blog.csdn.net/madao1234/article/details/85111533