C语言 是否可以将结构成员名作为函数中的参数传递?

ntjbwcob  于 2023-11-16  发布在  其他
关注(0)|答案(2)|浏览(121)

我正在编写一个网格的解析器,但是我最终在函数体中重复了4次相同的代码块,每次都有很小的差异,所以我被建议编写一个内联函数,使其更好看。
我的网格是一个具有成员大小的结构体,线条由另一个结构体表示:

typedef struct
{
  int size;
  binline *lines;
} grid_t;

字符串

typedef struct
{
  uint64_t ones;
  uint64_t zeros;
} gridline;


1(resp zeros)是一个二进制整数,位代表1(resp zeros)在网格中的位置,我选择用这种方式表示线,因为它们可以是1或0或空。
所以我现在有一个函数,它的入口看起来像static inline bool subheuristic(grid_t *grid, ..., ..., char c),在主体中,我测试'c'是1还是0,然后应用相应的启发式算法。
问题是,它并没有真正减少代码大小.我想知道是否有可能采取一些“一些”作为参数,然后在主体中立即使用它来访问,例如grid->gridline.some,在这种情况下,这将真正减少代码大小。

e4yzc0pl

e4yzc0pl1#

有一些方法可以在C中实现所需的功能。
不能将成员名传递给函数 *,但 * 可以在结构中传递成员的偏移量。偏移量可以从stddef.h中定义的标准offsetof宏中获得。

#include <stddef.h>

uint64_t get_grid_bits(const gridline *gl, size_t offset) {
  return *(uint64_t*)( (char*)gl + offset );
}

...

gridline gl = { .ones = 13, .zeros = 42 };
get_grid_bits(&gl, offsetof(gridline, ones)); // return 13
get_grid_bits(&gl, offsetof(gridline, zeros)); // return 42

字符串
请注意,该行为完全由C标准定义,因为任何对象的任何部分都可以通过char*类型的指针算法访问。
Works就像一个魅力。

kgsdhlau

kgsdhlau2#

这在C语言中是不可能的,但我会使用一个内联函数,当你传递常量表达式为bittype时,它将被很好地优化为非常简单的操作

typedef struct
{
  uint64_t data[2];
} gridline;

typedef enum {zeroes, ones} type; 

static inline __attribute__((always_inline)) uint64_t get_grid_bits(const gridline * restrict gl, const type t) 
{
  return gl -> data[t];
}

static inline __attribute__((always_inline)) void set_grid_bit(gridline * restrict gl, const type t, int bit) 
{
    gl -> data[t] |= 1ULL << bit;
}

static inline __attribute__((always_inline)) void reset_grid_bit(gridline * restrict gl, const type t, int bit) 
{
    gl -> data[t] &= ~(1ULL << bit);
}

static inline __attribute__((always_inline)) int get_grid_bit(const gridline * restrict gl, const type t, int bit) 
{
    return !!(gl -> data[t] & (1ULL << bit));
}

字符串
https://godbolt.org/z/dzMM7vfnb

相关问题