指针数组

307 阅读3分钟

1.指针数组

一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都存放一个地址,相当于一个指针变量。

下面定义一个指针数组: int*p[4];

   由于[]比*优先级高,因此p先与[4]结合,形成p[4]形式。
   这显然是数组形式,表示p数组有4个元素。
   然后再与p前面的“*”结合,“*”表示此数组是指针类型的,
   每个数组元素(相当于一个指针变量)都可指向一个整型变量。

注意不要写成 int(*p)[4];这是指向一维数组的指针变量

定义一维指针数组的一般形式为:

类型名*数组名[数组长度];

类型名中应包括符号“*”,如“ int* ”表示是指向整型数据的指针类型
#include <stdio.h>
int main(){
	int a=10;
	int b=20;
	int c=30;
	int d=40;
	int *p[4]={&a,&b,&c,&d};
	for(int i=0;i<4;i++){
		printf("%p\n",*(p+i));
	}
}
000000000061FE18
000000000061FE14
000000000061FE10
000000000061FE0C

2.指针函数

一个函数可以返回一个整型值、字符值、实型值等,也可以返回指针型的数据,即地址其概念与以前类似,只是返回的值的类型是指针类型而已。

例如“int *a(int x,int y);”,

a是函数名调用它以后能得到一个int*型(指向整型数据)的指针,即整型数据的地址。x和y是函数a的形参,为整型。

注意在*a两侧没有括号,在a的两侧分别为 * 运算符和 () 运算符。而 () 优先级高于 * ,因此 a 先与 () 结合,显然这是函数形式。这个函数前面有一个 *表示此函数是指针型函数(函数值是指针)。最前面的 int 表示返回的指针指向整型变量。

示例:有a个学生,每个学生有 b门课程的成绩。
要求在用户输入学生序号以后能输出该学生的全部成绩。
用指针函数来实现。

里面有几点需要注意:

#include <stdio.h>
int* getNum(int num,int (*scores)[4])//函数指针,返回指针的函数 
{
	int *pnum;
	pnum=(int *)scores+num;//强制类型转换,数组首地址加上偏移量得到给定地址
	return pnum;
}

int (*scores)[4]而非 int scores[4]

int scores[4] :含有4个整型变量元素的数组

int *scores[4]:含有4个指针变量元素的数组( [] 的优先级高于 *)

int (*scores)[4]:含有4个整型变量元素的数组,但 *scores表明,指针scores指向该一维数组

pnum=(int *)scores+num; 强制类型转换,数组首地址加上偏移量得到给定地址

int main(){
	int a[3];
	int num=2;
	int *p;
	p=a;
	printf("%p\n",a);
	printf("%p\n",p);
	printf("%p\n",a+num);
	printf("%p\n",p+num);
}
000000000061FE04
000000000061FE04
000000000061FE0C
000000000061FE0C
#include <stdio.h>
int main(){
	int a[3][4];
	int num=2;
	int *p;
	p=a[0];
	printf("%p\n",a);
	printf("%p\n",p);
	printf("%p\n",a+num);
	printf("%p\n",p+num);
}
000000000061FDE0
000000000061FDE0
000000000061FE00
000000000061FDE8

printf("%p\n",a+num);//由结果可知,偏移了424=32个字节 printf("%p\n",p+num);//偏移了2*4=8个字节

由此可知,a[0]和p虽然同时指向a[0][0]的地址,但偏移量却完全不同

void printScore(int *pnum){
	printf("该生成绩为:");
	for(int i=0;i<4;i++){
		printf("%d ",*(pnum+i));
	}
	puts("");
}

void search(int scores[3][4]){
	for(int i=0;i<3;i++){
		for(int j=0;j<4;j++){
			if(scores[i][j]<60){
				printf("第%d位同学第%d门成绩不及格,成绩为:%d\n",i+1,j+1,scores[i][j]);
			}
		}
	}
}

int main(){
	int scores[3][4]={
		{55,65,66,80},
		{75,85,68,90},
		{66,59,79,89}};
	int num;
	int *pnum;
	printf("请输入学生序号:\n");

}
	scanf("%d",&num);
	num--;
	pnum=getNum(num,scores);//将序号转换为指针变量
	printScore(pnum);
	search(scores);

pnum=getNum(num,scores);//将序号转换为指针变量

注意在数组在函数传参时,定义函数时要指明数组的类型和列大小。联系一维数组作为函数参数时,不需要传递其大小,因为函数不关心数组元素的维度。但当参数为二维数组时,要表明数组的列数,即子数组的维数。在调用函数时,无论是一维数组还是二维数组,都只需写数组名即可,目的是表明数组的起始地址。

3.多级指针