在程序开始时,我为一个char指针数组分配内存:
char **buffer = calloc( 20, sizeof(char *) );
然后用户最多可以输入20个单词:
buffer[i] = calloc( 40, sizeof(char) );
fgets( buffer[i], 40, stdin )`
之后我想对这个数组进行排序。如果我使用我的交换函数,它按预期工作:
void swap(char *args1, char *args2) {
char tmp[40];
strcpy( tmp, args1 );
strcpy( args1, args2 );
strcpy( args2, tmp );
}
void sort( char **args, int count ) {
...
swap( args[i], args[j] );
...
}
在仔细思考之后,我注意到这是浪费CPU,因为我所要做的只是将指针重定向到相应的字符串。 所以我重写了我的交换功能:
void swap(char **args1, char **args2) {
char *tmp = *args1;
*args1 = *args2;
*args2 = tmp;
}
void sort( char **args, int count ) {
...
swap( &args[i], &args[j] );
...
}
然而,这根本不起作用,结果是非常意外的,我无法弄清楚为什么(我尝试了几个printf调用等等)...我的理解是指针只是被重定向并因此被交换,让我们说内存看起来像这样:
(begin of char**):
100: *160
108: *200
116: *240
124: *280
...
(begin of char*):
160: Hello!\0
200: World!\0
...
我的想法是改变指针而不是数组以获得最小的CPU工作量(这里:交换指针在100中,指针在108中):
(begin of char**):
100: *200
108: *160
116: *240
124: *280
...
(begin of char*):
160: Hello!\0
200: World!\0
...
我试图尽可能彻底地解释这一点,如果解释得太多,我很抱歉。 如果有人能让我深入了解并帮助我,我将非常高兴!
完整代码(带有工作strcpy)可以在这里找到:http://pastie.org/5361481
答案 0 :(得分:5)
你的排序功能应该看起来像这样:
void sort(char ** args, const int start, const int end) {
char **pivot = &args[end];
int i = start-1, j = start;
while( j < end ) {
int cmp = strcmp( *pivot, args[j] );
if( cmp > 0 )
swap( &args[++i], &args[j] );
j++;
}
swap( &args[++i], pivot );
if( start + 1 < i )
sort( args, start, i - 1 );
if( end - 1 > i )
sort( args, i + 1, end );
}
我怀疑您没有将数据透视为char**
,而是将其保留为char*
。如果你这样做,那么每当你进行交换时,你实际上并没有交换数组中的两个元素,而是使用局部变量交换数组的一个元素。 pivot变量最终指向不同的字符串,而不是指向不同字符串的最后一个数组成员。
答案 1 :(得分:3)
char *pivot = args[end];
...
swap( &args[++i], &pivot );
这是你的问题。您不希望将指针与本地变量交换,而是使用数组中的实际pivot元素(即args+end
)。 working example here