C语言 有没有办法找出指针指向什么类型的结构体?

svgewumm  于 2023-03-28  发布在  其他
关注(0)|答案(6)|浏览(309)

我的程序包含几个结构体,它们只有一个公共参数。例如:

struct first {
    var a;
    var b;
    var common_var;
    var c;
};

struct second {
    var d;
    var common_var;
    var e;
    var f;
};

“common_var”是所有结构体共有的参数,但它在不同结构体中的出现顺序不同。在第一个结构体中,它是第三个变量,在第二个结构体中,它是第二个变量。
现在,我有一个函数,它接受一个指向void的指针作为参数。我想传递指向这两个结构体中任何一个的指针,传递给这个函数,并根据“common_var”变量做一些事情。

void main()
{
    struct first * pFirst;
    theFunctionIMentioned(pFirst);
}

void theFunctionIMentioned(void * p)
{
    /* Get hold of "common_var" parameter somehow. */
    /* Do something based on the "common_var" parameter. */
}

如果“common_var”是所有结构中的第一个条目,这不会是一个问题。
所以问题是:我能以某种方式找出函数参数(void *p)是指向第一个结构体的指针还是指向第二个结构体的指针吗?

**编辑1:**问题是这个程序有一个UI,它可以让用户(当然是间接地)“决定”哪个结构体指针被发送到函数。如果用户执行动作A,那么程序将一个指向第一个的指针传递给函数。如果用户执行动作B,它将一个指向第二个的指针传递给函数。然而,程序不能(在任何情况下)知道用户执行的是动作A还是动作B。所以基本上,我在编程时唯一“知道”的是传递给“theFunctionIMentioned()”的参数是一个指向包含“common_var”的结构体的指针。我习惯于面向对象编程,在这种情况下,我会通过使用某种接口机制来解决这个问题。我想我有点希望C中会有类似的代码技术。

wf82jlnq

wf82jlnq1#

不,当程序运行时,指针只是一个内存地址,指向的内存只是位。没有隐藏的类型标记。
(If你知道你的结构体中不同的字段可以包含什么值,并且位模式碰巧是独特的,它可能 * 可能 * 编写代码,可以确定,从原始位,指针指向什么类型的结构体。类似于类型字段,但偶然的。这将是复杂的,容易出错的,脆弱的和混乱的,所以我几乎不会推荐它。
你可以改变结构体,或者它们是固定的吗?如果你可以改变它们,你可以创建一个新的结构体,带有一个类型字段和一个由你的两个结构体组成的联合。或者,你可以在两个结构体的开头插入一个类型字段。
如果你不能改变结构体,你需要一个额外的参数来告诉函数你要发送什么。

c6ubokkw

c6ubokkw2#

上面提到的两个结构体是不可互换的。指向first的指针不能转换为指向second的指针。即使你对它进行类型转换,底层的数据组织也不能改变。
我建议您将公共参数common_var作为函数的参数,并以这种方式使用它。

void theFunctionIMentioned(var common_var)

void main()
{
    struct first * pFirst;
    theFunctionIMentioned(pFirst->common_var);
}
4nkexdtk

4nkexdtk3#

在C中,变量名只在编译和链接步骤中出现,但在运行时它们不可用。您必须考虑一种不同的解决方案,通过该解决方案可以访问值。

void main()
{
    struct first * pFirst;
    theFunctionIMentioned(pFirst, pFirst->common);
}

void theFunctionIMentioned(void * p, var common)
{
    /* Get hold of "common_var" parameter somehow. */
    /* Do something based on the "common_var" parameter. */
}
gcxthw6b

gcxthw6b4#

所以问题是:我能以某种方式找出函数参数(void *p)是指向第一个结构体的指针还是指向第二个结构体的指针吗?
不可以,通常没有这样的方法。当您转换为void*时,类型信息会丢失。
听起来UI需要重写了。使用void*的函数接受几个不同的结构体已经表明程序设计有缺陷-应该有不同的函数用于不同的情况。(函数指针可以用来创建一致的接口。)
解决此问题的变通方法取决于允许更改代码的哪一部分。

yqyhoc1h

yqyhoc1h5#

结构firstsecond是不同类型的结构,由您定义。* 您不能将其中一个更改为另一个。* 当您声明指向其中一个的指针时,可以将其传递给theFunctionIMentioned。但您将知道其类型,因为您已经声明了它。
此外,无论你传递一个指向结构体first还是second的指针,你都可以通过使用pFirst->variable;来访问它的任何变量,其中pFirst是你声明的指针,variable是你想要的变量。

yiytaume

yiytaume6#

我相信你会被允许修改函数参数。在这种情况下,
空干管(){

struct first * pFirst;
theFunctionIMentioned(pFirst, 1);

}

void theFunctionIMentioned(void * p, var decider) // decider = 1 for first
                                                  //         = 2 for second
                                                  //         = 3 for third 
{
      if (decider == 1)
      {
             struct first * pFirst = (struct first*) p;
       }

     else
     {
      }
}

相关问题