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<><> |
|