gpt4 book ai didi

用于设置位的 c 宏

转载 作者:行者123 更新时间:2023-11-30 18:01:18 25 4
gpt4 key购买 nike

我有一个程序,可以比较两个结构中的变量,并为位图变量相应地设置一些位。我必须比较结构的每个变量。实际上,每个结构的变量数量更多,但为了简单起见,我使用了 3 个。我想知道是否可以创建一个宏来比较变量并相应地设置位图中的位。

#include<stdio.h>


struct num
{
int a;
int b;
int c;
};

struct num1
{
int d;
int e;
int f;
};

enum type
{
val1 = 0,
val2 = 1,
val3 = 2,
};
int main()
{
struct num obj1;
struct num1 obj2;
int bitmap = 0;

if( obj1.a != obj2.d)
{
bitmap = bitmap | val1;
}
if (obj1.b != obj2.e)
bitmap = bitmap | val2;

printf("bitmap - %d",bitmap);
return 1;


}

我可以声明一个宏,例如...

#define CHECK(cond)
if (!(cond))
printf(" failed check at %x: %s",__LINE__, #cond);
//set the bit accordingly

#undef CHECK

最佳答案

只要稍加小心,您就可以相当轻松地做到这一点。您只需要仔细识别要比较和设置的内容,并将它们作为宏参数传递。用法示例:

CHECK(obj1.a, obj2.d, bitmap, val1);
CHECK(obj1.b, obj2.e, bitmap, val2);

这假设 CHECK定义如下:

#define STRINGIFY(expr) #expr

#define CHECK(v1, v2, bitmap, bit) do \
{ if ((v1) != (v2)) \
{ printf("failed check at %d: %s\n", __LINE__, STRINGIFY(v1 != v2)); \
(bitmap) |= (1 << (bit)); \
} \
} while (0)

当然,您可以按照自己喜欢的方式布置宏;我对此并不完全满意,但也不算太糟糕。

演示代码

编译和测试运行:

$ gcc -Wall -Wextra -g -O3 -std=c99 xx.c -o xx && ./xx
failed check at 40: obj1.a != obj2.d
failed check at 42: obj1.c != obj2.f
bitmap - 5
$

实际代码:

#include <stdio.h>

struct num
{
int a;
int b;
int c;
};

struct num1
{
int d;
int e;
int f;
};

enum type
{
val1 = 0,
val2 = 1,
val3 = 2,
};

#define STRINGIFY(expr) #expr

#define CHECK(v1, v2, bitmap, bit) do \
{ if ((v1) != (v2)) \
{ printf("failed check at %d: %s\n", __LINE__, STRINGIFY(v1 != v2)); \
(bitmap) |= (1 << (bit)); \
} \
} while (0)


int main(void)
{
struct num obj1 = { 1, 2, 3 };
struct num1 obj2 = { 2, 2, 4 };
int bitmap = 0;

CHECK(obj1.a, obj2.d, bitmap, val1);
CHECK(obj1.b, obj2.e, bitmap, val2);
CHECK(obj1.c, obj2.f, bitmap, val3);

printf("bitmap - %X\n", bitmap);
return 0;
}

显然,此代码依赖于您在 CHECK 宏调用中匹配正确的元素和位数。

可以使用 offsetof() 设计更复杂的方案等等以及描述数据结构的初始化数组等,但是您最终会得到一个更复杂的系统并且没有什么好处。特别是,调用不能减少太多参数数量。您可以假设“位图”是变量。您需要识别这两个对象,因此您将指定“obj1”和“obj2”。在此过程中,您需要确定正在比较哪些字段以及要设置的位。这可能是某个单个值(可能是位数),但您仍然有 3 个参数( CHECK(obj1, obj2, valN) 和关于 bitmap 的假设)或 4 个参数( CHECK(obj1, obj2, bitmap, valN) 没有关于 bitmap 的假设),但是背景很复杂,出错的可能性也更大。如果您可以修改代码,以便拥有单一类型而不是两种类型等,那么您可以使用假设的系统使生活变得更轻松,但我认为按照工作代码中所示的方式处理事情仍然更简单.

我同意gbulmer我可能不会这样做,但你确实声明你已经大大减小了结构的大小(为此,谢谢!)并且随着字段数量的增加,它会变得更加诱人(但我只会在单个函数中写出一对结构类型的比较一次)。

您还可以将宏修改为:

#define CHECK(cond, bitmap, bit) do \
{ if (cond) \
{ printf("failed check at %d: %s\n", __LINE__, STRINGIFY(cond)); \
(bitmap) |= (1 << (bit)); \
} \
} while (0)

CHECK(obj1.a != obj2.d, bitmap, val1);
...
CHECK((strcmp(obj3.str1, obj4.str) != 0), bitmap, val6);

其中最后一行表明这将允许您选择任意比较,即使它们包含逗号。请注意对 strcmp() 的调用周围的额外括号。 !

关于用于设置位的 c 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9881530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com