【指针分析】

指针和数组的关系
地址匹配,进行计算
***在C语言中,数组名在大多数情况下会被隐式地转换为指向数组首元素的指针***
因此, 可以直接用作指向字符数组首元素(即字符串的首地址)的指针。
	int a[1024];
	int *p = a;
	p = a;
	a = &(a[0]);
	p = &(a[0]);
	p+0 = &(a[0+0]);
	p+i = &(a[i]);
	*(P+i) = *(&(a[i])) = a[i];
	* (p+i) = p[i];

指针·指针数组·数组指针

指针

符号&取地址,*解应用
指针用来存储对应数据的地址;
	int a = 10;
	int *p = NULL;
	p = &a;
	或者
	int a = 10;
	int* p = &a; 声明指针,直接存储地址
那现在p中就是a的地址,输出时使用*p解应用得到对应值;

指针数组

指针数组,声明一个指针类型的数组,数组里面时每一个都是用来存储数据的地址;
int mat[3][4] =
{
	{1,2,3,4},
	{5,6,7,8},
	{9,10,11,12}
};
int* pmat[3];
在这个里面我们可以这样处理对应关系;
pmat[0]用来存储一个地址····以此类推
所以
	pmat[0] = mat[0];
	pmat[1] = mat[1];
	pmat[2] = mat[2];
那么为什么在mat[]数组赋值给pmat时忽略了&这个符号呢?
在C语言中,数组名在大多数情况下会被隐式地转换为指向数组首元素的指针。
这是C语言的一个特性,因此你可以直接使用 mat[0] 而不需要显式地写 &mat[0][0]。
那么我们在指针数组中存储了每一行对应的首地址之后,就可以按照规则直接输出了;
输出
	for(int i = 0;i<3;i++){
		for(int j = 0;j<4;j++){
			printf_s("%d ",(pmat[i]+j));//这样输出就是地址,因为我们的pmat直接存储了地址因此需要解应用输出;
			printf_s("%d ",*(pmat[i]+j));//这样输出就是对应的值
		}
		printf("\r\n");
	}

数组指针

数组指针,将一整个数组定义一个指针,也就是当下的指针长度为 int类型*5 = 20
	int (*px)[5];//等同于数组
	int test[4][5]={
		{4,3,2,1,0},
		{9,8,7,6,5},
		{6,7,8,9,0},
		{5,6,7,8,9}
	};
接下来我们将地址写入px当中;
px为数组指针,仍然具有指针的全部特性;
px = test;  //为什么这样写呢?应该等价于px ==&test[0],px为第一行的首地址,第二行为px+1以此类推

***在C语言中,数组名在大多数情况下会被隐式地转换为指向数组首元素的指针***

接下来我们输出
	px[i][j] == *(&test[i][j])------>>>>px[i][j] == test[i][j]

	for(int i = 0;i<4;i++){
		for(int j=0;j<5;j++){
			pritnf("%d ",px[i][j]);
		}
		printf("\r\n");
	}

这里是引用

#include <iostream>

using namespace std;

int main() {
	int a[5] = {1,2,3,4,5};
	int* p = NULL;
	//p = &a[0];
	p = a;
	printf_s("%d \n", p);
	printf_s("%d \n", a);
	printf_s("%d \n", *( & a[0]));//所以*( & a[0]) = a[0]
	//for (int i = 0; i < 5;i++) {
	//	printf_s("%d \n",*p);
	//	p++;
	//	printf_s("%#X \n", p[i]);
	//}
	printf_s("%d \n", p[2]);
	printf_s("%d \n", &p[2]);
	printf_s("%d \n", a[2]);
	printf_s("%d \n", &a[2]);
	//char b[] = "I";
	//char c[] = "Love";
	//char d[] = "you";

	//char* e[3] = { NULL,NULL,NULL };
	//e[0] = b;
	//e[1] = c;
	//e[2] = d;
	//for (int i = 0; i < 3;i++) {
	//	printf_s("%s ", e[i]);
	//}

	/*指针数组*/
	int mat[3][4] =
	{
		{1,2,3,4},
		{5,6,7,8},
		{9,10,11,12}
	};
	int* pmat[3];
	pmat[0] = mat[0];
	pmat[1] = mat[1];
	pmat[2] = mat[2];
	for (int i = 0; i < 3;i++) {
		for (int j = 0; j < 4;j++) {
			printf_s("%#X ", (pmat[i] + j));
			printf_s("%d ", *(pmat[i]+j));
		}
		printf_s("\n");
	}
	//printf("--------------------------\n");
	/*数组指针*/
	int (*px)[5];
	int test[4][5]={
		{4,3,2,1,0},
		{9,8,7,6,5},
		{6,7,8,9,0},
		{5,6,7,8,9}
	};
	px = test;
	for (int i = 0; i < 4;i++) {
		for (int j = 0; j < 5;j++) {
			printf("%d ",px[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述

函数指针·指针函数

#include <iostream>

using namespace std;

/*指针函数
	传递值地址,返回值为值

*/
int* fun() {

	return NULL;
}
int* getArray(int a,int b,int n) {
	int* ret = new int[n];

	for (int i = 0; i < n;i++) {
		ret[i] = a + i * b;
	}
	return ret; //返回这个地址的首地址
}


/*函数指针
	传递函数地址
*/
double (*ptr)(int a, int b, int n);
double func_d(int a,int b ,int n) {
	cout << "a" << endl;

	return 0.0;
}

/*函数指针类型定义*/
typedef void (*fptr)(int a, int b, int n);
void func(int a, int b, int n) {

}

/*函数指针数组*/
typedef void (*fptrs[])(int a,int b,int c,int d);

void func_2(int a, int b, int c, int d) {
	cout << "func_2" << endl;
}
void func_3(int a, int b, int c, int d) {
	cout << "func_3" << endl;
}
void func_4(int a, int b, int c, int d) {
	cout << "func_4" << endl;
}
void func_5(int a, int b, int c, int d) {
	cout << "func_5" << endl;
}

int main() {
	/*指针函数*/
	int* ans = getArray(3,6,7);
	for (int i = 0; i < 7;i++) {
		printf_s("%d ",ans[i]);
	}
	cout << "******************" << endl;

	/************/
	/*函数指针*/
	ptr = func_d;
	ptr(4, 5, 6);

	/*函数指针类型*/
	fptr ptr2= func;


	/*函数指针数组*/
	fptrs fps12 = { func_2 ,func_3, func_4 ,func_5 };
	cout << sizeof(fps12)/8 << endl;

	for (int i = 0; i < 4;i++) {
		cout<<fps12[i]<<endl;
		fps12[i](1, 2, 3, 4);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值