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);//将序号转换为指针变量
注意在数组在函数传参时,定义函数时要指明数组的类型和列大小。联系一维数组作为函数参数时,不需要传递其大小,因为函数不关心数组元素的维度。但当参数为二维数组时,要表明数组的列数,即子数组的维数。在调用函数时,无论是一维数组还是二维数组,都只需写数组名即可,目的是表明数组的起始地址。