- 一 指针
- 二 面试题目练习
void* 类型的指针 可以接受任意类型的地址 void* 类型的指针 不能进行解引用操作 void* 类型的指针 不能进行+-整数的操作
#include#include struct stu { char name[20]; int age; }; void qsort(void* base, size_t num, size_t width, int(*cmp)(const void* eleml, const void* elem2) ); int cmp_int(const void* e1, const void* e2) { //比较两个整形的值 return *(int*)e1 - *(int*)e2; } int main() { int arr[10] = {9,8,7,6,5,4,3,2,1,0}; int sz = sizeof(arr) / sizeof(arr[0]); struct stu s[3] = { {"zhangsan",20},{"list",30},{"wangwu",10}}; float f[] = {9.0,8.0,7.0,6.0,4.0}; qsort(arr,sz, sizeof(arr[0]), cmp_int); for (int i = 0; i < sz; i++) { printf("%d ",arr[i]); } }
#include#include struct stu { char name[20]; int age; }; int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int cmp_stu_by_age(const void *e1,const void *e2) { return ((struct stu*)e1)->age - ((struct stu*)e2)->age; } int cmp_stu_by_name(const void* e1, const void* e2) { strcmp(((struct stu *)e1)->name,((struct stu*)e2)->name); } void test2() { struct stu s[3] = { {"a",30},{"b",20},{"c",10}}; int sz = sizeof(s) / sizeof(s[0]); qsort(s, sz, sizeof(s[0]), cmp_stu_by_age); for (int i = 0; i < sz; i++) { printf("%s %d n",s[i].name,s[i].age); } } void test3() { struct stu s[3] = { {"a",30},{"b",20},{"c",10}}; int sz = sizeof(s) / sizeof(s[0]); qsort(s, sz, sizeof(s[0]), cmp_stu_by_name); for (int i = 0; i < sz; i++) { printf("%s %d n",s[i].name,s[i].age); } } int main() { test2(); test3() return 0; }
#include#include struct stu { char name[20]; int age; }; void swap(char* buf1, char* buf2, int width) { for (int i = 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++; buf2++; } } void bubble_sort(void *base, int sz,int width,int(*cmp)(void *e1,void *e2)) { for (int i = 0; i < sz - 1; i++) { for (int j = 0; j < sz - 1 - i; j++) { if (cmp((char *)base+j*width,(char*)base+(j+1)*width)>0) { swap((char*)base + j * width, (char*)base + (j + 1) * width,width); } } } } int cmp_stu_by_age(const void *e1,const void *e2) { return ((struct stu*)e1)->age - ((struct stu*)e2)->age; } int cmp_stu_by_name(const void* e1, const void* e2) { return strcmp(((struct stu *)e1)->name,((struct stu*)e2)->name); } void test5() { struct stu s[3] = { {"a",30},{"e",20},{"c",10} }; int sz = sizeof(s) / sizeof(s[0]); bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_name); for (int i = 0; i < sz; i++) { printf("%s %d n",s[i].name,s[i].age); } } int main() { test5(); return 0; }
#include#include int main() { //1、 sizeof(数组名)——数组名表示整个数组 //2、 &数组名——数组名表示整个数组 //3、 其他情况下——数组名时首元素地址 int a[] = {1,2,3,4}; printf("%dn",sizeof(a)); //16 sizeof(数组名)——计算的是整个数组的大小 4*4=16字节 printf("%dn",sizeof(*&a)); //16 &a取出的是数组的地址,数组的地址解引用访问数组 //sizeof(*&a)就是计算数组的大小(单位是字节) printf("%dn",sizeof(a+0)); //4/8 数组名首元素的地址 a+0还是首元素的地址 printf("%dn",sizeof(&a[0])); //4/8 &a[0]第一个元素的地址 printf("%dn",sizeof(&a[0]+1));//4/8 &a[0]+1第二个元素的地址 printf("%dn",sizeof(a+1)); //4/8 数组名首元素的地址 a+1就是第二个元素的地址 printf("%dn",sizeof(*a)); //4 a[0]的大小——4字节 printf("%dn",sizeof(a[1])); //4 a[1]的大小——4字节 printf("%dn",sizeof(&a)); //4/8 &a整个数组的地址,本质还是一个地址 printf("%dn",sizeof(&a+1)); //4/8 &a是整个数组的地址 &a+1虽然地址体跳过整个数组 但还是地址 printf("----------------------------------------------n"); char arr1[] = { 'a','b', 'c','d','e','f'}; printf("%dn",sizeof(arr1)); //6 计算整个数组的大小 6*1=6 printf("%dn",sizeof(arr1+0)); //4/8 首元素地址 printf("%dn",sizeof(*arr1)); //1 首元素 printf("%dn",sizeof(arr1[1])); //1 第二个元素 printf("%dn",sizeof(&arr1)); //4/8 整个数组的地址 printf("%dn",sizeof(&arr1+1)); //4/8 跳过整个数组 但还是个数组 printf("%dn",sizeof(&arr1[0]+1)); //4/8 第二个元素的地址 printf("----------------------------------------------n"); char arr[] = "abcdef"; printf("%dn",strlen(arr)); //6 printf("%dn",strlen(arr+0)); //6 //printf("%dn",strlen(*arr)); //err //printf("%dn",strlen(arr[1])); //err printf("%dn",strlen(&arr)); //6 数组的地址—数组指针 char(*p)[7]=&arr printf("%dn",strlen(&arr+1)); //随机值 printf("%dn",strlen(&arr[0]+1)); //5 printf("----------------------------------------------n"); char* p = "abcdef"; printf("%dn",sizeof(p)); //4/8 计算指针的大小 printf("%dn",sizeof(*p)); //1 计算第一个字符的大小 6*1=6字节 printf("%dn",sizeof(p[0])); //1 第一个字符;p[0] == *(p+0)=='a' printf("%dn",sizeof(&p)); //4/8 整个字符串的地址 printf("%dn",sizeof(&p+1)); //4/8 跳过整个字符串 但还是地址 printf("%dn",sizeof(p+1)); //4/8 第二个字符的地址 printf("%dn",sizeof(&p[0] + 1)); //4/8 第二个字符的地址 printf("----------------------------------------------n"); printf("%dn",strlen(p)); //6 printf("%dn",strlen(p+1)); //5 //printf("%dn",strlen(*p)); //err //printf("%dn",strlen(p[0])); //err printf("%dn",strlen(&p)); //随机值 printf("%dn",strlen(&p+1)); //随机值 printf("%dn",strlen(&p[0] + 1)); //5 printf("----------------------------------------------n"); int a2[3][4] = { 0 }; printf("%dn",sizeof(a2)); //48 12*4=48字节 printf("%dn",sizeof(a2[0][0])); //4 第一行第一个元素的大小 printf("%dn",sizeof(a2[0])); //16 a2[0] 相当于第一行作为一维数组的数组名 //计算第一行的大小 printf("%dn",sizeof(a2[0]+1)); //4/8 a2[0]+1 第一行的第二个元素的地址 printf("%dn",sizeof(*(a2[0]+1))); //4 第一行第二个元素的大小 printf("%dn",sizeof(a2+1)); //4/8 a2是二维数组的数组名, //没有sizeof(a2),也没有&(a),所以a2是首元素的地址 //而把二维数组看成一维数组时,二维数组的首元素是它的第一行,a2就是第一行的首元素的地址 //a2+1就是第二行的地址 printf("----------------------------------------------n"); printf("%dn",sizeof(*a2)); //16 a2是首元素地址——第一行的地址;*a2就是第一行;所以计算的是第一行的大小 printf("%dn",sizeof(*(a2+1))); //16 sizeof(*(a2+1)) 计算的是第二行的大小 printf("%dn",sizeof(*(&a2[0] + 1))); //16 计算第二行的大小 printf("%dn",sizeof(&a2[0] + 1)); //4/8 第二行的地址 printf("%dn",sizeof(a2[3])); //16 不用管数字 数组名——首元素(行)地址 }



