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);
}
现在,这项功能可以完美地用于:
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);
}
}