【问题标题】:access members of a structure from void pointer inside a structure从结构内部的 void 指针访问结构的成员
【发布时间】:2014-04-20 05:22:04
【问题描述】:

我想从结构内的 void 指针访问结构的成员,我尝试了以下代码,但它给出的错误是“'(' token 之前的预期标识符”。我应该在 printf 语句中更改什么?谢谢前进。

#include "stdio.h"
struct
{
    int date;
    char *name;
}test;

struct
{
    void *check;
}massage;

main()
{
    test.date=21;
    test.name="Nilesh";
    massage.check =&test;
    printf("date - %d , name - %s\n",massage.((struct test *)check)->date,massage.((struct test *)check)->name);
}

【问题讨论】:

    标签: c


    【解决方案1】:
    struct  // anonymous struct type 
    {
        int date;
        char *name;
    } test;
    

    上面的语句定义了一个匿名结构类型,并创建了这个结构类型的变量test,它没有名字。同样,下面的语句定义了一个匿名结构类型,并创建了一个该类型的变量massage——

    struct  // anonymous struct type
    {
        void *check;
    } massage;
    

    类型转换运算符必须在括号 (type) 中具有类型,而不是变量名。因此,您必须给第一个struct 一个名称(标记),以便使用类型转换运算符。 此外,类型转换运算符的结果是r-value,因此它不能与成员选择.(dot) 运算符一起使用(它应该是成员的名称)。因此,类型转换运算符应该在从结构中获取值之后应用。因此,以下表达式是错误的 -

    massage.((struct foo *)check)->date
    //      |____________________|
    //                |
    //       this should be the member name but it
    //       evaluates to a r-value - the result of
    //       the typecast operator assuming struct tag
    //       is foo
    
    // it should instead be
    ((struct foo *)massage.check)->date
    // dot operator has higher precedence than typecast
    // so the struct member check is fetched first and 
    // it is typecast to type (struct foo *)
    

    我建议进行以下更改 -

    // standard headers should be 
    // enclosed in angle < > brackets
    #include <stdio.h>
    
    // give the structure a name so it can be 
    // used in typecasting
    struct foo {  
        int date;
        char *name;
    } test;
    
    // anonymous struct type
    struct {
        void *check;
    } massage;
    
    // return type of main should be int and 
    // parameter list should contain void
    int main(void) {
        test.date = 21;
        test.name = "Nilesh";
        massage.check = &test;
    
        // fetch the struct member check and then 
        // apply typecast operator
        printf("date - %d , name - %s\n", ((struct foo *)massage.check)->date, 
                                          ((struct foo *)massage.check)->name);
        return 0;
    }
    

    【讨论】:

    • 感谢您的详细解释。我得到了我想要的。
    【解决方案2】:

    在你的表达中:

    massage.((struct test *)check)->date
    //               ^^^ is variable not a data-type 
    

    有两个错误:

    1. 您不能在变量中键入大小写,在您的代码中 test 是变量而不是类型,因此 (struct test *) 是错误的表达式。您应该命名用户定义的类型(正如我在下面建议的那样)。

    2. 您正在应用类型转换而不访问 massage 的指针成员。所以在表达式(struct test *)check 中,实际上“check”是未知变量。编译器会报错你“检查”是未声明的变量(认为test 不是数据类型,但应用类型转换的顺序在概念上是错误的)。

    我建议对其进行一些更正尝试:

    1. 命名结构,例如newtype

       struct newtype  // notice I given name to user defined datatype
       {
          int date;
          char *name;
       }test;
      
    2. 然后纠正 printf 函数中的第二个和第三个参数,如下所示

        ((struct newtype *)massage.check)->date
       // ^^^^^^^^^^^^^^ notice  
      

    printf 中类似的第三个参数。首先访问成员,然后将类型转换为正确的类型。

    完整代码请参考 Ajay 的answer

    【讨论】:

    • test 这里是struct 变量,而不是struct 标签。可以用于类型转换吗?
    【解决方案3】:

    结构定义不是你想要的——它定义了一个未命名结构类型的对象测试。试试看

    struct testType
    {
        int date;
        char *name;
    } test;
    

    然后转换为 (testType *)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-14
      • 2021-08-05
      • 1970-01-01
      • 2021-01-08
      • 2014-06-09
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      相关资源
      最近更新 更多