如何在不知道名称的情况下访问结构成员?

Posted

技术标签:

【中文标题】如何在不知道名称的情况下访问结构成员?【英文标题】:How to access a structure member without knowing the name? 【发布时间】:2015-07-27 09:00:45 【问题描述】:

我们如何在不知道名称的情况下访问结构的成员?

例如:这是我的结构。

struct A

   int a;
   char b;  
   int c;
 

现在我想访问结构 A 的 char 成员而不使用它的名称。

我只有一个指向该结构的指针。

示例:结构 A *temp;

现在我需要使用 'temp' 访问。

我知道这个问题与How would you access a C structure's members without knowing the name? 类似, 但它并没有澄清我的疑问。

【问题讨论】:

这个问题很奇怪,因为如果你不知道任何内部成员,你到底想做什么?假设我有Opaque opaqe - 你到底想要什么?举个例子吧。 您对struct A 了解多少?我假设您必须知道它只有一个 char 成员(否则您的问题不合适);您是否还知道它的所有其他成员是什么,以及它们的顺序等等? @ruakh 我的结构成员的顺序与我在上面声明的顺序相同,我想使用“temp”结构指针从结构访问“char b” @Praveenupadrasta 如果你有一个struct A* temp,你可以做temp->b。这应该包含在任何关于 C 的基础书籍或教程中。 @NiBZ,该函数可以带一个指向前向声明的结构A的指针,该函数将不知道它的结构。 【参考方案1】:

从cmets,我了解到你有以下功能

struct A;
void foo( struct A * temp )

    // access temp->b here

如果您可以包含具有结构 A 定义的文件,请这样做

#include "A.h"
void foo( struct A * temp )

    do_something_with_b(temp->b);

如果您无法包含该文件,请执行 Luc Forget 在他的回答中建议的操作: 声明一个具有相同结构的struct B,并将temp 转换为struct B。因为struct Bstruct A 具有相同的内存布局,所以访问((struct B*)temp)->e 与访问A->b 相同。

【讨论】:

感谢您理解我的问题并提供准确答案:) 实际上,如果您无法访问带有struct A 声明的标头,只需自己编写声明即可。无需调用它struct B 并进行演员表。【参考方案2】:

如果您是结构字段,我认为访问字段的最简单方法是声明具有相同字段的另一个结构 Struct B 并将您的结构 A* 转换为结构 B,然后以“传统”访问字段方式。 这是我的意思的一个简单示例:

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

struct A 
    int a;
    char b;
    int c;
;

struct B 
    int d;
    char e;
    int f;
;

void printStruct(void* struct_ptr)

    struct B *tmp = struct_ptr; 
    fprintf(stdout, "a:%d b:%c c:%d\n", tmp->d, tmp->e, tmp->f);


int main(int argc, char** argv)

    struct A test =  42, 'A', 24 ;
    printStruct(&test);

这里 printStruct “不知道” Struct A 的字段名称,但可以访问它们

【讨论】:

@MattMcNabb 抱歉,我没注意到。【参考方案3】:

如果您知道成员的类型和顺序(以及打包),那么您可以创建另一个结构并强制转换指针,如下所示:

struct AMirror 
  int a;
  char b;
  int c;
;
void function_to_use_struct(AMirror *ptr);
...
A *s;
...
function_to_use_struct((AMirror*)s);

【讨论】:

补充:它之所以有效,是因为具有完全相同成员的结构保证具有相同的布局【参考方案4】:

下面的代码应该可以工作

void *b=temp;
int *c = (int *) b;
cout<<"Value1: "<<*c <<endl;
char *cc =(char *) (b+4);
cout<<"Char1: "<<*cc<<endl;
c =(int *) (b+6);
cout<<"Value2: "<<*c<<endl;

【讨论】:

【参考方案5】:

我想一种方法是强制转换和增加 char* ,但在这种情况下,您必须知道成员声明的类型和顺序。

【讨论】:

你能按照我声明的顺序向我解释一下上面列出的结构成员的例子吗? 如果您在此代码中没有定义struct A,则char *tmp = (char *)temp; char b = tmp[sizeof(int)]; 之类的东西可能会起作用。但是一个更“干净”的实现将包括一个正确的包含和使用char b = temp-&gt;b,因为它对你可以在你的结构中执行的任何重新排序都是安全的。

以上是关于如何在不知道名称的情况下访问结构成员?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不输入对象名称的情况下访问对象的数据?- JSON

在不知道字典名称的情况下如何在字典中查找内容

如何通过偏移获取/设置结构成员

如何在不知道表单内控件名称的情况下获取表单中的 GET/POST 元素

如何在不使用类名作为范围的情况下获取类中成员函数的地址?

在不知道架构名称的情况下向组角色添加权限