1. 数组指针变量 2. ⼆维数组传参的本质 3. 函数指针变量
2. ⼆维数组传参的本质
3. 函数指针变量
)
1.数组指针变量
1.1了解数组指针变量的概念
整形指针变量 ——变量——存放的是整形的地址
字符指针变量——变量——存放的是字符的地址
数组指针——变量——存放的是数组的地址
int (p)[5]
诠释: * 先与p结合 说明 p是一个指针变量 , [5]代表的是存放的是5个整形的数组,所以p是一个指针,指向数组,这就是一个数组指针。
注意:[]的优先级比高所以要用()确保p先于*结合。
1.2数组指针变量初始化
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int arr[3] = { 0 };int(*p)[3] = &arr;//得到的是数组的地址return 0;
}
p与&arr的类型一样
2.二维数组传参的本质
二维数组传参,形参是数组时
void xs(int a[3][4], int b, int c)
{for (int i = 0; i < b; i++){for (int j = 0; j < c; j++){printf("%d ", a[i][j]);}}
}
int main()
{int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };xs(arr, 3, 4);return 0;
}
根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀维数组的地址。根据上⾯的例⼦,第⼀⾏的⼀维数组的类型就是 int [4] ,所以第⼀⾏的地址的类型就是数组指针类型 int(*)[4] 。那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀⾏这个⼀维数组的地址,那么形参也是可以写成指针形式的。如下:
void xs(int(*p)[4], int b, int c)
{for (int i = 0; i < b; i++){for (int j = 0; j < c; j++){printf("%d ", *(*(p+i)+j));}}
}
int main()
{int arr[3][4] = { 1,2,3,4,5,6,7,8,9 ,10,11,12};xs(arr, 3, 4);return 0;
}
3.函数指针变量
变量可以取地址、数组可以取地址、函数也可以取地址。
写一个简单函数来看看
int mul(int x, int y)
{return x * y;
}
int main()
{printf("%p\n", mul);printf("%p\n", &mul);return 0;
}
函数是有地址的,函数名就是函数的地址,当然也可以通过 &函数名的⽅式获得函数的地址。
如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针⾮常类似。如下:
3.1 函数指针变量的创建
int (*p)(x, y) = mul;//x和y写上或者省略都是可以的
int —— p指向函数的返回类型
(*p)—— 函数指针变量名
(int x, int y)—— p指向函数的参数类型和个数的交代
3.2 函数指针变量的使⽤
int mul(int x, int y)
{return x * y;
}
int main()
{int (*p)(x, y) = mul;//x和y写上或者省略都是可以的int ret = (*p)(2, 4);printf("%d\n", ret);printf("%d\n", (*p)(2, 3));printf("%d\n", p(3, 4));return 0;
}
持续指针系列