Tag:

如何在C中的初始化程序中使用static_assert?

信不信由你,我想在宏扩展到指定的初始化器中使用static_assert : #define INIT(N) \ /* static_assert((N) < 42, "too large"), */ \ [(N)] = (N) int array[99] = { INIT(1), INIT(2), INIT(42) }; 我想从INIT(42)发出错误,但取消注释static_assert是一个语法错误。 AFAIK static_assert在语法上是一个声明。 我如何在这个例子中使用它?

这个MIN宏如何工作?

如果这是一个愚蠢的问题,请原谅我。 我似乎无法弄清楚以下MIN宏是如何工作的: #define MIN(x, y) (y) ^ ((x ^ y) & -(x < y))

为什么某些库例程同时实现为宏? 为什么“va_arg”宏被声明为一个函数(没有“#define”)?

我正在努力用语言清楚地表达出来。 所以让我把它分成几部分。 背景来自Mike Banahan的C书(链接在下面的每个部分提供)。 这是我的问题,作为粗体的要点: 为什么某些库函数同时也实现为宏? 有什么需要? 这是我从书中读到的内容(第9.1.1节) : 最后一点是,许多库例程可以实现为宏,前提是副作用没有问题(如第7章所述)。 标准保证,如果函数通常作为宏实现,则还将提供用于执行相同作业的真实函数。 要使用真实函数,可以使用#undef取消定义宏名称,或将其名称括在括号中,这样可以确保它不会被视为宏: 我们知道, va_start是一个函数还是宏? 书中的以下文字是混乱的根源,因为它暗示着相同的气息,相邻的线条! (第9.9节) 在尝试访问变量参数列表之前,必须调用va_start 。 它被定义为 #include void va_start(va_list ap, parmN); va_start宏初始化ap以供函数va_arg和va_end随后使用。 最后,最令人困惑的部分。 在下面一行中,清楚地写明了va_arg是一个宏,并继续展示它是如何实现的。 但是如何在没有#define关键字的情况下实现宏,并且返回类型(’type’)也是如此,就好像它是一个函数一样? (第9.9节) 初始化后,可以通过va_arg宏顺序访问提供的参数。 这很奇怪,因为返回的类型由宏的参数决定。 请注意,这不可能作为真正的函数实现,仅作为宏。 它被定义为 #include type va_arg(va_list ap, type); 非常感谢您的回答。 谢谢。

使用函数与宏时,为什么会得到不同的结果?

我正在使用DevCPP IDE,我发现在用c编程时, 返回的值: float f(float x) { return 1/(1+x*x); } 和f(x)返回的值如果定义为: #define f(x) 1/(1+x*x) 是不同的。 为什么我在这些情况下会得到不同的结果? 编辑: 这是我的代码,我得到了exception: main() { int i; float a=0, b=1, h, n=12, s1, s2=0; h=(ba)/n; //step length s1=f(a)+f(b); for(i=1;i<=n-1;i++) { s2+=f(a+(i*h)); } s1=(s1+2*s2)*h/2; printf("sum: %f", s1); getch(); } 输出1:0.693581(使用MACRO) 输出2:0.785109(使用function)

像宏这样的函数是否需要强制括号? 在参考GCC cpp手册后我很困惑

这让我感到困惑: 要定义类似函数的宏,可以使用相同的’#define’指令,但是在宏名称后面紧跟一对括号。 我相信这是为了让代码脱颖而出,而不是该程序的作者。 像宏名称的其他CAPS规则一样。 但以下是我感到困惑的地方: 类似函数的宏只有在其名称后面带有一对括号时才会展开。 如果你只写这个名字,那就不管它了。 我读完之后立刻就不同意了。 并且gcc -Evalidation了以下代码 #define FUNC display() void display() { printf(“Display\n”); } int main() { FUNC; return 0; } 预处理的输出按预期显示main()函数的内容: int main() { display(); return 0; } 那我在这里错过了什么? 预处理器用于标记源,宏扩展是一个令牌,上面的代码以这种方式处理,预处理器不应该检查任何东西或validation任何东西,它只是转储令牌。 在那种情况下,gcc手册试图传达什么。 我正在学习C编程,所以我可能会经常发生误解,我搜索了一个正确的解释,最后在这里求助。 请帮我解决一下这个。

什么时候宏可以使代码比函数更漂亮?

确切地说,编程语言不需要宏。 例如,没有宏,Java工作得很好。 通常,宏使代码更清晰,更短,同时更危险。 那么,使用宏的最佳方法是什么? 我们在代码中谈谈。

在C中,当其他宏引发名称冲突时,如何使用其他宏定义宏

这是后面的一个后续问题(请到最后阅读我的问题): 如何避免来自C中#define的名称冲突? (或C ++)假设我使用#define定义ROW和COL。 然后我使用ROW和COL定义ARRSIZE。 我声明一个静态数组,如float myarray[ARRSIZE]; 。 当我修改ROW和COL时,静态数组大小会相应地改变。 但在我的特殊情况下,名称ROW和COL名称与我在同一文件中使用的结构类型的成员名称冲突。 有人告诉我使用const变量而不是使用’#define’来避免混淆。 我喜欢我将代码修改为beloow(这是一个例子)。 const int ROW = 100; const int COL = 200; const int ARRSIZE = ROW*COL; float myarray[ARRSIZE]; 对此进行处理给了我 error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘ARRSIZE’ 在我定义ARRSIZE的行。 当然我可以使用int ARRSIZE = ROW*COL; 在函数内部,使用malloc在函数内动态分配数组。 但是,如果我只想改变ROW和COL并且不想使用malloc怎么办? 当使用#define时,没有问题(名称冲突除外)。 #define ROW 100 #define COL 200 #define […]

根据C ++模板类型调用不同的C函数

我的问题如下:我有一个C库,它包含每个函数的几个版本,根据它们使用的数据类型,例如: void add(double *a, double *b, double *c); 和 void sadd(float *a, float *b, float *c); 现在,有了一个外部C ++模板函数,我希望能够做到这样的事情: template void myfunc(/*params*/) { // Obtain a,b,c of type T* from params /* If T is double call add(a,b,c); else if T is float call sadd(a,b,c). */ } 我知道它可以通过专门的模板函数来完成,例如: template void myfunc(/*params*/) { // Obtain a,b,c of […]

C中的宏指令,我的代码示例不起作用

我想获得以下代码片段: #define READIN(a, b) if(scanf(‘”#%d”‘, ‘”&a”‘) != 1) { printf(“ERROR”); return EXIT_FAILURE; } int main(void) { unsigned int stack_size; printf(“Type in size: “); READIN(d, stack_size); } 我不明白,如何使用#运算符指令。 我想多次使用带有打印错误等的scanf ,但是”‘”#%d”‘和'”&a”‘”我认为是完全错误的。 有没有办法让它运行? 我认为宏是最好的解决方案吗?

c中的doxygen:定义的分组

我用doxygen记录C代码。 为了使文档更具可读性,我想至少使用@defgroup和@ingroup将每个.c / .h文件对中的代码添加到一个组中。 在这些组中,我想使用@name块将一些定义组合在一起。 “文件”页面中的结果与我的预期密切相关:文件中记录的所有内容都列在那里,或多或少地很好地分组。 另一方面,在“模块”页面中,仅列出函数和变量,并在第一个@name块之前的定义列在“变量”下。 缺少所有其他定义和枚举。 删除@name块列出“variables”下的所有定义/ typedefs / enums。 没有自己的宏或枚举部分,也没有在这些页面上进一步分组。 如何在模块/组页面上列出的组中获取所有定义和枚举,例如在文档页面上记录定义/function等? 我使用doxygen 1.8.9.1 windows binarires。 我的代码看起来类似于:.h文件: /** @file * blabla * @author bla */ /// @ingroup MY_GRP /// @{ #define SOMEDEF1 1 /// @name Special defs /// @{ #define SOMEDEF2 2 /// @} enum someenum { foo, bar }; extern int some_variables; […]