#c语言学习—指针程序设计

冒泡排序法是初学者接触的常用排序法,但是其只能排序整型数组,float或者char类型则都不能比较

void bubble_sort(int arr[],int sz)
{
    int i, j = 0;
    for (i = 0;i<sz - 1; i++)
    {
        for (j = 0; j < sz - i-1; j++)
        {
            int temp = 0;
            if (arr[j] > arr[j + 1])
            {
                temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
            }
        }
    }

}



int main()
{
    int arr[] = { 10,9,8,7,6,5,4,3,2,1 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    bubble_sort(arr,sz);
    for (i = 0; i < sz; i++)
    {
        printf("%d ",arr[i]);
    }
    return 0;
}

C语言提供了qsort函数来对不同类型的数据进行排序

void qsort(void* base,//目标数组起始位置
           size_t num,//数组大小
           size_t width,//元素大小
           int(_cdc1*compare)((const void* elem1,const void* elem2))//比较函数的函数指针,函数是一个自定义函数,要求是elment1大时返回大于0的数,相等返回0,小于返回小于0的数,对于不同的类型比较,要自定义不同的函数来进行处理

void * 的解释说明

对于int a=10;来说
应该用int p=&a;来接收a的地址
当然也可以char
p=&a,int 和char只是决定p指针能访问空间的大小
而void *p 是能接收任何类型的指针,比如char int float double等都可以
因为qsort是一个泛化函数,需要接收各种数组类型,所以就需要用void *来接收地址
void *p的使用需要注意的是,void型的指针在使用时不能做解引用操作和地址加减操作,因为void型的指针不知道指针p能够访问空间的大小,仅仅作为接收首地址使用

 int com_int(const void *element1, const void *element2)//qsort的泛化性要求其函数的参数是void*,所以具体自定义函数在接收的时候也要用void来接收
{
      //比较两个整型值
    return  *((int*)element1) - *((int*)element2);
      //但是具体的自定义函数是知道所比较的类型的,所以要对void指针进行强转后再进行解引用操作,函数要返回一个数
}

int main()
{
    int arr[] = { 10,9,8,7,6,5,4,3,2,1 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    qsort(arr,sz,sizeof(arr[0]),com_int);
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

在上述代码基础上加入了float型数组的比较

 int com_int(const void *element1, const void *element2)
{
      //比较两个整型值
    return  *((int*)element1) - *((int*)element2);
      //qsort的泛化性要求其函数的参数是void*,所以具体自定义函数在接收的时候也要用void来接收
      //但是具体的自定义函数是知道所比较的类型的,所以要对void指针进行强转后再进行解引用操作
}
 int com_float(const void* element1, const void* element2)
 {
     if (*((float*)element1) > *((float*)element2))
         return 1;
     else if (*((float*)element1) == *((float*)element2))
         return 0;
     else
         return -1;
         //或者return  (int)(*((float*)element1)) - (int)(*((float*)element2));
 }
        
 void test1()
 {
     int arr[] = { 10,9,8,7,6,5,4,3,2,1 };
     int sz = sizeof(arr) / sizeof(arr[0]);
     int i = 0;
     qsort(arr, sz, sizeof(arr[0]), com_int);
     for (i = 0; i < sz; i++)
     {
         printf("%d ", arr[i]);
     }
     printf("\n");
 }
 void test2()
 {
     float f[] = {10.0,9.0,8.0,7.0,6.0};
     int sz = sizeof(f) / sizeof(f[0]);
     int i = 0;
     qsort(f, sz, sizeof(f[0]), com_float);
     for (i = 0; i < sz; i++)
     {
         printf("%f ", f[i]);
     }
     printf("\n");
 }
int main()
{
    test1();
    test2();
    return 0;
}

结构体排序

struct Stu
{
    char name[20];
    int age;
};
int com_by_age(const void* e1, const void* e2)
{
    return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int com_by_name(const void* e1, const void* e2)
{
    //比较名字就是比较字符串,要用strcmp来比较
    return strcmp(((struct Stu*)e1)->name , ((struct Stu*)e2)->name);
}
 void test3()
 {
     struct Stu s[3] = { {"zhangsan",23},{"lisi",43},{"wangxianglong",22}};
     int sz = sizeof(s) / sizeof(s[3]);
     qsort(s,sz,sizeof(s[0]),com_by_age);
     qsort(s, sz, sizeof(s[0]), com_by_name);

 }
int main()
{
    test3();
    return 0;
}

尝试自定义sort相关函数进行泛化排序

struct Stu
{
    char name[20];
    int age;
}; 
 void Swap(char* buf1, char* buf2, int width)//逐字节交换
 {
     int i = 0;
     for (i = 0; i < width; i++)
     {
         char temp = *buf1;
         *buf1 = *buf2;
         *buf2 = temp;
         buf1++;
         buf2++;
     }

 }
 void bubble_sort(void* base, int sz, int width, int(*cmp_fun)(const void* e1, const void* e2))
 {
     int i = 0;
     for (i = 0; i < sz - 1; i++)
     {
         int j = 0;
         for (j = 0; j < sz - i - 1; j++)
         {
             if (cmp_fun((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
             {
                 //交换
                 Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
             }
         }
     }
 }
int com_int(const void* element1, const void* element2)//qsort的泛化性要求其函数的参数是void*,所以具体自定义函数在接收的时候也要用void来接收
{
    //比较两个整型值
    return  *((int*)element1) - *((int*)element2);
    //但是具体的自定义函数是知道所比较的类型的,所以要对void指针进行强转后再进行解引用操作,函数要返回一个数
}
int com_float(const void* element1, const void* element2)
{
    if (*((float*)element1) > *((float*)element2))
        return 1;
    else if (*((float*)element1) == *((float*)element2))
        return 0;
    else
        return -1;
    //或者return  (int)(*((float*)element1)) - (int)(*((float*)element2));
}
int com_by_age(const void* e1, const void* e2)
{
    return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int com_by_name(const void* e1, const void* e2)
{
    //比较名字就是比较字符串,要用strcmp来比较
    return strcmp(((struct Stu*)e1)->name , ((struct Stu*)e2)->name);
}

void test1()
{
    float f[] = { 10.0,9.0,8.0,7.0,6.0 };
    int sz = sizeof(f) / sizeof(f[0]);
    int i = 0;
    bubble_sort(f, sz, sizeof(f[0]), com_float);
    for (i = 0; i < sz; i++)
    {
        printf("%f ", f[i]);
    }
    printf("\n");
}
void test2()
{
    struct Stu s[3] = { {"zhangsan",23},{"lisi",43},{"wangxianglong",22} };
    int sz = sizeof(s) / sizeof(s[3]);
    bubble_sort(s,sz,sizeof(s[0]),com_by_age);
    

}
void test3()
{
    struct Stu s[3] = { {"zhangsan",23},{"lisi",43},{"wangxianglong",22} };
    int sz = sizeof(s) / sizeof(s[3]);
    //qsort(s,sz,sizeof(s[0]),com_by_age);
    bubble_sort(s, sz, sizeof(s[0]), com_by_name);

}
 void test4()
 {
     int arr[] = {1,2,3,4,5,6,7,8,9};
     int sz = sizeof(arr) / sizeof(arr[0]);
     int i = 0;
     bubble_sort(arr,sz,sizeof(arr[0]),com_int);
     for (i = 0; i < sz; i++)
     {
         printf("%d ", arr[i]);
     }
     printf("\n");
 }
int main()
{
    test1();//float排序
    test2();//age排序
    test3();//int 排序
    test4();// name排序
    

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值