字符指针
#include <stdio.h>
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
char* str3 = "hello bit.";
char* str4 = "hello bit.";
if (str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if (str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
指针数组
指针数组是指针还是数组呢? 我们需要看后缀(包括后面讲到的数组指针,函数指针等等)。
所以,指针数组明显是数组
int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组
可以查表了解 [ ] 和 * 的优先级帮助理解。
arr1,arrr2,arr3和[ ]先结合,说明他们是数组,然后每个元素分别是int* char* char**
数组指针
看后缀,所以是指针
int (*p2)[10]; //*说明p2是指针,int [10]说明p2指向的是一个10个元素的数组,每个元素是int
数组名实际含义详解
我们要学好指针的进阶,必须掌握数组名的实际意义。
先看看一维数组
说明了什么? arr实际上是首元素的地址,而&arr取出的是整个数组的地址,&arr+1当然会跳过整个数组。
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p 。
在来看看二维数组
二维数组实际上就是多个一维数组,int arr[3][5]实际上是3个一维数组。每个数组5个元素。
这也是二维数组为什么行标可以省略,而列标不能省略的原因。
int arr[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4]=arr; //数组指针这样应用是可以的
知识点回顾
int arr[5]; //5个元素的数组,每个元素的类型是int
int *parr1[10]; // parr1首先和[]结合,说明是数组。该数组有10个元素,每个元素的类型int* 。所以是指针数组
int (*parr2)[10];//parr2首先和*结合,说明是指针,指向了一个含有10个元素的数组,每个元素的类型是int,所以是数组指针
int (*parr3[10])[5];// parr3首先和[]结合,是一个数组,含有10个元素,每个元素的类型是int(*)[5],即数组指针,该指针指向一个含有5个元素的数组,每个元素的类型是int
一维数组的传参
二维数组传参
函数指针
void test()
{
printf("hehe\n");
}
//下面pfun1和pfun2哪个有能力存放test函数的地址?
void (*pfun1)(); //显然是pfun1,首先和*结合,说明他是指针,然后参数为空,返回类型为空
void *pfun2();
看看两段让人难受的代码
(*(void (*)())0)();// 首先将0强制类型转换成void(*)()类型的函数指针,该函数指针没有参数,返回类型void,然后解引用调用0地地址处的函数
void (*signal(int , void(*)(int)))(int); //首先signal没有和*结合,所以他不是指针,而是函数声明,该函数声明有两个参数,
//一个是int,一个是函数指针,该函数指针的参数是int,返回类型是void,
//然后函数声明的返回类型是函数指针void(*)(int),该函数指针参数是int,返回类型是void.
//可以简化成
//typedef void(*pfun_t)(int);
//pfun_t signal(int, pfun_t);
函数指针数组
看后缀,他是数组
例如
int (*parr1[10])(); //首先parr1和[]结合,是一个数组,每个元素的类型是int(*)();也就是函数指针
指向函数指针数组的指针
指向函数指针数组的指针是一个 指针
指针指向一个 数组 ,数组的元素都是 函数指针
void test(const char* str) {
printf("%s\n", str);
}
int main()
{
//函数指针pfun
void (*pfun)(const char*) = test;
//函数指针的数组pfunArr
void (*pfunArr[5])(const char* str);
pfunArr[0] = test;
//指向函数指针数组pfunArr的指针ppfunArr,
//该*说明ppfunArr是一个指针,[10],说明他指向了一个含有10个元素的数组
//该数组的每个元素的类型是void(*)(const char*)
void (*(*ppfunArr)[10])(const char*) = &pfunArr;
return 0;