C语言函数指针,数组指针,数组引用用法

void main()//关于指针的扩展理解
{
int ar[10] = {};//ar时整型数组
int a = 1;
int b = 2;
int c = 3;
int *br[10] = { &a, &b, &c };//br不是指针而是一个存放地址的数组
int(*cr)[10]=&ar;//cr是一个存放数组的首指针,cr后面括号的值必须和所存放数组的 大小一样,这是cr+1时,会移动整个数组大小,它的识别能力为整个数组
//int(*xr) = &br;这样无法编译通过,因为在这条语句中xr是一个存放整型数组的指 针,然而br是一个存放地址的数组,所以类型不同
int *(xr)[10]=&br;//xr也是一个指向数组的首地址,但是xr所指的数组是存放地址的
//同理,当qr要指向br时需要加

int *(&qr)[10] = br;
int(&qr)[10] = ar;//引用
//int &cr[10] 这样的写法是错误的,因为引用是不开辟空间的,然而给的方括号中10,又让系统去开辟空间,造成了矛盾
//同理 int &(&cr)[10]自然也无法通过编译
}

下面是函数指针的介绍

int Add(int x, int y)
{
	return x + y;
}
int dis(int x, int y)
{
	return x - y;
}
int *App(int x,int y)
{
	int z = x + y;
	return &z;
}

void printdis(int x, int y, int(*pfun)(int, int))//printdis(int x, int y, int pfun(int, int)),这样也是正确的,当函数的声明在形参时,是当做函数指针使用的
{
	if (pfun != NULL)
	{
		int z = (*pfun)(x, y);
		cout << z;
	}
}
void main2()
{
	int pfub(int, int);//是函数声明
	int(*pfun)(int, int);//pfun是一个指针,而最前面的int表示所调用函数的返回类型
	int *(*pfum)(int, int);//同理int *知识表示调用函数的类型,(*pfun)表示pfun是一个指针
	//上面两种方式是定义函数指针的唯一方式

	int(*pfun)(int, int) = NULL;//是将pfun的值赋为NULL,而不是将函数的值赋值为NULL;
	pfun = Add;//表示将add函数的地址赋值给pfun
	int x = 1;
	int y = 2;
	int z;
	int z = (*pfun)(x,y);
	pfum = App;
	int *p;
	p = (*pfum)(x, y);
	sizeof(pfun);//结果为4,就是指针的大小
	//sizeof(*pfun)是无法计算的,因为无法计算出函数的大小
	//同理函数指针pfun+=1也是无法进行的,因为无法计算函数的大小所以也无法用过+1来跳到下一个函数;

	printdis(x, y, Add);//这就是函数指针的调用方式,至于函数指针的定义是在printdis函数中进行的

}

//下面的函数内容是使用一个指针,将多个类型的数组进行输出,qsort,bsearch



struct Student
{
	char s_id[20];
	char s_name[20];
	char s_sex;
	int s_age;
};
void * PrintInt(void *p)
{
	int *s = (int*)p;
	printf("%d \n", *s);
	return s + 1;
}
void * PrintDouble(void *p)
{
	double *s = (double*)p;
	printf("%f \n", *s);
	return s + 1;
}
void * PrintStudent(void *p)
{
	Student *s = (Student *)p;
	printf("%s  ", s->s_id);
	printf("%s  ", s->s_name);
	printf("%c  ", s->s_sex);
	printf("%d \n", s->s_age);
	return s + 1;
}
void PrintArray(void *ar, int n, void * (*pfun)(void*))
{
	if (ar == NULL || n < 1 || pfun == NULL)
		return;
	for (int i = 0; i<n; ++i)
	{
		ar = pfun(ar);
	}
	printf("\n");
}

struct node{
	int(*p)(int);
	void(*q)(double);
};
int app(int){}
void diss(double){}
int main3()
{
	int ar[] = { 12, 23, 34, 45, 56, 67, 78, 90 };
	int arlen = sizeof(ar) / sizeof(ar[0]);

	double dr[] = { 1.2, 2.3, 3.4, 5.6, 7.8 };
	int drlen = sizeof(dr) / sizeof(dr[0]);

	Student sr[] = { "201901001", "yhping", 'm', 23,
		"201901002", "lilingjie", 'f', 15,
		"201901003", "zhanghuan", 'f', 18
	};
	int studlen = sizeof(sr) / sizeof(sr[0]);

	PrintArray(ar, arlen, PrintInt);
	PrintArray(dr, drlen, PrintDouble);
	PrintArray(sr, studlen, PrintStudent);

	int x = 1, y = 2;
	int(*pfunm[2])(int, int) = { Add, dis };//用数组的方式来使用函数指针,(*pfunm[2])中的pfunm是一个存放地址的数组不是指针
	node n = { app, diss };
	int di;                                 //但是使用数组存放函数指针是必须要求每个函数的类型相同
	cin >> di;                              //但是为了是解决这个难题,可以使用结构体来初始化
	switch (di)
	{
	case 0:
		cout<<(*pfunm[0])(x, y); break;
	case 1:
		cout<<(*pfunm[1])(x, y); break;
	default:break;
	}
	return 0;


	//如果给出了函数的地址,需要我们调用函数,这是我们需要先将地址给强转为函数指针类型,再调用函数
	//比如地址为0x00412db0
	//调用的方式为int z = (*(int(*)(int,int)0x00412db0)(x,y)
	typedef int(*gun)(int, int);//这是类型声明,不是宏替换,这是gun就是函数指针类型
#define sun int*
	sun a, b;//相当于int *a,*b
	typedef int *sum;
	sum a, b;//也相当于 int *a,*b
		//在typedef中*sum就已经说明了他为指针类型,然后经过typedef后确定了他是一个int类型的指针类型
		//所以typedef的意义和#define是不同的

}

举一个例题
要求数组指针向下移动,在从数组里面向下移动,输出ar2中的第三个
在这要说明的数组的地址和数组的首元素地址的值是一样的,但是意义不同
在数组的地址前加*号就变为了数组的首元素地址如&ar0是数组的地址,
*&ar就变为了数组首元素的地址

	int ar0[4];
	int ar1[4];
	int ar2[4] = { 1, 2, 4, 5 };
	int(*s)[4] = &ar0;
	s += 2;
	cout<<*(*s+2);
	//也可写作
	cout<<*(*(s+2)+2);
	cout<<*(s[2]+2);
	cout<<s[2][2];
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值