• Home
  • -
  • C语言技巧

C语言技巧

在C程序中,经常会用到结构体,需要获取结构体成员变量的值,获取结构体成员变量一般采用get接口方式,如果结构体成员比较多,就会每个成员对应一个get接口函数,可参考librdkafka的conf配置相关的代码,通过宏获取。

#define GETOFFSET(type,feild) ((size_t)&((type *)0)->feild)
#define GETVALUE(value_type,base_ptr,offset) ((value_type)(*(value_type *)(base_ptr+offset)))

example代码如下:

#include <stdio.h>
#include <stdlib.h>
#define GETOFFSET(type,feild) ((size_t)&((type *)0)->feild)

#define GETVALUE(value_type,base_ptr,offset) ((value_type)(*(value_type *)(base_ptr+offset)))
typedef struct  
{
    double language;
    double math;
}grade_t;

typedef struct  
{
    char country[16];
    char province[16];
}address_t;

typedef struct  
{
    char *name;
    short age;
    grade_t *grade;
    address_t address;
    double level;
}student_t;

int main(int argc,char *argv[])  
{
    grade_t *grade=(grade_t *)malloc(sizeof(grade_t));
    if(NULL==grade)
        return;
    grade->math=88.2;
    grade->language=87.88;
    student_t s;
    strcpy(s.address.country,"China");
    strcpy(s.address.province,"Hubei");
    s.name="sweety";
    s.age=18;
    s.grade=grade;
    s.level=88.33;
    size_t student_size=sizeof(student_t);
    size_t name_offset=GETOFFSET(student_t,name);
    size_t age_offset=GETOFFSET(student_t,age);
    size_t grade_offset=GETOFFSET(student_t,grade);
    size_t address_offset=GETOFFSET(student_t,address);
    size_t level_offset=GETOFFSET(student_t,level);
    printf("offset %d,%d,%d,%d,%d,%d\n",student_size,name_offset,age_offset,grade_offset,address_offset,level_offset);
    size_t base_offset=(size_t)&s;
    char *s_name=GETVALUE(char*,base_offset,name_offset);
    short s_age=GETVALUE(short,base_offset,age_offset);
    grade_t *s_grade=GETVALUE(grade_t *,base_offset,grade_offset);
    address_t s_address=GETVALUE(address_t,base_offset,address_offset);
    double s_levle=GETVALUE(double,base_offset,level_offset);
    printf("name %s,age:%d,laguage:%lf,math:%lf,count:%s,provice:%s,level:%lf\n",s_name,s_age,s_grade->language,s_grade->math,s_address.country,s_address.province,s_levle);

}