目录
1.函数指针
1.1如何定义一个函数指针
1.2如何使用函数指针
2.指针数组
3.指针函数
4.多级指针
4.1认识二级指针和多级指针
4.2 二级指针的用法
4.3二级指针不能简单粗暴指向二维数组
5.总结
1.函数指针
1.1如何定义一个函数指针
如果程序中定义了一个函数,在编译时,编译系统为函数代码分配一段储存空间,这段储存空间的初始地址(又称入口地址),称为这个函数的指针。
函数名==地址!!(就像数组中,数组名==地址)
Int (*p)(int); 从P处开始,先与指针结合,说明P是一个指针,然后与( )结合,说明指针指向的是一个函数,然后再与( )里的int结合,说明函数有一个int型的参数,再与最外层的int结合,说明函数的返回类型是整型,所以P是一个指向有一个整型参数且返回类型为整型的函数的指针。
1.2如何使用函数指针
void printWelcom()
{
puts("程序启动,欢迎使用!\n");
}
int inCData(int data)
{
return ++data;
}
int main()
{
void (*p)();//定义了一个函数指针变量
int(*p2)();
p = printWelcom;//指向函数
p2=inCData;
(*p)();//调用
printf("p2测试:%d\n",(*p2)(10));
return 0;
}
巧妙理解:以普通指针做对比
int a;//声明一个变量
int \*pa;//声明一个指针变量
pa=&a;
printWelcom( ); //声明一个函数
void (\*p)( ); //声明一个函数指针
p=printWelcom; //函数名==地址!!
2.指针数组
前文提到的数组指针 int (*p)[4] 是指向数组的指针,这个指针是含有4个元素的一维数组。
而指针数组是一个数组,其元素均为指针类型, 换句话说,指针数组中的每一个元素都存放一个地址
定义为: int *p[4]
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("%d ", *p[i]);
}
return 0;
}
3.指针函数
一个函数可以返回一个整形值,字符值,实型值,也可以返回指针型的数据,即地址。概念与前文类似,只是返回的值是指针类型而已。
例如“int *a(int x, int y);”, a是函数名,调用他以后能得到一个 int*型(指向整形数据)的指针,即整形数据的地址。 x和y是函数a的形式参数。
问题:有a个学生,每个学生有b门课程的成绩。要求在用户输入学生序号以后,能输出该学生的全部乘机。用指针函数实现。
int* getPosPerson(int pos, int(*pstu)[4])//指针函数,返回指针的函数
{
int* p;
p = (int*)(pstu + pos);//偏移
return p;
}
int main()
{
int scores[3][4] = {
{55,66,77,88},
{66,55,99,100},
{11,22,33,59},
};
int* ppos;
int pos;
printf("请输入你需要看的学生号数:0,1,2\n");
scanf("%d", &pos);
ppos = getPosPerson(pos, scores);
for (int i = 0;i < 4;i++) {
printf("%d ", *ppos++);
}
return 0;
}
4.多级指针
4.1认识二级指针和多级指针
写法**p
int main()
{
int data = 100;
int *p = &data;
printf("data的地址是:%p\n",&data);
printf("p保存data的地址:%p,内容是%d\n",p,*p);
/*可以用一级指针变量存放指针变量的地址,但是使用有缺陷,无法获得最终地址内容
printf("p的地址是:%p\n",&p);
int *pp = &p;
printf("pp保存p的地址:%p\n",pp);
printf("*pp是%p\n",*pp);*/
int **p2;//二级指针
p2 = &p;
printf("p2保存p的地址:%p\n",p2);
printf("*p2是%p\n",*p2);
printf("**p2来访问data:%d\n",**p2);
int ***p3;//三级指针
p3 = &p2;
printf("p3保存p2的地址:%p\n",p3);
printf("*p3是%p2\n",*p3);
printf("***p3来访问data:%d\n",***p3);
return 0;
}
4.2 二级指针的用法
void getPosPerson(int pos, int(*pstu)[4], int **ppos)//指针函数,返回指针的函数
{
*ppos = (int*)(pstu + pos);//偏移
}
int main()
{
int scores[3][4] = {
{55,66,77,88},
{66,55,99,100},
{11,22,33,59},
};
int* ppos;
int pos;
printf("请输入你需要看的学生号数:0,1,2\n");
scanf("%d", &pos);
getPosPerson(pos, scores,&ppos);
for (int i = 0;i < 4;i++) {
printf("%d ", *ppos++);
}
return 0;
}
4.3二级指针不能简单粗暴指向二维数组
int main()
{
int scores[3][4]={
{55,66,77,88},
{66,55,99,100},
{11,22,33,59},
};//int (*p)[4];
int (*p2)[4] = scores;
int **p;
p = scores; //会出问题!
printf("scores:%p\n",scores);
printf("p=%p\n",p);
printf("*p=%p\n",*p);//*p是一个野指针,不是我们认为的会编程列地址
printf("*score=%p\n",*scores);//*p是一个野指针,不是我们认为的会编程列地址
**p = 100;
printf("done\n");
int **p3 = &p2;//能用
**p3 = 100;//能改的动,但是一般不这么进行
printf("%d\n",scores[0][0]);
return 0;
}
5.总结
C语言指针 两篇主要讲了:①指针是什么 ②为什么用指针 ③指针与数组的关系 ④数组指针 ⑤函数指针 ⑥指针数组 ⑦指针函数 ⑧二级指针
面试题会出现: