Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用指针的通用冒泡排序程序_C_Arrays_Pointers_Char - Fatal编程技术网

C 使用指针的通用冒泡排序程序

C 使用指针的通用冒泡排序程序,c,arrays,pointers,char,C,Arrays,Pointers,Char,根据我先前的问题: 我解决了这个问题,得到了以下代码 #include <stdio.h> #include <stdlib.h> #include <string.h> void bubble_sort (void* base, size_t num, size_t width, int (*compar)(const void*,const

根据我先前的问题:

我解决了这个问题,得到了以下代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bubble_sort (void* base, 
                  size_t num, 
                  size_t width,
                  int (*compar)(const void*,const void*)){
    int i,j,k;
    unsigned char *ptr = base;
    unsigned char tmp[256];

    if(num < 2 || width == 0)
        return;

    for(i = num-1; i >= 0; i--)
    {
        for(j = 1; j <= i; j++)
        {
            k = compar((void*)(ptr + width * (j-1)), (void*)(ptr + width * j));
            if(k > 0)
            {
                memcpy(tmp, ptr + width*(j-1), width);
                memcpy(ptr + width*(j-1), ptr + width*j, width);
                memcpy(ptr + width * j, tmp, width);
            }
        }
    }
}

int compare_int(const void *a, const void *b)
{
    int *c = (int *)a;
    int *d = (int *)b;
    return *c - *d;
}

int compare_string(const void *a, const void *b)
{
    const char *c = (char *)a;
    const char *d = (char *)b;
    return strcmp(c, d);
}
#包括
#包括
#包括
void bubble_排序(void*base,
大小_tnum,
尺寸和宽度,
int(*比较)(常量无效*,常量无效*){
int i,j,k;
无符号字符*ptr=base;
无符号字符tmp[256];
如果(num<2 | | width==0)
返回;
对于(i=num-1;i>=0;i--)
{
对于(j=1;j 0)
{
memcpy(tmp,ptr+宽度*(j-1),宽度);
memcpy(ptr+width*(j-1),ptr+width*j,width);
memcpy(ptr+宽度*j,tmp,宽度);
}
}
}
}
整数比较整数(常数无效*a,常数无效*b)
{
int*c=(int*)a;
int*d=(int*)b;
返回*c-*d;
}
int比较_字符串(常量无效*a,常量无效*b)
{
常量char*c=(char*)a;
常量char*d=(char*)b;
返回strcmp(c,d);
}
现在,这项功能可以完美地用于:

  • Int,Long等数组,如
    inta[]={1,3,4,52,2,3}
  • 字符数组,如
    chara[5][20]={“jhsa”、“asndb”、“drtfe”、“nhurh”、“bvhr”}
  • 但是我想用
    char*
    数组实现它,比如:

  • char*a[]={“jhsa”、“asndb”、“drtfe”、“nhurh”、“bvhr”}
  • 尝试了一点,但遇到了分段错误

    所以我需要一些帮助

    您正在将变量“a”声明为字符指针(字符串)。但是你有一个字符串数组

    因此“a”应该是这样的

    char *a[] = { "jhsa", "asndb", "drtfe", "nhurh", "bvhr"};
    

    此外,还应该为变量指定更有意义的名称。在这种情况下,字符串或单词会更清晰。

    第一个注释声明:

    char *a = { "jhsa", "asndb", "drtfe", "nhurh", "bvhr"};
    
    如果不正确,则应如下所示:

    char *a[] = { "jhsa", "asndb", "drtfe", "nhurh", "bvhr"}; 
    
    这是一个字符指针数组。[i]
    中的每个索引都指向一个字符串文本

    问题在于你的比较函数。前两个数组是值数组,而
    a[]
    是指针数组。 阅读以了解
    char*a[]
    的内存组织与
    char[][]
    (二维连续分配内存组织)的不同之处

    在传递
    a[i]
    地址(但不传递
    a[i]
    自身)的
    compare()函数中发生了什么。当
    a[i]
    是一个值地址时,它可以工作,例如
    int[]
    char[][]
    而在
    char*[]
    的情况下,您不是传递值的地址,而是传递值的地址。我认为您的主要混淆是在2D字符数组
    char[][]
    和文本字符串数组
    char*[]
    之间传递

    首先了解传递给比较函数的是什么,假设您有以下数组,那么您传递的是内容地址
    x
    y
    z
    (即&a[i]),而不是
    x
    y
    z
    (即a[i])

    现在看看
    字符a[5][20]
    的情况下的内存组织,因为
    &a[i]
    a[i]
    的内存组织值相同。检查以下代码及其输出:

    #include<stdio.h>
    int main(){
     char a[5][20] = { "jhsa", "asndb", "drtfe", "nhurh", "bvhr"};
     int i = 0;
     for(i = 0; i < 5; i++)
        printf(
            "&a[i] = %p, a[i] = %p, *a[i] = %c, string a[i] = \"%s\"\n", 
            (void*)&a[i], // you are passingg this &a[i]
            (void*)a[i],  // compare &a[i] and a[i] address value
            *a[i], 
            a[i]
        );
     return 0;
    }
    
    #include<stdio.h>
    int main(){
     char *a[] = {"jhsa", "asndb", "drtfe", "nhurh", "bvhr"};
     int i = 0;
     for(i = 0; i < 5; i++)
        printf("&a[i] = %p, a[i] = %p, *a[i] = %c, string a[i] = \"%s\"\n", 
            (void*)&a[i],
            (void*)a[i], 
            *a[i], 
            a[i]); 
     return 0;
    }
    
    虽然
    &a[i]
    a[i]
    不一样,但在值方面是相同的。要理解这些差异,请阅读

    但是
    &a[i]
    a[i]
    的值在
    char*[]
    的情况下不相同检查以下代码:y.c(类似于上面的x.c)及其输出:

    #include<stdio.h>
    int main(){
     char a[5][20] = { "jhsa", "asndb", "drtfe", "nhurh", "bvhr"};
     int i = 0;
     for(i = 0; i < 5; i++)
        printf(
            "&a[i] = %p, a[i] = %p, *a[i] = %c, string a[i] = \"%s\"\n", 
            (void*)&a[i], // you are passingg this &a[i]
            (void*)a[i],  // compare &a[i] and a[i] address value
            *a[i], 
            a[i]
        );
     return 0;
    }
    
    #include<stdio.h>
    int main(){
     char *a[] = {"jhsa", "asndb", "drtfe", "nhurh", "bvhr"};
     int i = 0;
     for(i = 0; i < 5; i++)
        printf("&a[i] = %p, a[i] = %p, *a[i] = %c, string a[i] = \"%s\"\n", 
            (void*)&a[i],
            (void*)a[i], 
            *a[i], 
            a[i]); 
     return 0;
    }
    
    现在,注意
    &a[i]
    a[i]
    的值是不同的(实际上偏移地址值显示段是不同的&a[i]在堆栈中获得地址空间,而
    a[i]
    在字符串文本存储的位置获得地址空间,但这是不同的事情)

    因此,在字符串比较函数中:
    int compare\u string()
    该语句
    返回strcmp(c,d)对于
    char*[]
    不起作用,它应该类似于
    returnstrcmp(*c,*d)(虽然它是为
    char[][]
    工作的,
    &[i]
    a[i]
    的值是相同的第一种情况,我使用
    -Wall
    -pedantic
    编译代码,但它不会发出任何警告,所以我相信使用它作为字符串地址没有问题,但我也不确定)。因此,对于
    char*[]
    ,您需要一个单独版本的compare_string,在其中调用
    strcmp(*c,*d)。但现在的问题是函数参数是
    contvoid*
    ,取消引用cont是未定义的行为。为了纠正代码,我从每个位置删除了
    const
    ,并为
    char*a[]
    添加了一个新函数
    int compare\u string\u v2(void*a,void*b)
    ,如下所示:

    int compare_string_v2( void *a,  void *b)
    {
        char **c = a;
        char **d = b;
        return strcmp(*c, *d);
    }
    

    只需将您的代码编译为:
    $gcc code.c-Wall-pedantic-o code
    它应该可以正常工作。在这里您可以查看@

    您可以使用此代码,越简单越好! 首先在main()中编写Isless函数,类似这样的内容:

    static int IsLess(void* num1, void* num2)
    {
       return (*(int*)num1 > *(int*)num2) ? TRUE : FALSE;
    }
    
    然后使用这个代码

    static void Swap(void* ptr1, void* ptr2, size_t _sizeof)
    {
    void* temp = malloc(_sizeof);
    memcpy(temp,ptr2, _sizeof);
    memcpy(ptr2,ptr1, _sizeof);
    memcpy(ptr1,temp, _sizeof);
    free(temp);
    }
    static void BubbleUp(int _end, void* _arr[], size_t _sizeofitem, fp _IsLess)
    { 
    size_t j;
    for(j = 0; j < _end; ++j)
    {
        if(_IsLess((char*)_arr + j*_sizeofitem, (char*)_arr + (j+1)*_sizeofitem))
        {
            Swap((char*)_arr + j*_sizeofitem, (char*)_arr + (j+1)*_sizeofitem, _sizeofitem);
        }
    }
    }
    void SortGen(void* _arr, size_t _sizeofitem, size_t _numOfItems, fp _IsLess)
    {
    int i;
    if(_arr == NULL)
    {
        return;
    }
    for(i = (int)_numOfItems -1; i >= 0; i--)
    {
        BubbleUp(i, _arr, _sizeofitem, _IsLess);
    }
    }
    
    静态无效交换(void*ptr1、void*ptr2、size\u t\u sizeof)
    {
    void*temp=malloc(_sizeof);
    memcpy(温度、ptr2、尺寸);
    memcpy(ptr2,ptr1,_sizeof);
    memcpy(ptr1、温度、尺寸);
    免费(临时);
    }
    静态空气泡(int _end,void*_arr[],size _t _sizeofitem,fp _IsLess)
    { 
    尺寸j;
    对于(j=0;j<_end;++j)
    {
    如果(_IsLess((字符*)_arr+j*_sizeofitem,(字符*)_arr+(j+1)*_sizeofitem))
    {
    交换((字符*)\u arr+j*\u sizeofitem,(字符*)\u arr+(j+1)*\u sizeofitem,\u sizeofitem);
    }
    }
    }
    void SortGen(void*\u arr,size\u t\u sizeofitem,size\u t\u numOfItems,fp\u IsLess)
    {
    int i;
    如果(_arr==NULL)
    {
    返回;
    }
    对于(i=(int)_numOfItems-1;i>=0;i--)
    {
    气泡(i,_arr,_sizeofitem,_IsLess);
    }
    }
    
    我看到了你的代码,我错了,请删除答案,我会尝试回答你,顺便说一句,好问题。慢慢来,如果我解决了问题,我会在比较函数中给出错误的答案(但没有
    static void Swap(void* ptr1, void* ptr2, size_t _sizeof)
    {
    void* temp = malloc(_sizeof);
    memcpy(temp,ptr2, _sizeof);
    memcpy(ptr2,ptr1, _sizeof);
    memcpy(ptr1,temp, _sizeof);
    free(temp);
    }
    static void BubbleUp(int _end, void* _arr[], size_t _sizeofitem, fp _IsLess)
    { 
    size_t j;
    for(j = 0; j < _end; ++j)
    {
        if(_IsLess((char*)_arr + j*_sizeofitem, (char*)_arr + (j+1)*_sizeofitem))
        {
            Swap((char*)_arr + j*_sizeofitem, (char*)_arr + (j+1)*_sizeofitem, _sizeofitem);
        }
    }
    }
    void SortGen(void* _arr, size_t _sizeofitem, size_t _numOfItems, fp _IsLess)
    {
    int i;
    if(_arr == NULL)
    {
        return;
    }
    for(i = (int)_numOfItems -1; i >= 0; i--)
    {
        BubbleUp(i, _arr, _sizeofitem, _IsLess);
    }
    }