一、字符指针变量
字符指针变量一般用char*来表示
一般使用:
#include"stdio.h"
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'w';
return 0;
}
还有一种使用方法:
#include"stdio.h"
int main()
{
const char* pc = "hello bit.";
printf(%s\n",pc);
return 0;
}
代码 const char* pc = "hello bit.";特别容易让我们以为是把字符串hello bit放到字符指针pc里,但是本质上是把字符串hello bit.首字符的地址放到了pc里。
二、数组指针变量
2.1数组指针变量是什么?
数组指针变量是指针变量
我们已经知道:
- 整型指针变量:int * pc;存放的是整型变量的地址,能够指向整型数据的指针。
- 浮点型指针变量:float * pa;存放浮点型变量的地址,能够指向浮点型数据的指针。
那数组指针的变量应该是:存放的应该是数组的地址,能够指向数组的指针变量。
数组指针变量:
1 int (*p)[10];
解释:p先和*结合,说明p是一个指针变量,然后指针指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫做数组指针。
注:[]的优先级要高于*号,所以必须加上()来保证p先和*结合。
2.2数组指针变量怎么初始化
如果要存放数组的地址,就得存放在数组指针变量中:
1 int arr[10] = {0};
2 int (*p)[10] = &arr;
数组指针类型解析:
int (*p) [10] = &arr;
| | |
| | p指向数组的元素个数
| p是数组指针变量名
p指向的数组的元素类型
三、二维数组传参的本质
#include"stdio.h"
void test(int a[3][5], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
test(arr, 3, 5);
return 0;
}
这里实参是二维数组,形参也写成二维数组的形式
二维数组其实可以看作是每个元素是一维数组的数组,也就是二维数组的每个元素是一个一维数组。那么二维数组的首元素就是第一行,是一个一维数组。
根据数组名是数组首元素的地址这个规则,二维数组的数组名表示的就是第一行的地址,是一维数组的地址。。第一行的一维数组的类型是int [5] ,所以第一行的地址的类型就是数组指针类型 int (*)[5]。那就意味着二维数组传参本质上也是传递了地址,传递的是第一行这个一维数组的地址,那么形参也是可以写成指针形式的。
#include"stdio.h"
void test(int(*p)[5], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("%d ", *(*(p + i) + j));
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
test(arr, 3, 5);
return 0;
}
总结:二维数组传参,形参的部分可以写成数组,也可写成指针形式。
四、函数指针变量
4.1函数指针变量的创建
函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数。
#include"stdio.h"
int test()
{
printf("hehe\n");
return 0;
}
int main()
{
printf("test: %p\n", test);
printf("&test: %p\n", &test);
return 0;
}
输出结果如下:
所以函数是有地址的,函数名就是函数的地址,当然也可以通过&函数名的方式获得函数的地址。
void test()
{
printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)()= test;
int Add(int x, int y)
{
return x+y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的
函数指针类型解析:
int (*pf3) (int x,int y)
| | ___________
| | |
| | pf3指向函数的参数类型和个数的交代
| 函数指针变量名
pf3指向函数的返回类型
int (*) (int x,int y) //pf3函数指针变量的类型
4.2函数指针变量的使用
#include"stdio.h"
int Add(int x, int y)
{
return x + y;
}
int main()
{
int(*pf3)(int, int) = Add;
printf("%d\n", (*pf3)(2, 3));
printf("%d\n", pf3(3, 5));
return 0;
}
输出结果:
4.3typedef关键字
typedef是用来类型重命名的,可以将复杂的类型简答化。
比如:
1 typedef unsigned int uint;
2 //将unsigned int 重命名为uint
但是对于数组指针和函数指针稍微有点区别:
将数组指针类型int (*) [5],重命名为parr_t,那就要写成:
1 typedef int(*parr_t)[5];//新的类型名必须在*的右边
函数指针类型的重命名也是一样的,将void(*)(int)类型重命名为pf_t,就可以这样写:
1 typedef void(*pf_t)(int);//新的类型名必须在*的右边
五、函数指针数组
要把函数的地址存到一个数组中,那这个数组就叫函数指针数组
1 int (*parr1[3])();
parr1先和[]结合,说明parr1是数组,数组的内容是int (*)()类型的函数指针。
标签:变量,int,理解,深入,数组,test,函数指针,指针 From: https://blog.csdn.net/L73S37/article/details/140656016