C语言按已知大小

时间:2016-09-26 12:21:15

标签: c pointers

简单的问题,我们可以用c语言按已知大小按未知数据类型转换void指针吗?

考虑这种情况:

函数 assertEqual ,它应该得到2个指针作为参数,取消引用它们和相等的值。你当然不能取消引用void指针,但如果我知道指针所指向的数据大小呢?我可以创建一些已知大小但未知数据类型的动态指针吗?该函数应该看起来像 assertEqual(void * expected,void * current,size_t size)

3 个答案:

答案 0 :(得分:3)

您可以将参数转换为unsigned char*,然后比较第一个size字节(或更好地使用memcmp这样做),但不保证它会做你做的事情想要在给定值有多个表示的情况下(例如,考虑到结构中的填充,填充内容的差异可能是无害的,但是可以通过这种方法检测到,还有其他情况,如NaN浮点格式的值,在技术上可能发生在大多数原始类型中。)

答案 1 :(得分:0)

  

我可以创建一些已知大小但未知数据类型的动态指针吗?

作为一般规则。没有。您需要知道类型以对类型指针进行类型转换。例如float和int都有4个字节的大小,但类型不相等。

但是,如果您具有等效类型,则可以将类型转换为等效类型。例如在某些系统上,int和long都是4个字节并且是等效的。

答案 2 :(得分:0)

  

简单的问题,我们可以用c语言按已知大小按未知数据类型转换void指针吗?

没有。每个指针类型都有一个特定的类型。其中包括void *,其引用类型(void)是该语言提供的不完整类型。没有指向未知数据类型的指针,但在void *中,您的指针类型与所有其他对象指针类型的可互换

另一方面,通过指向字符类型的指针(例如char *unsigned char *)访问任何类型的对象是有效的,并且一种方法是通过左值type是一个字符数组。你可以得到与你所要求的非常相似的东西:

int assertEqual(void* expected, void* current, size_t size) {
    unsigned char (*ep)[size] = expected;
    unsigned char (*cp)[size] = current;
    // ...
}

使用可变长度数组类型作为指向类型:指针epcp均指向size数组 unsigned char类型的元素。该数组类型的大小为size,因此,例如,您确实会找到sizeof(*ep) == size。也就是说,你有一个指向指定大小的对象的指针,通过它可以访问该对象的字节。

正如其他人已经指出的那样,你所要求的是有点无意义的。如果您只想比较两个字节序列而不知道它们代表什么类型的对象,那么您可以使用memcmp()。另一方面,这作为一般的相等性测试是不安全的,因为当作为给定类型的对象进行比较时,具有不同字节序列的两个对象仍然可以是相等的。发生这种情况是因为允许许多整数类型具有不对其值有贡献的填充位,并且因为浮点表示完全取决于实现。

此外,structunion类型可以包含未指定的填充字节,并且不一定是一致的值。您无法将复合类型与==运算符进行比较,但比较构成此类对象表示的字节数组并不一定会产生与按成员比较对象的结果相同的结果。