C/C++指针与数组、void指针、指针函数、指针数组、指向指针的指针

本文深入探讨C/C++中的指针概念,包括指针与数组的关系、void指针、函数指针、指针数组及指向指针的指针。通过实例解析,帮助读者理解指针的复杂应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 指针是C/C++中的难点之一,本文列举一些复杂的指针内容。

指针与数组

 这一点应该已经是常识了,一个数组的名字实际上就是一个指向该数组的起始位置的指针,这使得我们可以通过指针对数组进行操作:

int a[] = {1,2,3,4};
int *p;
p = a;
//此时指针p就指向数组a的起始元素。

另外,在数组作为函数参数时,

void func(int *p){}

void func(int a[]){}

 是等价的,这两个函数是完全等价的函数,不属于重载。
 而且要注意到的是,在实际函数调用中,即使采用的是第二种方式,传入的实参依然是指针,这意味着在函数中不能调用sizeof()来计算数组所占的内存,因为结果会是本地编译器中指针类型的内存。
如果想要在函数中计算实参数组的长度,可以利用模板函数,通过传递对数组的引用

void指针

void *p;

 以上语句声明了一个类型为void的指针。
 void指针需要注意的点是,在C++中,不同类型的指针不存在隐式转换,但是void指针是一个特例,void指针不能隐式转换为其他类型的指针(在另外一篇博客中有解释,这也是C++中NULL的定义和C中不同的原因)但是其他类型的指针可以隐式转换为void类型的指针
 另外,void类型指针的指向的内容是未定义的,所以对void指针进行sizeof()计算和取值是没有意义的。

函数指针

 程序在运行期间,函数是占用内存的,而我们在调用函数时使用的函数名就是这段内存的入口(即起始地址),我们知道指针是可以指向任何内存中的内容的,那么指针也可以指向函数或者说函数的入口地址——函数名。
 如果将函数赋给指针使该指针指向函数,这个指针就称为函数指针。
 函数指针的定义为:

类型名 (*指针变量名)(参数列表);

 即为了让一个指针指向一个函数,我们在声明该指针的时候,需要参考函数原型。

int sum(int x,int y)
{
	return x+y;
}
int main()
{
	//声明函数指针,为了使指针指向sum函数,所以指针声明需要参考sum原型:
	int (*p)(int,int);
	p = sum;
	cout<<p(4,5)<<endl;
	//输出结果9,这里通过指针p实现了对函数sum的调用。

 我们一般情况下不会用到函数指针的概念,因为如果仅仅是为了调用一个函数使用函数指针实在是多此一举。而函数指针存在的意义除去C语言的历史原因以外,更多的是应用在回调函数中。
 如果一个函数在执行过程中依赖于另外一个函数,而这个被依赖的函数尚未定义。我们举个很简单的例子:

//我们定义一个求和函数,但是这个函数并不是单纯的求和,可能是求平方和、立方和等等。
int xxSum(int a,int b, int (*xx)(int,int)
{
	return xx(a,b);
}
int sq(int a)
{
	return pow(a, 2);
}
int cube(int a)
{
	return pow(a, 3);
}
int main()
{
	int x = 3, y = 4;
	//这里我们对xxSum函数的调用,依赖于其中xx函数指针。
	cout << xxSum(x, y, sq); 
	//输出25
	cout << xxSum(x, y, cube);
	//输出91
}

 当然,这个例子确实是多此一举,为的是演示指针函数的使用和意义,更具体的应用的是参见qsort函数的调用,这里不再赘述。

指针数组与指向指针的指针

 如果有一个数组,数组中的元素都是指针,这个数据就称为指针数组。

T *a[N];	//N是整数类型的常量或常量表达式。

 指针也是变量,如果用一个指针指向一个指针,就称该指针为指向指针的指针。

T **p;

 这里的指针p指向一个指针,该指针指向一个类型为T的数据。
 这里相同类型的指针数据和指向指针的指针是可以相互赋值的,因为我们知道一个数组名即指向这个数组初始地址的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值