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

C++ primer(七)--函数、C++的编程模块 函数指针 函数指针数组 typedef

2013-10-07 15:22 519 查看
如何定义函数、给函数传递信息以及从函数那里获得信息。如何使用函数来处理数组、字符串和结构,最后介绍递归和函数指针。



一、函数的基础

对于有返回值的函数,必须使用返回语句,C++对于返回值的类型有一定的限制:不能是数组,可以是其他任何类型--甚至是结构体和对象!(虽说不能直接返回数组,但是可以将数组作为结构或对象组成部分来返回)。

在原型的参数列表中,可以包括变量名,也可以不包括。

二、按值传递

C++通常按值传递参数,这意味着将数值参数传递给函数,而后者将其赋给一个新的变量。

1)const和指针

声明一个指向常量的指针pt;

int age=39;

const int *pt=&age;

该声明指出,pt指向一个const int(这里是39),因此不能使用pt来修饰这个值。换句话说,*pt的值为const,不能被修改:

*pt+=1;// error

cin>>*pt;// error

pt的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对pt而言,这个值是常量。例如,pt指向age,而age不是const。可以直接通过age变量修改age的值,但不能使用pt指针来修改它:

*pt=20;//error

age=20;//no error

这种声明中的const只能防止修改pt指向的值(这里是39),而不能防止修改pt的值。也就是说,可以将一个新地址赋给pt:

int sage=80;

pt=&sage; //no error

但仍然不能使用pt来修改它指向的值(现在为80)。



这里将常规变量的地址赋给指向const的指针。因此还有两种可能:一个是将const变量的地址赋给指向const的指针、将const的地址赋给常规指针。第二种可行,第一种不可行。

const int gp=10;

const int *pe=&gp; // no error

const int gm=21;

int * pm=&gm; // error



对于这种情况来说,既不能使用gp来修改值10,也不能使用pe来修改。对于第二种情况,C++禁止将const的地址赋给非const指针。

假设有一个由const数据组成的数组:

const int months[];

对于函数定义:int sum(int arr[],int n);

int j=sum(months,12);//error 编译器不允许这样

三、函数指针

1)使用指针来调用函数

对于函数指针的声明和初始化在此省略:

double pam(int);

double (*pf)(int);

pf=pam;

double x=pam(4);

double y=(*pf)(5);

实际上,C++也允许像使用函数名那样使用pf:

double y=pf(5);

也就是说pf和(*pf)等价,也就是说对于函数指针来调用函数,可以通过两种方式来实现,一个是直接使用函数指针,也就是第二种方式;另一种就是使用函数指针来构造和函数名一样的那样来调用,也就是第一种方式。

2)深入探讨函数指针

这里主要讨论函数指针数组。比如三个函数:

const double * f1(const double ar[],int n);

[b]const double * f2(const double [],int );[/b]

[b]const double * f1(const double *,int );[/b]

[b] 如果有一个函数指针数组将很方便。这种声明类似于当个函数指针的声明,但必须在某个地方加上[3],以指出这是一个包含三个函数指针的数组:[/b]

[b] const double * (*pa[3])(const doble *,int)={f1,f2,f3};[/b]

[b] pa是一个包含三个元素的数组,而要声明这样的数组,首先需要使用pa[3],该声明的其他部分指出了数组包含的元素是什么样的。运算符[]的优先级高于*,因此*pa[3]表明pa是一个包含三个指针的数组。此时可以调用函数如下所示:[/b]

[b] const double * px=pa[0](av,3);[/b]

[b] const double * py=(*pa[2])(av,3);// 依然是两种方式在调用函数[/b]

[b] 可以创建一个指向真个数组的指针,由于数组名pa是指向函数指针的指针,因此指向数组的指针将是这样的指针,既它指向指针的指针。这种声明类似于pa的声明,但由于增加了一层间接,因此需要在某个地方添加一个*。具体地说,如果这个指针名为pd,则需要指出它是一个指针,而不是数组。这意味着声明的核心部分是(*pd)[3],其中的括号让标示符pd与*先结合,也就是数组指针和指针数组的区别,pd是一个指针,它指向一个包含三个元素的数组。[/b]

[b] const double *(*(*pd)[3])(const double *,int)=&pa;[/b]

[b] 要调用函数,需要认识到这样一点:既然pd指向数组,那么*pd就是数组,而(*pd)[i]是数组中的元素,既函数指针。因此,较简单的函数调用是(*pd)[i](av,3),而*(*pd)[i](av,3)是返回的指针指向的值。也可以使用第二种使用指针调用函数的语法:使用(*(*pd)[i])(av,3)来调用函数,而*(*(*pd)[i])(av,3)是指向的double值。[/b]

[b] 请注意pa(它是数组名,表示地址)和&pa之间的区别。pd是数组第一个元素的地址,既&pa[0]。因此,他是单个指针的地址。但&pa是整个数组(既三个指针块)的地址。从数字上说,pa和&pa的值相同,但他们的类型不同。(类型不同,在《C专家编程》中有那么一章单独说明这个问题)。一种差别是,pa+1为数组中下一个元素的地址,而&pa+1为数组pa后备一个12字节内存块的地址,另一个差别是,要得到第一个元素的值,只需对pa解除一次饮用,但需要对&pa解除两次引用:[/b]

[b] **&pa==*pa==pa[0];[/b]

[b]四、使用typedef[/b]

[b] 使用这个关键字创建类型别名:[/b]

[b] typedef const double * (*p_fun)(const doble *,int); //p_fun 现在是一种新的类型[/b]

[b] p_fun p1=f1;[/b]

[b] 然后使用这个别名来简化代码:[/b]

[b] p_fun pa[3]={f1,f2,f3};[/b]

[b] p_fun (*pd)[3]=&pa;[/b]

[b] 对于这个很严肃的问题,还是用代码说明比较好,这段代码在书中也有相似的:[/b]



#include <iostream>
const int * f1(const int ar[],int n);
const int * f2(const int [],int );
const int * f3(const int *,int);
using namespace std;
int main()
{
	int temp[]={2,3,4};
	int i;
	cout<<"单个函数指针"<<endl;
	const int * (*p1)(const int *,int n)=f1;
	const int * mn=p1(temp,3);
	cout<<(*p1)(temp,3)<<": "<<*(*p1)(temp,3)<<endl;
	cout<<p1(temp,3)<<": "<<*(*p1)(temp,3)<<endl;
	cout<<mn<<": "<<mn[0]<<endl;
	cout<<temp<<endl;

	cout<<"函数指针数组 两种方法"<<endl;
	const int * (*pa[3])(const int *,int n)={f1,f2,f3};
	for(i=0;i<3;i++)
		cout<<pa[i](temp,3)<<": "<<*(pa[i])(temp,3)<<endl;
	for(i=0;i<3;i++)
		cout<<(*pa[i])(temp,3)<<": "<<*(*pa[i])(temp,3)<<endl;
	cout<<"二级指针"<<endl;
	const int * (**pb)(const int *,int n)=pa;
	for(i=0;i<3;i++)
		cout<<pb[i](temp,3)<<": "<<*pb[i](temp,3)<<endl;
	for(i=0;i<3;i++)
		cout<<(*pb[i])(temp,3)<<": "<<*(*pb[i])(temp,3)<<endl;
	cout<<"指针地址"<<endl;
	const int * (*(*pc)[3])(const int *,int n)=&pa;
	for(i=0;i<3;i++)
		cout<<(*pc)[i](temp,3)<<": "<<*(*pc)[i](temp,3)<<endl;
	for(i=0;i<3;i++)
		cout<<(*(*pc)[i])(temp,3)<<": "<<*(*(*pc)[i])(temp,3)<<endl;
	
	return 0;
	}
const int * f1(const int ar[],int n)
{
	return ar;
	}
const int * f2(const int ar[],int n)
{
	return ar+1;
	}
const int * f3(const int ar[],int n)
{
	return ar+2;
	}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: