1.数组指针和指针数组
数组指针:数组的指针,是一个指针,指向数组的指针
指针数组:指针的数组,是一个数组,装着指针的数组
(*p)[n]:根据优先级,先看括号内,则p是一个指针,这个指针指向一个一维数组,数组长度为n,这是“数组的指针”,即数组指针;
*p[n]:根据优先级,先看[n],则p是一个数组,再结合,这个数组的元素是指针类型,共n个元素,这是“指针的数组”,即指针数组
int *p1[5];//指针的数组
int (*p2)[5];//数组的指针
首先,对于语句int* p1[5],因为“[]”的优先级要比 * 要高,所以 p1 先与“[]”结合,构成一个数组的定义,数组名为 p1,而“int*”修饰的是数组的内容,即数组的每个元素。也就是说,该数组包含 5 个指向 int 类型数据的指针,如图 所示,它是一个指针数组。
其次,对于语句int (* p2)[5],“()”的优先级比“[]”高,“*”号和 p2 构成一个指针的定义,指针变量名为 p2,而 int 修饰的是数组的内容,即数组的每个元素。也就是说,p2 是一个指针,它指向一个包含 5 个 int 类型数据的数组,如图 所示,它是一个数组指针,数组在这里并没有名字。
对指针数组来说,首先它是一个数组,数组的元素都是指针,也就是说该数组存储的是指针,数组占多少个字节由数组本身决定;而对数组指针来说,首先它是一个指针,它指向一个数组,也就是说它是指向数组的指针,在 32 位系统下永远占 4 字节,至于它指向的数组占多少字节,这个不能够确定,要看具体情况。
1.1 数组指针
#include<stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int (*p)[5]; //数组指针。数组中有5个元素
p = &a; //把数组a的地址赋给p,则p为数组a的地址,则*p表示数组a本身
p //根据上面,p为数组a的地址,输出数组a的地址
*p //*p表示数组a本身,一般用数组的首元素地址来标识一个数组
&a[0] //a[0]的地址
&a[1] //a[1]的地址
p[0] //数组首元素的地址
**p //*p为数组a本身,即为数组a首元素地址,则*(*p)为值,当*p为数组首元素地址时,**p表示首元素的值1
*p[0] //根据优先级,p[0] 表示首元素地址,则*p[0]表示首元素本身,即首元素的值1
1.2数组指针与二维数组
#include<stdio.h>
int_64 value = 0;
int arr[3][4] = { 0 };
int (*p)[4] = arr; //根据优先级,这是一个数组指针
Arr_Point pp = arr;
p++; //p + 4个int
int(*q)[4] = &arr[0];
q++;// q + 4个int
int* s = &arr[0][0];
s++; //s + 1个 int
int (*w)[3][4]= &arr;
w++; //w + 12个int ,*w表示一整个大数组
*int* p = arr[0];
printf("%d %d\n",w,arr);
1.3指针数组*p[n]
int main()
{
int a = 1;
int b = 2;
int *p[2];
p[0] = &a;
p[1] = &b;
printf("%p\n", p[0]); //a的地址
printf("%p\n", &a); //a的地址
printf("%p\n", p[1]); //b的地址
printf("%p\n", &b); //b的地址
printf("%d\n", *p[0]); //p[0]表示a的地址,则*p[0]表示a的值
printf("%d\n", *p[1]); //p[1]表示b的地址,则*p[1]表示b的值
2. 函数指针
函数指针是指向函数的指针变量。 因此“函数指针”本身首先是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。
2.1 函数指针的定义
int (*p)(int,int);
int代表的是指针变量名,两个int代表,函数参数有两个,且都为int型,当然以上定义只为示例,需要根据不同的函数,指定不同的参数类型和参数个数。
- 通过函数指针调用函数
先定义一个判断大小的函数
int Max(int a,int b)
{
return a>b?1:0;
}
通过指针变量,调用函数形式为*p(a,b)
int main(int argc, char *argv[]) {
// 定义函数指针
int (*p)(int,int);
// 让指针指向函数
p = Max;
//调用函数
int result = (*p)(1,2);
printf("%d",result);
return 0;
}
- 函数指针作函数参数
函数指针也可以当作参数在函数之间传递
int test(int (*a)(int,int),int (*b)(int,int))
{
return 0;
}
2.2 具体用途
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int add(int a, int b) {
return a + b;
}
int mul(int a, int b) {
return a * b;
}
int main(){
int a, b;
char op[10] = { 0 }; //"+" "*"
scanf("%d%d", &a, &b);
scanf("%s", &op);
//定义一个函数指针,指向add 指向mul
int (*pfun)(int, int);
//声明一个指针变量
//函数指针类型
if (strcmp(op, "+") == 0) {
pfun = add;
}
else {
pfun = mul;
}
int result = pfun(a, b);
printf("%d\n", result);
}