C 使用指针交换对象
我试图用一个家庭作业问题来交换对象,这个问题使用空指针来交换对象。我的职能声明必须是:C 使用指针交换对象,c,pointers,C,Pointers,我试图用一个家庭作业问题来交换对象,这个问题使用空指针来交换对象。我的职能声明必须是: void swap(void *a, void *b, size_t size); 我并不是在寻找确切的代码来完成它,所以我可以自己找出它,但我不确定我是否理解正确。我发现一个问题是: void *temp; temp = a; a = b; b = temp; 只更改指针指向的内容。对吗?如果它是正确的,为什么交换指针实际上不改变*a和*b之间的内容呢。因为如果你的指针指向不同的东西,你不能取消它的引用
void swap(void *a, void *b, size_t size);
我并不是在寻找确切的代码来完成它,所以我可以自己找出它,但我不确定我是否理解正确。我发现一个问题是:
void *temp;
temp = a;
a = b;
b = temp;
只更改指针指向的内容。对吗?如果它是正确的,为什么交换指针实际上不改变*a和*b之间的内容呢。因为如果你的指针指向不同的东西,你不能取消它的引用,对象现在就不同了吗
类似地,只需切换如下值:
void *temp;
*temp = *a;
*a = *b;
*b = *temp;
也不正确,我不知道为什么。因为再一次,在我看来,内容被切换了
交换对象是否意味着完全交换内存和指针指向的值
因此,似乎我必须使用malloc为我的交换分配足够的空间。如果我为一个对象分配了足够的内存,假设它们的大小相同,我真的看不出它与上面的其他两种方法有什么不同
void *temp = malloc(sizeof(pa));
// check for null pointer
temp = a;
// do something I'm not sure of since I don't quite get how allocating space is any
// different than the two above methods???
谢谢 要在内部更改指针并将其保持在外部,必须通过引用或双指针传递指针 如果您的功能必须类似于:
void swap(void *a, void *b, size_t size);
我认为您必须实现以下内容:
void * temp;
temp = malloc(size);
memcpy(temp,a,size);
memcpy(a,b,size);
memcpy(b,temp,size);
free(temp);
交换指针不会更改指向的值。如果是这样的话,那就好比交换信封上的地址标签,把我搬进你家,把你搬进我家 你就快到了:
void swap(void *a, void *b, size_t size) {
char temp[size]; // C99, use malloc otherwise
// char serves as the type for "generic" byte arrays
memcpy(temp, b, size);
memcpy(b, a, size);
memcpy(a, temp, size);
}
函数复制内存,这是C中对象的定义(称为POD或PAND OL数据在C++中比较)。这样,MimcPy就是如何在不关心对象类型的情况下完成分配,甚至可以编写其他任务作为MimcPy,而不是:
int a = 42, b = 3, temp;
temp = b;
b = a;
a = temp;
// same as:
memcpy(&temp, &b, sizeof a);
memcpy(&b, &a, sizeof a);
memcpy(&a, &temp, sizeof a);
这正是上述函数所做的,因为当您不知道对象的类型时,不能使用赋值,而void是代表“未知”的类型。(当用作函数返回类型时,也表示“无”。)
好奇的是,另一个版本在常见情况下避免使用malloc,并且不使用C99的VLA:
void swap(void *a, void *b, size_t size) {
enum { threshold = 100 };
if (size <= threshold) {
char temp[threshold];
memcpy(temp, b, size);
memcpy(b, a, size);
memcpy(a, temp, size);
}
else {
void* temp = malloc(size);
assert(temp); // better error checking desired in non-example code
memcpy(temp, b, size);
memcpy(b, a, size);
memcpy(a, temp, size);
free(temp);
}
}
void swap(void*a、void*b、size\u t size){
枚举{阈值=100};
如果(size首先,请注意,对函数内部指针的任何更改都不会传播到函数外部。因此,您必须移动内存
最简单的方法是使用memcpy
-在堆栈上分配一个缓冲区,memcpy
从a
放入适当大小的缓冲区,memcpy
从b
到a
,最后一个memcpy
从temp进入b
要产生任何实际效果,您需要执行以下操作你提到的第二个街区:
void *temp;
*temp = *a;
*a = *b;
*b = *temp;
这里的问题是“void”没有大小,因此您无法按原样分配“void”。您需要为要指向的temp
分配空间,然后使用类似memcpy()的方法复制值
参数类似于局部变量,在函数开始执行之前将值复制到它们中。此原型:
void swap(void *a, void *b, size_t size);
这意味着这两个地址被复制到名为a
和b
的新变量中。因此,如果您更改a
和b
中存储的内容,则在swap
返回后,您所做的任何操作都不会产生任何影响。如果您正在编写一个函数来交换两个整数,给定指向它们的指针,那么您的swa解决方案将不会产生任何影响将指向的值进行工作,但是,考虑到的情况。
struct {
int a;
int b;
} a, b;
swap(&a, &b, sizeof(a));
您需要找出一种方法来交换传递的每个值的内容,而不知道它们实际上是由什么组成的。要回答第一个问题,让我们填写一些值以查看发生了什么:
void* a = 0x00001000; // some memory address
void* b = 0x00002000; // another memory address
/* Now we'll put in your code */
void* temp; // temp is garbage
temp = a; // temp is now 0x00001000
a = b; // a is now 0x00002000
b = temp; // b is now 0x00001000
因此,在这些语句的末尾,指针的值被交换,也就是说,无论a
指向什么,现在都被b
指向,反之亦然。这些指针指向的值没有被修改,只是现在它们的内存地址被不同的指针持有
要回答第二个问题,您不能取消引用void*
。原因是void
没有大小,因此尝试取消引用或分配给没有大小的对象是毫无意义的。因此,void*
是一种保证您可以指向某个对象的方法,但您永远不会知道该对象是什么不需要更多信息(因此将size
参数添加到例程中)
从那里,知道指针和指针指向的数据的大小,您可以使用类似于memcpy
的例程将一个指针指向的数据移动到另一个指针指向的位置。您已经接近了
问题是:只“交换”函数中的局部变量指针a和b
我假设函数之外有一些变量,我们调用它们:
void *x = ...;
void *y = ...;
当你打电话时:
swap(x, y, some_size);
a和b分别指向与x和y相同的对象。现在,当您交换a和b点时,x和y仍然指向它们之前指向的对象
要更改内存x和y的指向,必须将指针传递给x变量,因此指针指向:)
因为您不能更改函数声明,所以只能交换x(和a)和y(和b)指向的内存内容。其他答案中有一些解决方案:)通常memcpy
是您想要的。对于我的C课程,我有一个类似的问题。我认为memcopy可能是最好的,但您也可以尝试一下:
typedef unsigned char * ucp;
void swap(void *a, void *b, int size){
ucp c=(ucp)a;
ucp d=(ucp)b;
for(int i=0; i<size; i++){
int temp=(int)c[i];
c[i]=(int)d[i];
d[i]=temp;
}
}
typedef无符号字符*ucp;
无效交换(无效*a、无效*b、整数大小){
ucp c=(ucp)a;
ucp d=(ucp)b;
对于(int i=0;i我们不需要使用memcpy来交换两个指针,下面的代码工作得很好(经过测试用于交换int*和char*字符串):
你是cl
void swap(void **p, void **q)
{
void *t = *p;
*p = *q;
*q = t;
}