指针(完结)
#include<stdio.h>#include<stdlib.h>//void test(int a[3][5], int r, int c)//{// int i = 0;// int j = 0;// for (i = 0; i < r; i++)// {// for (j = 0; j < c; j++)// {// printf("%d ", a[i][j]);// }// printf("\n");// }//}//void test(int (*p)[5], int r, int c)//类比一维数组的传参,二维数组传参是二维数组的首地址,即第一行地址,是一个数组指针//{// int i = 0;// int j = 0;// for (i = 0; i < r; i++)// {// for (j = 0; j < c; j++)// {// printf("%d ", *(*(p + i) + j));// }// printf("\n");// }//}//int int_cmp(const void* p1, const void* p2)//{// return (*(int*)p1 - *(int*)p2);//}//void*无类型指针,加(int*)强制转换为int类型,前面加*解引用,这个函数是排序规则说明p1大于p2升序//qsort比较结构体structStu{charname[20];intage;};intcmp_stu_by_age(constvoid*e1,constvoid*e2){return((structStu*)e1)->age-((structStu*)e2)->age;}//强制转换为Stu类型再用->指向ageintcmp_stu_by_name(constvoid*e1,constvoid*e2){returnstrcmp(((structStu*)e1)->name,((structStu*)e2)->name);}intmain(){//int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//printf("&arr[0] = %p\n", &arr[0]);//printf("&arr[0]+1 = %p\n", &arr[0] + 1);//printf("arr = %p\n", arr);//printf("arr+1 = %p\n", arr + 1);//这两个都是数组首地址+1是根据int类型跳4个字节//printf("&arr = %p\n", &arr);//printf("&arr+1 = %p\n", &arr + 1);//&arr+1即跳过整个数组/*const char* pstr = "hello world.";*///这是把字符串的首字母地址放到了pstr中//char str1[] = "hello bit.";//char str2[] = "hello bit.";//const char* str3 = "hello bit.";//const 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)//str3和4指向同一字符串// printf("str3 and str4 are same\n");//else// printf("str3 and str4 are not same\n");//int* p1[10];//指针数组,本质是数组,里面存放的地址//int (*p2)[10];//数组指针本质是指针,指向数组/*int arr[10] = { 0 }; int(*p)[10] = arr; printf("%p\n", p); printf("%p\n", p+1); printf("%p\n", arr); printf("%p\n", arr+1); printf("%p\n", &arr); printf("%p\n", &arr+1);*///由这部分代码可得p(数组指针)和arr(数组首变量地址)和&arr(数组地址)输出的都是首地址//但进行指针运算可以得到p等效&arr(整个数组地址)即+1直接跳出数组//传参,数组名作为参数函数形参,退化成首元素地址,如果arr是函数参数,也就是在函数中sizeof(arr)=1,在函数外arr在sizeof内才升级为整个数组字节数//int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };//test(arr, 3, 5);//在这里arr相当于函数里的形参(*p)[5]////printf("%p", test);//函数地址//如果想储存函数地址//对于无返回值函数可用(*p)()//对于有返回值函数(*p)(变量类型 (变量名可省略) )例(*p)( int x ,int y),xy可以不写//调用函数代码输出可以调用函数//typedef关键字//typedef undesigned int uint 可以把复杂的定义类型转换为简单好写的形式/*int x, y; int input = 1; int ret = 0; int(*p[5])(int x, int y) = { 0, add, sub, mul, div };*///调用四个函数为避免复杂的利用可以这样定义,利用p[input]可以调用四个函数//int(*)()是变量类型,说明存进去的是函数指针,p[5]说明变量是个数组//回调函数,用函数指针调用的函数//像上面那个用数组储存函数地址再调用的思路,可以进一步再写一个函数void calc(int(*pf)(int, int))//分析一下,int(*)(int ,int)是返回值类型 pf是返回值形参,这个整体是说明返回值是函数指针也就是函数名,这样就可以用calc(函数名)直接调用函数,在一些重复编码,只有调用函数不同的环境可用//int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };//int i = 0;//qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);//四个参数arr是读取数组首地址,第二个是数组里元素个数,第三个是每个元素的字节数,最后一个是函数地址,是排序规则//for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)//{// printf("%d ", arr[i]);//}//printf("\n");//qsort比较结构体structStus[]={{"zhangsan",20},{"lisi",30},{"wangwu",15}};intsz=sizeof(s)/sizeof(s[0]);inti=0;qsort(s,sz,sizeof(s[0]),cmp_stu_by_age);for(i=0;i<3;i++){printf("%s %d\n",s[i].name,s[i].age);}qsort(s,sz,sizeof(s[0]),cmp_stu_by_name);for(i=0;i<3;i++){printf("\n%s %d\n",s[i].name,s[i].age);}//sizeof和strlen//sizeof是操作符,是求所占字节数,strlen是库函数所求字符串长度,\0前面的字符数量return0;}