glibc中qsort
的实现通过交换函数修改指针数组,如下定义:
#define SWAP(a, b, size) \
do \
{ \
register size_t __size = (size); \
register char *__a = (a), *__b = (b); \
do \
{ \
char __tmp = *__a; \
*__a++ = *__b; \
*__b++ = __tmp; \
} while (--__size > 0); \
} while (0)
...查看完整代码here ...
说,我已经声明了这样的指针数组:(我知道指针字符串不能被修改)。
char *a[] = {"one", "two", "three", "four"},
*lo = (char*)a,
*hi = &lo[2];
SWAP(lo, hi, 4); // Doesn't work.
简而言之,我想知道qsort
如何排序指向字符串的数组。据我所知,指针数组无法修改。它只能指向其他指针。
答案 0 :(得分:3)
您对lo
和hi
的初始化不正确。他们应该是:
char *lo = (char*)&a[0],
*hi = (char*)&a[2];
这将交换lo
和hi
的值。完整代码:
#include <stdio.h>
#define SWAP(a, b, size) \
do \
{ \
register size_t __size = (size); \
register char *__a = (a), *__b = (b); \
do \
{ \
char __tmp = *__a; \
*__a++ = *__b; \
*__b++ = __tmp; \
} while (--__size > 0); \
} while (0)
int main(int argc, char *argv[]) {
char *a[] = {"one", "two", "three", "four"};
char *lo = (char*)&a[0], *hi = (char*)&a[2];
SWAP(lo, hi, sizeof(*lo));
int i;
for (i = 0; i < 4; i++) {
printf("a[%d] = %s\n", i, a[i]);
}
}
输出:
a[0] = three
a[1] = two
a[2] = one
a[3] = four
假设字符串内存最初是这样的,从地址1000开始:
one\0two\0three\0four\0
数组的值为:
a[0] = 1000 -> one
a[1] = 1004 -> two
a[2] = 1008 -> three
a[3] = 1014 -> four
在SWAP
之后,字符串内存不变,但数组现在是:
a[0] = 1008 -> three
a[1] = 1004 -> two
a[2] = 1000 -> one
a[3] = 1014 -> four