qsort函数
qsort(s,sz,sizeof(s[0]),cmp_stu_by_name);
第一个参数:待排序数组的首元素地址
第二个参数:待排序数组的元素个数
第三个参数:待排序数组的每个元素的大小-单位是字节
第四个参数:是函数指针,比较两个元素的所用函数的地址-这个函数使用者自己实现函数指针的两个参数是:待比较的两个元素的地址
如下是以模拟qsort函数自创一个以冒泡排序为方法的排序函数。
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
struct Stu
{
char name[20];
int age;
};
//void qsort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2));
int cmp_int(const void* e1, const void*e2)
{
//比较两个整型值的
return *(int*)e1 - *(int*)e2;
}
void test1()
{
int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; ++i)
{
printf("%d ", arr[i]);
}
}
int cmp_float(const void* e1, const void*e2)
{
if (*(float*)e1 == *(float*)e2)
{
return 0;
}
else if (*(float*)e1> *(float*)e2)
{
return 1;
}
else
{
return -1;
}
}
void test2()
{
float f[] = { 9.0,8.0,7.0,6.0 ,5.0,4.0 };
int sz = sizeof(f) / sizeof(f[0]);
qsort(f, sz, sizeof(f[0]), cmp_float);
int i = 0;
for (i = 0; i < sz; ++i)
{
printf("%f ", f[i]);
}
}
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 test3()
{
struct Stu s[3] = { { "Zhangsan",20 },{ "Lisi",30 },{ "Wangwu",10 } };
int sz = sizeof(s) / sizeof(s[0]);
//qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (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)(const void* e1, const void* e2))
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (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);
}
}
}
}
void test4()
{
int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
}
void test5()
{
struct Stu s[3] = { { "Zhangsan",20 },{ "Lisi",30 },{ "Wangwu",10 } };
int sz = sizeof(s) / sizeof(s[0]);
bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
int main()
{
//test1();
//printf("\n");
//test2();
//printf("\n");
//test3();
test4();
//test5();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
//数组名是首元素的地址
//1.sizeof(数组名)-数组名表示整个数组
//2.&数组名-数组名表示整个数组
//
//一维数组
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16 sizeof(数组名)-计算的是数组总大小-单位是字节
printf("%d\n", sizeof(a + 0));//4/8 数组名这里表示首元素的值,a+0还是首元素地址,地址的大小就是4/8个字节
printf("%d\n", sizeof(*a));//4 数组名表示首元素地址,*a就是首元素,sizeof(*a)就是4
printf("%d\n", sizeof(a + 1));//4/8 数组名这里表示首元素的值,a+1是第2个元素的地址,地址的大小就是4/8个字节
printf("%d\n", sizeof(a[1]));//4 第2个元素的大小
printf("%d\n", sizeof(&a));//4/8 &a取出的是数组的地址,但是数组的地址那也是地址,地址的大小就是4/8个字节
printf("%d\n", sizeof(*&a));//16 &a是数组的地址,数组的地址解引用访问的数组,sizeof计算的就是数组的大小,单位是字节
printf("%d\n", sizeof(&a+1));//4/8 &a是数组的地址,&a+1虽然地址跳过整个数组,但还是地址,所以是4/8个字节
printf("%d\n", sizeof(&a[0]));//4/8 &a[0]第一个元素的地址
printf("%d\n", sizeof(&a[0]+1));//4/8 &a[0]+1是第二个元素的地址
return 0;
}
问:
int a[4];printf("%d\n", sizeof(a));
为什么这个输出是16?指针大小不是只有4吗?
ChatAI答:首先需要指出的是,a 并不是一个指针,而是一个整型数组,所以其大小应该是 4 * sizeof(int),一般情况下,sizeof(int) 的结果为 4 字节,所以 sizeof(a) 的结果应该为 16 字节,这是因为数组中有 4 个元素,每个元素占用 4 个字节。
如果你把 a 声明为指针,例如 int *a;,那么输出的结果应该是 4,因为指针大小通常是与机器的位数相关的,32 位指针占用 4 个字节,64 位指针占用 8 个字节。
问:
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a+0));
为什么第二个输出是4而不是16?
ChatAI答:
在第二个输出中,a+0其实是对a数组的取地址运算,它相当于&a[0],仍然是一个指向整型的指针,所以其大小仅为 4 个字节,而不是整个数组 a 的大小 16 字节。
需要注意的是,在 sizeof 运算符中,对数组名字取大小运算并不会真正地求出数组所占内存的总大小,而是只会计算数组占用内存的字节数。在a+0中,数组名字 a 被写成了指针形式,因此 sizeof(a+0) 的结果是指针变量的大小,也就是 4 字节。
#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6 sizeof计算的是数组大小,6*1=6个字节
printf("%d\n", sizeof(arr + 0));//4/8 arr是首元素的地址,arr+0还是首元素的地址,地址大小是4/8字节
printf("%d\n", sizeof(*arr));//1 arr是首元素地址,*arr就是首元素,首元素是字符大小是一个字节
printf("%d\n", sizeof(arr[1]));//1 arr是第二个元素
printf("%d\n", sizeof(&arr));//4/8 &arr虽然是数组的地址,但还是地址,地址的大小是4/8个字节
printf("%d\n", sizeof(&arr + 1));//4/8 &arr+1是跳过整个数组后的地址,地址大小是4/8个字节
printf("%d\n", sizeof(&arr[0] + 1));//4/8 第二个元素的地址
return 0;
}