这段代码有什么问题

时间:2011-04-05 19:39:12

标签: c

这是大代码的片段。我想理解为什么compare_int没有得到正确的指示。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

static int 
compare_int ( void *left, void *right ) {
    int *l = (int*)left;
    int *r = (int*)right;

    if ( *l < *r ) 
        return -1;
    else if ( *l > *r ) 
        return 1;
    return 0;
}

int main()
{
    void *data1 = malloc ( sizeof ( int));
    int i = 55;
    memcpy ( data1, &i, sizeof(int));

    void *data2 = malloc ( sizeof ( int));
    int j = 65;
    memcpy ( data2, &j, sizeof(int));

    compare_int ( data1, data2 );


}

2 个答案:

答案 0 :(得分:2)

我想我明白你在挣扎着什么。我将解释这个问题为什么

int *l = (int*)left;
int *r = (int*)right;

这些必要条件。

它们是必要的,因为C基本上是装配。当你在C中使用一个类型时,你会告诉它你希望字段在内存方面有多大。 void类型正是 - 一种完全未定义的长度。 void指针是指向任何类型的变量的指针。实际上,任何指针都可以指向任何类型,但是当你取消引用它时,你只能读取该类型的大小。

现在类型void没有大小。因此,您无法取消引用void指针,因为C在读取值时不知道“在哪里停止”。

所以考虑它的好方法不是int* x是一个整数指针,而x是一个指针,它指向的数据是一个大小为4字节(或其他)的int。相比之下,void* y是一个指针,它指向的数据的大小和类型都是未知的。

使用强制转换,以便在取消引用指针后知道应该读取的内存大小。

另请参阅cplusplus.com的解释:

  

void指针

     

指针的void类型   是一种特殊类型的指针。在C ++中,   void表示缺少类型,   所以void指针是指针   指向没有类型的值(和   因此也是一个未确定的长度和   未定的解引用属性)。

     

这允许void指针指向   任何数据类型,来自整数值   或浮点到一串字符。   但作为交换,他们有一个伟大的   限制:他们指出的数据   不能直接解除引用(哪个   是合乎逻辑的,因为我们没有类型   解除引用,因此   我们将永远不得不施展   在一些虚拟指针中的地址   指向a的其他指针类型   以前的具体数据类型   解除引用它。

你怎么能解决这个问题?基本上停止使用void*。你的函数被称为compare_int但它理论上接受任何类型并试图抛出它。这是其他评论员/人们回答时所说的“你想在这里做什么?”的意思。 void*技巧有时是非常有用的(例如,当你希望能够使用回调函数指针并让程序员传递任何参数时。CreateThread在Windows上工作就像这样)但是这里,只是为了比较两个整数?这太过分了。

答案 1 :(得分:0)

从这开始:

int main() {     
   int i = 55;     
   int j = 65;    
   printf("%d\n", 
          compare_int ( &i, &j);   

   return 0;

} 

int compare_int(const void *left, const void *right)

也是一个值得考虑的事情。