让我们尽可能简单地做第一个例子。
我想知道如何应用这个宏;像这里申请例如printf("%s",macro(arg));
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#define type_string(name) { #name , name }
int main(void) {
char *hi = "Hello";
char *arr[]=type_string(hi);
printf("%s\n",type_string(hi));
return 0;
}
还有什么可以打印函数名称的其他方法: 我的最后一个解决方案就是这个:
是否有更好的方法来优化此代码,例如调整__func__
?
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
// let's declare different functions for calculation
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
// let's declare function pointers to different behaviors
//int (*functionPtr_1[4])(int,int); // basic form
typedef int (*myFuncDef)(int, int); // typedef as the basic form
int do_calculations (int (*functionPtr)(int, int)); // function receives function pointer with two args and returns int
int (*functionFactory(int n))(int, int);
int main() {
int m = 6;
int n = 10;
int res,i;
int (*functionPtr_arr[4])(int,int) = {&add, &sub, &mul, ÷};
for(i=0;i<4;i++)
{
res=(*functionPtr_arr[i])(4,5);
}
}
int add(int x, int y) {
int result = x + y;
printf("result for %s op is %d\n",__func__,result);
return result;
}
int sub(int x, int y) {
int result = x - y;
printf("result for %s op is %d\n",__func__,result);
return result;
}
int mul(int x, int y) {
int result = x * y;
printf("result for %s op is %d\n",__func__,result);
return result;
}
int divide(int x, int y) {
int result = x / y;
printf("result for %s op is %d\n",__func__,result);
return result;
}
答案 0 :(得分:3)
#define FN_RECORD(f) { #f, f }
这个宏的工作原理是将变量in,f,并将该值放入它所替换的内容中。
实施例
有一个函数int abc(void);
在预处理后,将FN_RECORD(abc)
放入代码中将替换为{ "abc", abc }
。 #
创建一个字符串。
创建此宏的人似乎希望将它用作函数的名称作为c-string,以及它的函数指针。
答案 1 :(得分:3)
描述宏的评论非常清楚,因此不确定您可能会对此感到困惑。
在上下文中,它用于为fns
数组生成初始化程序。所以:
fn_record fns[3] = {
FN_RECORD(fna),
FN_RECORD(fnb),
FN_RECORD(fnc)
};
扩展为:
fn_record fns[3] = {
{"fna", fna},
{"fnb", fnb},
{"fnc", fnc}
};
评论说这是为了节省你打字,但这是一个相当愚蠢的理由 - 它几乎不值得节省宝贵的时间。它有用的是确保字符串和函数名称匹配以避免可能的错误。
答案 2 :(得分:0)
让我们一步一步地分解它。
#define type_string(name) { #name , name }
int main(void) {
char *hi = "Hello";
char *arr[]=type_string(hi);
printf("%s\n",type_string(hi));
}
编译分两个阶段进行(三个,如果计算链接,但让我们忽略它)。在很多情况下,预处理器和编译器实际上是独立的程序,但编译器会自动运行预处理器。
首先,我们进行所有预处理。那么让我们来看看会发生什么:
char *arr[]=type_string(hi);
令牌hi
传递给type_string
。 hi
是变量的事实并不重要; name
包含hi
,而不是"Hello"
。
#是字符串化运算符。由于name
为hi
,#name
的评估结果为"hi"
。
name
只评估为hi
。
所以type_string(hi)
作为一个整体评估为{ "hi" , hi }
,整个行变为char *arr[]={ "hi" , hi };
。 printf("%s\n", type_string(hi));
的工作方式相同,变为printf("%s\n", { "hi" , hi });
。
现在预处理已经完成,实际的编译器就可以了。这是编译器将看到的内容:
int main(void) {
char *hi = "Hello";
char *arr[]={ "hi" , hi };
printf("%s\n",{ "hi" , hi });
}
{ "hi", hi }
将评估为char*
的数组;第一个元素隐式指向(常量)字符串文字"hi"
,第二个元素初始化为当前包含在hi
中的地址,恰好是字符串文字"Hello"
的地址
当然,这不起作用; printf("%s\n", { "hi" , hi })
期待一个字符串并获取一个数组文字,这在该上下文中是不合法的。
您可以执行printf("%s, %s\n", arr[0], arr[1]);
,这将打印hi, Hello
。