Typecast void指向int和string

时间:2016-10-20 07:33:30

标签: c pointers

我要做的是将值存储在Element struczs数组中(具有成员void *数据)

typedef struct {
void* data
} Element;

我已经将数组malloc给了3个元素

Element* array = malloc(3 * sizeof(Element));

我知道如果数据是int,你可以这样做,但如果数据无效,你怎么办呢*

array[0].data = 65;

我尝试过类型转换

((*int)(array[0].data)) = 65;

但我在'int'

之前得到了预期表达式的消息

我的第二个问题是如何在Element结构中存储字符串(我不能使另一个成员是一个字符串,它必须使用void指针)

我可以使用strcopy或sscanf吗?

以下示例主要我做错了

#include "test.h"
int main (void)
{  
    Element* array = malloc(3 * sizeof(Element));
    ((*int)(array[0].data)) = 65;
    ((*int)(array[1].data)) = 64;
    ((*int)(array[2].data)) = 66;
}

修改

很抱歉我应该补充说,数据将使用循环添加(迭代基于用户输入,因此arrayOfElements可能有5,8,20个ect元素),基于user3386109回答

Element* arrayOfElements = malloc(3 * sizeof(Element));
arrayOfElements[0].data = malloc( sizeof(int) );
int *ptr = arrayOfElements[0].data;
*ptr = 65;

完美的工作,但如果我想制作arrayOfElements [1] .data = 67

Element* arrayOfElements = malloc(3 * sizeof(Element));
 arrayOfElements[1].data = malloc( sizeof(int) );
 int *ptr = arrayOfElements[1].data;
 *ptr = 76;

即使我自由(ptr)也不能重复使用* ptr,如果你不知道arrayOfElements有多少个元素,那么还有吗?

2 个答案:

答案 0 :(得分:4)

问题中的malloc会创建一个包含三个结构的数组。每个struct都有一个名为data的未初始化指针。在使用该指针之前,必须先调用malloc来初始化它。

存储int

array[0].data = malloc( sizeof(int) );
int *ptr = array[0].data;
*ptr = 65;

存储字符串:

array[0].data = malloc( strlen(str) + 1 );
strcpy( array[0].data, str );

这是一个完整的示例,展示了如何初始化数组,打印数组的元素,然后free数组。请注意,ptr只是一个临时变量,用于避免与转换和取消引用void *相关的讨厌语法。 (一个好的编译器会优化ptr变量。)

int main( void )
{
    int *ptr;
    char *str = "hello";

    Element *array = malloc(3 * sizeof(Element) );

    array[0].data = malloc( sizeof(int) );
    ptr = array[0].data;
    *ptr = 65;

    array[1].data = malloc( strlen(str) +  1 );
    strcpy( array[1].data, str );

    array[2].data = malloc( sizeof(int) );
    ptr = array[2].data;
    *ptr = 76;

    ptr = array[0].data;
    printf( "%d\n", *ptr );
    str = array[1].data;
    printf( "%s\n", str );
    ptr = array[2].data;
    printf( "%d\n", *ptr );

    for ( int i = 0; i < 3; i++ )
        free( array[i].data );
    free( array );
}

答案 1 :(得分:1)

你在这里的角落里。 C标准(草案n1256)在6.3转换中指定:

  

2将操作数值转换为兼容类型不会导致值或更改   表示

后来在6.3.2.3指针:

  

5整数可以转换为任何指针类型。除非事先指明,否则   结果是实现定义的,可能没有正确对齐,可能不指向   引用类型的实体,可能是陷阱表示.56)

     

6任何指针类型都可以转换为整数类型。除非事先指明,否则   结果是实现定义的。如果结果无法以整数类型表示,   行为未定义。结果不必在任何整数类型的值范围内。

标准库甚至定义了一个特殊的整数类型intptr_t,可以接受而不丢失任何指针,但这只是一个信息性部分。

无论如何,在所有常见的实现中,将一个整数强制转换为来回指针是安全的:

  • 如果它原来是一个整数,你永远不会尝试引用它,但在使用之前将其转换回整数(与原始类型相同)。由于演员阵容不会改变代表性,你会得到原始值
  • 如果它最初是指针,则不要尝试将其用作整数,除非您的实现确保没有陷阱表示 - 常见实现允许它
  • 整数类型接受所有指针表示 - 如果不确定使用intptr_t

所以你可以这样做:

array[0].data = (void *) (intptr_t) 65;

以后

int i = (intptr_t) array[0].data;