我试图实现一个可以接受任何数据类型并处理它的泛型宏,这个示例工作得很好,但是对于两个泛型宏,我如何使用一个带有char*int和double的泛型来实现它?
#include <stdio.h>
#include <stdlib.h>
#define puts(x) _Generic((x), \
char*: _puts((void*) x, "str"), \
int: _puts((void*) x, "int") \
)
#define putsd(x) _Generic((x),\
double: _puts((void*)to_s(x), "float") \
)
char*
to_s(double x)
{
char* str = (char *)malloc(1502);
sprintf(str, "%lf", x);
free(str);
return str;
}
void _puts(void* d, const char* type)
{
if (strcmp(type, "int") == 0){
printf("%d\n", d);
} else if (strcmp(type, "float") == 0){
double res;
sscanf(d, "%lf", &res);
printf("%lf\n", res);
} else {
printf("%s\n", d);
}
}
int main(void) {
puts("String");
puts(1230);
putsd(13.37);
return 0;
}
另外,当我尝试follows时,我得到一个错误“to_s”puts(“String”)的参数1的不兼容类型:
#include <stdio.h>
#include <stdlib.h>
#define puts(x) \
_Generic((x), \
char*: _puts((void*) x, "str"), \
int: _puts((void*) x, "int"), \
double : _puts((void *)to_s(x), "float") \
)
char *to_s(double x) {
char *str = (char *)malloc(1502);
sprintf(str, "%lf", x);
free(str);
return str;
}
void _puts(void *d, const char *type) {
if (strcmp(type, "int") == 0) {
printf("%d\n", d);
} else if (type == "float") {
double res;
sscanf(d, "%lf", &res);
printf("%lf\n", res);
} else {
printf("%s\n", d);
}
}
int main(void) {
puts("String");
puts(1230);
puts(13.37);
return 0;
}
最佳答案
不能将字符串与==
进行比较
改变
if (type == "int") {
具有
if (strcmp(type, "int") == 0) {
与
float
相同。。。另一方面,不能传递像
1230
或13.39
这样的文本的地址,请使用中间指针:int i = 1230;
int *pi = &i;
puts(pi);
然后在通用宏中:
#define puts(x) \
_Generic((x), \
char*: _puts((x), "str"), \
int *: _puts((x), "int"), \
double *: _puts((x), "float") \
)
GLib使用一些丑陋的技巧将文本(casting to
long
)作为指针传递,但这不是可移植的:Type Conversion Macros另外,请注意
puts
是标准库中函数的名称,覆盖此名称不是一个好主意。为了传递指针,使用复合文字更正了代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Puts(x) \
_Generic((x), \
char *: _Puts((x), "str"), \
int *: _Puts((x), "int"), \
double *: _Puts((x), "float") \
)
static void _Puts(void *d, const char *type)
{
if (strcmp(type, "int") == 0) {
printf("%d\n", *(int *)d);
} else
if (strcmp(type, "float") == 0) {
printf("%f\n", *(double *)d);
} else {
printf("%s\n", (char *)d);
}
}
int main(void)
{
Puts("String");
Puts((int []){1230});
Puts((double []) {13.37});
return 0;
}
关于c - 具有void *指针的_Generic宏不带双引号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49829970/