C语言中多种指针浅析笔记

本文章主要讨论c语言中的一些简单的指针和一些学习其过程的总结(用自己的话)。

目录:

  • 1.普通指针。
  • 2.二重指针。
  • 3.行指针。
  • 4.指针数组,数组指针。
  • 5.指针函数,函数指针。
  • 6.复杂指针解析。(另一篇文章)本篇中列举了一个例子,(函数指针函数)

1.普通指针。

int a =10;
int *p = &a;
char *c="abcd";
char *p=c;

2.二重指针。

int a=10;
int *str =&a;
int *p = str; //p是与str指向相同的指针
int **pop = &p; //pop是指向指针的指针,二重指针
cout<<&str<<endl;
cout<<&p<<endl; 
cout<<pop<<endl;//与p的地址相同,说明pop保存的是p的地址。

利用二重指针开辟二维数组:

    //用二级指针创建二维数组
	int **p =new int*[4]; //P指向了一个指针数组,大小为4
	int i;
	for(i=0;i<4;i++)
	{
		p[i] = new int[4]; //为每一个指针都开辟了长度为4的数组
	}
	for(i=0;i<4;++i) // 赋值
	{
		for(int j=0;j<4;j++)
			p[i][j] = i+j;
	}
	for(i=0;i<4;++i) //打印
	{
		for(int j=0;j<4;j++)
			cout<<p[i][j]<<" ";
		cout<<endl;
	}
	//释放空间反着来,先释放指针数组里面的指针指向的空间。接着释放p
	for(i=0;i<3;i++)
		delete p[i];
	delete []p;
    p=NULL;

3.行指针。

在二维数组时,其数组名就是个行指针。

例如:int a[3][4]={0,1,2,3,4,45,6,6,7,7,1,2}; 数组名a就相当于int(*a)[4]  它是一个数组指针,也就是a指向了一个数组,大小为4。

int a[3][4]={0,1,2,3,4,45,6,6,7,7,1,2};
	cout<<**a<<endl; //0
	cout<<*(*a+1)<<endl;//1
	cout<<**(a+1)<<endl;//4

 

4.指针数组,数组指针。

在上面的讨论中,其实已经接触过了数组指针,指针数组。

在二重指针时,出现了int **p =new int*[4];里面int*[4] 是一个指针数组,相当于表示为 int *p[4],根据优先级,p先与数组[]结合,所以其本质是一个数组,有因为其是一个int* 类型,所以这个数组存储了4个int*类型变量。称之为指针数组。

在二维数组时,是int(*a)[4],与上面不同的是多了一个()改变了结合的优先级,所以这个的本质是一个指针,其指向了一个int 数组。称之为数组指针。

5.指针函数,函数指针。

在分析一个东西到底是那种指针时,我们首先就是要抓中核心重点的东西,判断其本质是指针,或是数组,或是函数。然后在看其他的部分。

指针函数:见名知意,其本质是函数,其返回值是一个指针,所以称之为指针函数。例子很多。

函数指针:其本质是一个指针,指针指向了一个函数。思考:一个指针能指向什么类型的函数?

根据指针的含义,若指针能指向a或b。说明a,b是同类型的。既然函数指针,是个指针,那么这个指针肯定能指向多个同类型的函数。什么是同类型的函数?那就是返回值相同,参数相同的函数(包括参数类型,个数)。

反思:遇到问题时,冷静思考。抓住其本质,明白本质后,其属性不会改变。从属性去分析,学习它的行为。

下面就举个简单的理解说明函数指针,同时也对函数指针调用函数时的情况分析一下。

int add(int add1,int add2)
{
	return add1+add2;
}
int sub(int sub1,int sub2)
{
	return sub1-sub2;
}
int control(int a,int b,bool choose)
{
	int(*p)(int,int)=NULL;
	if(choose)
		p=add;
	else
		p=sub;
	return (*p)(a,b); //也可以写为 p(a,b)
}
void main()
{
	int a =10,b= 10;
	a = control(a,b,1);
	printf("%d\n",a);
}

对于上面代码 因为add,sub函数都是int p(int,int)模式,所以在control函数中定义了一个函数指针p,指向了返回值为int,参数为int,int的函数。

有一个概念,对于一个定义的函数,函数的名字就是调用函数的地址(函数的入口地址)。因为指针与函数同类型,所以直接可以将函数名给指针赋值,这点与数组名给同类型指针赋值相同。

可以用p(a,b) 或者(*p)(a,b)调用指向的函数。指针p保存的内存是函数的地址,地址就是函数入口,这是第一种。*p虽然解引用,但是效果还是和p是一样的,类似于一个通过指针调用操作和一个通过对象调用操作。一个是用->运算符,一个是 对象.运算符。但是函数调用不同,函数只能是 () 运算符。只是想说明-> 和.在这里和一个函数调用运算符()都一样,所以*p,p在这里调用函数没有区别。

6.复杂指针解析。

可以有更多的复杂指针,但是他们都是由上面几种指针复合而来。需要抓住重点,主要核心分清层次。

例如:

int add(int add1,int add2)
{
	return add1+add2;
}
int sub(int sub1,int sub2)
{
	return sub1-sub2;
}
//函数指针函数,返回一个函数指针,指针是指向一个int返回值,(int,int)参数的函数
int (*(func(int chooes)))(int,int)
{
	int (*p)(int,int);
	if(chooes)
		return (p=add);
	else
		return (p=sub);
}
void main()
{
	int (*p)(int,int);
	p = func(1);
	int a= p(1,2);
	printf("%d\n",a); //a=3
}

函数指针函数:也就是一个返回值为一个函数指针的函数。它还是有 指针函数 和函数指针复合而来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值