c语言中怎样通过索引获取结构体成员的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言中怎样通过索引获取结构体成员的值相关的知识,希望对你有一定的参考价值。

c语言中怎样通过索引获取结构体成员的值c语言中怎样通过索引获取结构体成员的值。例如: struct Test char a; int b; int c;,当然成员变量的类型是不确定的。我怎样才能实现通过索引值来获取成员变量的值,比如我要访问a,则给出的是索引值1,访问数据结构成员b,则给出2即可,以此类推。求大侠们帮帮忙。先谢过了。

也许你可以定义一个数组,数组的值是结构体各个成员在结构体中的偏移位置,如
const int offset[] = 0, sizeof(char), sizeof(char)+sizeof(int);
struct Test a;
那么访问第一个数据可以
char num1 = *(char*)((char*)&a + offset[0]);
int num2 = *(int*)((char*)&a + offset[1]);
int num3 = *(int*)((char*)&a + offset[2]);
参考技术A 你可以通过switch实现,每个case时注意成员类型。 参考技术B 不可能!

怎样求结构体成员的偏移地址 || 结构体的 sizeof 总结

C 语言中同意将值为 0 的变量强制转换成任一类型的指针,转换结果是一个NULL指针。

(type*)0 // 一个 type 类型的NULL指针

用这个指针訪问结构体内的成员是非法的,可是

&(((type*)0)->field)

是为了计算 field 的地址 ,编译器不会产生訪问 field 的代码。仅仅会依据 type 的布局和起始地址在编译期计算这个地址(常量)。而又由于初始地址为 0,故该地址的值就是该结构体成员相对于结构体基址的偏移。

(size_t)&(((type*)0)->field)

结构体的 sizeof 的相关知识:
对 32 位操作系统。默认按 4 字节对齐;
sizeof(union),结果是 union 占用内存最大成员的大小(各成员共享内存)

编译器是依照什么样的原则进行对齐的?

  • 1.数据类型自身的对齐值:

    对于char型数据,其自身对齐值为1,对于short型为2,对于int, float类型,其自身对齐值为4,对于double类型其自身对齐值为8,单位字节。

  • 2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。

  • 3.指定对齐值:#pragma pack (value)时的指定对齐值value。

  • 4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。

  • 5.对齐后的长度必须是成员中最大的对齐參数的整数倍
#include <iostream>
using namespace std;
#define ISUNSIGNED(x) ((x > 0) && (~x > 0))
#define OffSet(type, field) ((size_t)&(((type*)0)->field))
int main()
{
    struct A{
        char a;
        int b;
        float c;
        double d;
        char e;
        union B{
            char f[100];
            struct C{
                int g[50];
            } h;
        }i;
        bool j;
    } s;
    cout << sizeof(A) << endl; // 232
    cout << "a 的起始偏移:"<< OffSet(A, a) << endl; // 0
    cout << "b 的起始偏移:"<< OffSet(A, b) << endl; // 4
    cout << "c 的起始偏移:"<< OffSet(A, c) << endl; // 8
    cout << "d 的起始偏移:"<< OffSet(A, d) << endl; // 16
    cout << "e 的起始偏移:"<< OffSet(A, e) << endl; // 24
    cout << "i 的起始偏移:"<< OffSet(A, i) << endl; // 28
    cout << "j 的起始偏移:"<< OffSet(A, j) << endl; // 228


    int p = 1;
    unsigned int q = 1;
    cout << p << " " << ~p << endl; // 1 -2
    cout << q << " " << ~q << endl; // 1 4294967294
    cout << "p是否是无符号数:" << ISUNSIGNED(p) << endl; // 0
    cout << "q是否是无符号数:" << ISUNSIGNED(q) << endl; // 1
    return 0;
}

以上结构体分析:

struct A{
        char a;
        int b;
        float c;
        double d;
        char e;
        union B{
            char f[100];
            struct C{
                int g[50];
            } h;
        }i;
        bool j;
    } s;
  • 结构体 A 的自身对齐值为最大的成员的自身对齐值,为 8 (double d), 注意内部结构体 C 的最大对齐值是 4 (int)。Union B 最大对齐值是 4 (int);
  • 成员char a 的本身对齐值是 1,结构体对齐值是 8。按 1 字节对齐;
  • 成员 int b 的 本身对齐值是 4。结构体对齐值是 8,按 4 字节对齐,它的起始偏移地址为 4。
  • 成员 float c 的 本身对齐值是 4,结构体对齐值是 8,按 4 字节对齐。它的起始偏移地址为 8。
  • 成员 double d 的 本身对齐值是 8,结构体对齐值是 8。按 8 字节对齐,它的起始偏移地址为 16;
  • 成员 char e 的 本身对齐值是 1,结构体对齐值是 8,按 1 字节对齐。它的起始偏移地址为 24;(16+8)
  • 成员 Union B i 的 本身对齐值是 4,结构体对齐值是 8,按 4 字节对齐。它的起始偏移地址为 28;
  • 成员 bool j 的 本身对齐值是 1,结构体对齐值是 8。按 1 字节对齐。它的起始偏移地址为 228 ;(28+200)
  • 结构体对齐值是 8, 因此结构体 A 的大小为 232 (228+1 补齐成 8 的倍数)

一个成员在内存中补位所占的内存,决定于该成员之后的成员类型。

參考:《程序猿笔试面试宝典》



以上是关于c语言中怎样通过索引获取结构体成员的值的主要内容,如果未能解决你的问题,请参考以下文章

c语言:通过指向结构体变量的指针变量输出结构体变量中成员的信息

c语言结构体能否整体赋值

C语言-结构体

Go 语言之 struct 结构体

C 语言结构体 ( 结构体偏移量计算 | 代码示例 )

以结构体为参数的函数如何改变传入结构体成员的值