1.指针数组和数组指针区分
指针数组是存放指针的数组,实质上是数组。数组指针是指向数组的指针,实质上是指针。
1.1指针数组
比如int*arr[10];这里怎么理解,这里的arr[10]就是数组,数组中存放的是int类型的指针。
用例子来说:
#include
#include
1.2数组指针
比如int(*arr)[10];这里的意思是arr是个指针,这个指针指向一个数组,数组中有十个元素,每个元素都是int类型。这里可以借用int*arr;类比,这里的意思是指向整型的指针变量arr。
这里需要注意的是&arr和arr,认识到这个数组指针,这里对其再次解读。
点击加载图片
这里的&arr的类型是int(*)[10];是一个数组指针类型,其他的是整型指针类型,所以&arr+1跳过的是整个数组。
打印一维数组元素:
#include
打印二维数组:
#include
再来看看这个是什么鬼?
int(*parr[10])[5];
这个是什么东西?
首先它可拆分为两个int(*)[5]和parr[10],这里的意思是parr是存放数组指针的数组。
2.数组参数和指针参数
2.1一维数组传参
intarr[10]={0};
可以用intarr[]和intarr[10]和int*arr接收。
int*arr[10]={0};
这里的arr可以用int*arr[10]和int**arr接收。
2.2二维数组传参
intarr[3][5]={0};
这里的arr可以用intarr[3][5]和intarr[][5]和int(*arr)[5]接收,其他的都不行。
2.3一级指针传参
voidtest(int*p){}
2.4二级指针传参
voidtest(int**ptr){}
这里的int**ptr可以用二级指针和&一级指针和指针数组传参。
3.函数指针
点击加载图片
这里的函数名就是函数的地址。
这里用这个Add来写一下函数指针,void(*padd)(intx,inty);这个就是函数指针,首先把padd和void(*)(intx,inty)分开,首先是一个指针,这个指针的类型是函数,指向函数,这个函数的参数是x和y,返回值是void。
上述代码改进
intAdd(intx,inty){returnx+y;}intmain{inta=10;intb=20;int(*padd)(intx,inty)=&Add;intret=padd(3,5);printf('%d\n',ret);return0;}//结果是8
下面来看看这个代码是什么意思?
(*(void(*)())0)();
解释:void(*)()是函数指针类型,把0强制类型转换为函数指针类型,调用0地址处的函数。这里这个代码也可以写成(void(*)())0();
void(*signal(int,void(*)(int))(int);
解释:上述代码是函数声明,声明的函数叫做signal,函数的第一个参数是int类型,第二个参数是函数指针类型,该函数指针指向的函数参数是int,返回类型是void,signal函数的返回类型也是一个函数指针,该函数指针指向的函数参数是int,返回类型是void。
4.函数指针数组
比如:int(*p[3])(intx,inty);这里p是指数组,p中存放的是函数指针。
#include
5.指向函数指针数组的指针
函数指针数组:int(*p[3])(intx,inty);
指向函数指针数组的指针:int(*(*p)[3])(intx,inty);
6.回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
上述模拟计算器可以这样来写(利用回调函数):
#include
6.1.qsort库函数
初步了解:
点击加载图片
再次理解:
qsort库函数可以对任意类型数据进行排序,其原理类似于快速排序。
base:待排序数组的起始地址
num:待排序数据的元素个数
size:待排序数组的元素的大小
int(*compare)(constvoid*,constvoid*):比较两个元素的大小的函数指针
6.1.1qsort库函数排序整型数组
intcompare(constvoid*a,constvoid*b){return*(int*)a-*(int*)b;}voidprint(intarr[],intsz){inti=0;for(i=0;i
6.1.2qsort库函数排序结构体数据
6.1.2.1按照名字大小来排序
structstu{charname[20];intage;};intcmp_by_name(constvoid*a,constvoid*b){returnstrcmp(((structstu*)a)->name,((structstu*)b)->name);}voidprint(structstus[],intsz){inti=0;for(i=0;i
6.1.2.2按照年龄来排序
structstu{charname[20];intage;};intcmp_by_age(constvoid*a,constvoid*b){return(((structstu*)a)->age-((structstu*)b)->age);}voidprint(structstus[],intsz){inti=0;for(i=0;i
6.2实现冒泡排序对任意类型的排序
6.2.1对整型排序
intcmp_int(constvoid*e1,constvoid*e2){return(*(int*)e1-*(int*)e2);}voidSwap(char*buf1,char*buf2,intsize){inti=0;for(i=0;i<><>
6.2.2对结构体排序
6.2.2.1按照年龄进行排序
structstu{charname[20];intage;};intcmp_by_age(constvoid*a,constvoid*b){return(((structstu*)a)->age-((structstu*)b)->age);}voidSwap(char*buf1,char*buf2,intsize){inti=0;for(i=0;i<><>
6.2.2.2按照名字排序
structstu{charname[20];intage;};intcmp_by_name(constvoid*a,constvoid*b){returnstrcmp(((structstu*)a)->name,((structstu*)b)->name);}voidSwap(char*buf1,char*buf2,intsize){inti=0;for(i=0;i<><>
联系客服