一.字符指针
我们都知道,有一种指针类型是char*,一般存放字符的地址
比如存放的是单个字符,我们可以直接用%c将其打印,也可以存放字符串的首地址
可用%p将其打印,
二.指针数组
和整型数组,字符数组一样,指针数组就是存放指针的数组,比如 int* arr[10];创建了一个指针数组,有10个元素,每个元素的类型都是int*,以前的<<指针初阶>>里说明过,在这里不再详细介绍用法
三.数组指针
之前提起了指针数组,但数组指针可不一样,指针数组是一个数组,数组指针是一个指针,存放的是数组的地址,我们以前学过,数组的地址就是首元素的地址,但在这里不一样,我们看
在指针初阶我们讲过,指针+-,会根据指针类型跳过数据,arr是数组首元素地址,他们虽然相同,但跳过的字节不一样,观察他们的地址,我们可以知道,&arr+1,直接跳过了整个数组,所以存放数组地址的指针应该与其不同,
比如上面,
int (*p)[10];解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。这里要注意:[]的优先级要高于*号的,所以必须加上( )来保证p先和*结合。
数组指针与指针数组容易混淆,注意区分,
数组指针的使用
我们可以用数组指针表示二维数组,以前我们都知道在函数中,一维数组传参,可以写成指针的形式,二维数组也可以,二维数组可以看作存放了几个一维数组地址的数组指针的指针数组,比如
void print_arr(int(*arr)[5], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%d ", (*(arr+i))[j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
print_arr(arr, 3, 5);
return 0;
}
可以用数组指针表示二维数组传参,
再说明一个小知识点,*(arr+i)==arr[i];所以可以把arr[i][j]写成(*(arr+i))[j];当然也可以直接写成arr[i][j],
四.函数指针
既然很多东西都有地址,那么函数也不例外,函数也有自己的地址,
可以得出函数的地址就是函数名,那我们如何储存一个函数的地址
解释;要储存一个函数的地址,上面p为指针变量名,后面的()表示函数的参数,因为这个函数没有参数,
所以不写,最前面是函数的返回类型,之后我们就可以调用 指针变量(参数) 来调用这个函数,
例
我们来看两个有意思的代码
(*(void (*)())0)();
void (*signal(int, void(*)(int)))(int);
第一个非常经典,它是一个函数调用,调用的是地址为0出的函数,
第二个是个函数声明 声明了一个函数,它有两个参数,一个是int,一个是void(*)(int),返回值是函数指针类型