指针与数组
int arr[5];
//这是一个整型数组,每个元素是int型,有五个元素
int* parr1[10];
//这是一个数组,数组十个元素,每个元素类型是int *
int(*parr2)[10];
//这是一个指针,指向的数组有十个元素,每个元素类型是int
//可理解成int(*)[10]
int(*parr3[10])[5];
//这是一个数组,数组有十个元素,每个元素的类型是int(*)[5]
//parr3是存放数组指针(int(*)[5])的数组[10]
由上面可以理解 区分数组和指针区别根本在于“名称”到底先跟*还是[]结合。如(* parr1[ ])这样的,parr1优先与[ ]结合,因此这是数组;而(*parr)[ ]由于括号限制,parr优先与*结合,因此这是指针。
函数指针
定义一个简单加法函数
int Add(int x, int y)
{
return x + y;
}
int main()
{
int (*pf)(int , int) = Add;
}
这其中pf是函数指针变量,调用Add函数也可以写成这种形式,类似把Add函数进行改名。
printf("%d\n", (*pf)(1, 2));
printf("%d\n", pf(1, 2));
(*(void (*)( ) ) 0 )( )
void (*)()是函数指针类型
(void (*)() ) 0 强制类型转换,意味着0地址处放着一个 返回类型是void 无参的函数
*(void (*)())0 对零地址处解引用
(*(void (*)())0)()调用0地址这个函数
void (* signal (int , void (*) ( int ) ) ) ( int )
这是一个函数声明,可以写成一种错误但是容易理解的形式
void (*)(int) signal (int , void(*)(int) )
返回类型 函数名 函数参数
这样看来,signal是一个函数,函数参数是int 和一个函数指针 void(*)(int),返回类型也是一个函数指针void (*)(int)。
函数指针数组
根据“指针和数组”分析中,一个数组名称先和[ ]结合,除开数组名和[]的部分就是数组元素类型。
int (* p[4] ) ( int , int )
// 这是函数指针数组,数组里面有四个元素
// 元素类型为函数指针: int (*) ( int , int )
//函数指针
int (*pf)(int, int) = Add;
//函数指针数组
int (* pfarr[4])(int, int);
// p3指向函数指针数组的指针
int (* (*p3)[4])(int ,int) = &pfarr;
qsort
void qsort(void* base,//排序数组起始位置
size_t num,//数组的元素个数
size_t width,//一个元素的字节大小
int(*cmp)(const void* e1, const void* e2));
//比较函数(需要自定义) 比较两个元素地址