#include <stdio.h>
void swap(void *v[], int i, int j)
{
void *tmp;
tmp = v[i];
v[i] = v[j];
v[j] = tmp;
}
int main(void)
{
char *s[] = {"one", "two"};
printf("%s, %s\n", s[0], s[1]);
swap(s, 0, 1);
printf("%s, %s\n", s[0], s[1]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
one, two
two, one
Run Code Online (Sandbox Code Playgroud)
警告: no compatible pointer casting, need void**, but char
我使用这个程序来模拟K&R中的交换函数,以演示函数指针的使用,我的问题是它的转换是否void pointer总是安全的,或者是否有任何替换它的方法.
不,传递一个(实际上是一个函数参数)预期的char**地方并不一定安全.编译器使您执行显式转换的事实是一个提示.void**void*[]
在实践中,它可能会很好.但是,严格来说,您通常无法保证sizeof (T*) == sizeof (U*)不同的类型T和U.(例如,您可以想象一个假设的系统,sizeof (int*) < sizeof (char*)因为指针int对齐,因此不需要存储最低有效位.)因此,您的swap函数可能v使用错误的偏移量索引到数组中.
另请参阅comp.lang.c中的Q4.9 FAQ:我可以给出形式参数类型void **,并执行类似的操作吗?
要swap安全地打电话,你应该做的事情如下:
void* temp[] = { &s[0], &s[1] };
swap(temp, 0, 1);
Run Code Online (Sandbox Code Playgroud)
虽然这会交换元素temp,而不是s.
如果你正在创作swap,一般来说你应该让这样一个函数接受一个void*参数(而不是void**一个)和一个size_t指定每个元素大小的参数.那么你的函数可以投的void*,以char*安全和交换单个字节:
void swap(void* p, size_t elementSize, size_t i, size_t j)
{
char* item1 = p;
char* item2 = p;
item1 += i * elementSize;
item2 += j * elementSize;
while (elementSize-- > 0) {
char temp = *item1;
*item1 = *item2;
*item2 = temp;
item1++;
item2++;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:另请参阅此StackOverflow对类似问题的回答.
| 归档时间: |
|
| 查看次数: |
458 次 |
| 最近记录: |