我有一个复数的数组,我只想在两个元素之间交换。但是,我想实现未知类型的交换(使用void *)。所以我使用我看到here的第一个交换实现编写了以下代码:
#include<stdio.h>
typedef struct complex complex;
struct complex {
int real;
int img;
};
void swap(void *arr[], int i, int j)
{
void *temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void printComplexArray(complex* cArr, size_t len)
{
int i;
for (i = 0; i < len; i++)
{
printf("Cell %d : real- %d , img- %d\n", i, cArr[i].real, cArr[i].img);
}
}
void main(void)
{
complex cArr[] = { { 22, 3 },{ 1, 13 },{ 5, 7 },{ 8, 4 } };
size_t cLen = (sizeof(cArr) / sizeof(cArr[0]));
swap(cArr, 1, 2);
printComplexArray(cArr, cLen);
}
我希望得到:
Cell 0 : real- 22 , img- 3
Cell 1 : real- 5 , img- 7
Cell 2 : real- 1 , img- 13
Cell 3 : real- 8 , img- 4
但我得到了:
Cell 0 : real- 22 , img- 1
Cell 1 : real- 3 , img- 13
Cell 2 : real- 5 , img- 7
Cell 3 : real- 8 , img- 4
正如您所看到的,不仅交换没有正确执行 - 某些数组元素的内容也发生了变化。你能解释一下原因,我该如何解决这个问题?
答案 0 :(得分:5)
你可能想要这个:
void swap(struct complex arr[], int i, int j)
{
struct complex temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
您的解决方案交换指针,但您的数组不包含指针,而是struct complex
s。这基本上是编译器警告告诉你的。
如果你真的想要交换未知类型,你需要这个:
void swap(void *arr, int i, int j, size_t size)
{
char temp[size];
char *a = (char*)arr;
memcpy(temp, (a + size * i), size);
memcpy((a + size * i), (a + size * j), size);
memcpy((a + size * j), temp, size);
}
...
swap(cArr, 1, 2, sizeof(*cArr));
size参数是必需的,因为如果类型未知,则类型的大小当然也是未知的,因此您需要指定大小。
对于memcpy
,您需要添加<memory.h>
,因此您必须自己编写memcpy
,因为您只能包含<stdio.h>
。
有些编译器不允许使用char temp[size];
,因此您可以使用char temp[MAX_SIZE];
MAX_SIZE
定义未知类型的最大预期大小。
答案 1 :(得分:1)
您无法实现未知类型的交换,您需要知道类型的大小。你的函数交换指针(指针已知大小),但是你正在为它提供complex
数组,而不是指针数组。试试这个(未经测试):
void swap(void *array, size_t i, size_t j, size_t element_length) {
char *src, *dst, tmp;
src = (char*)array + i * element_length;
dst = (char*)array + j * element_length;
while (element_length--) {
tmp = *src;
*src = *dst;
*dst = tmp;
src++;
dst++;
}
}
...
swap(cArr, 1, 2, sizeof(complex));
答案 2 :(得分:1)
使用void *
(据我所知)这样做的唯一方法是重新设计结构的swap
函数交换/应对字节,例如
#include<stdio.h>
typedef struct complex complex;
struct complex {
int real;
int img;
};
void swap(void * to, void * from, size_t len)
{
unsigned char *uc_to = to;
unsigned char *uc_from = from;
unsigned char tmp;
for (size_t i = 0; i < len; i++)
{
tmp = uc_to[i];
uc_to[i] = uc_from[i];
uc_from[i] = tmp;
}
}
void printComplexArray(complex* cArr, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
{
printf("Cell %zu : real- %02d , img- %02d\n", i, cArr[i].real, cArr[i].img);
}
}
int main(void)
{
complex cArr[] = { { 22, 3 }, { 1, 13 }, { 5, 7 }, { 8, 4 } };
size_t cLen = (sizeof(cArr) / sizeof(cArr[0]));
swap((void *)(&cArr[0]), (void *)(&cArr[1]), sizeof(complex));
printComplexArray(cArr, cLen);
}