C 整数到字符串转换器(使用宏)

C 整数到字符串转换器(使用宏),c,macros,C,Macros,我在做宏的基础知识。我对宏的定义如下: #define INTTOSTR(int) #int 将整数转换为字符串 该宏是否将整数完美地转换为字符串?我的意思是,在某些情况下,这个宏会失败吗 我是否可以使用此宏替换标准库函数,如itoa() 例如: int main() { int a=56; char ch[]=INTTOSTR(56); char ch1[10]; itoa(56,ch1,10); printf("%s %s",ch,ch1);

我在做宏的基础知识。我对宏的定义如下:

#define INTTOSTR(int) #int
将整数转换为字符串

该宏是否将整数完美地转换为字符串?我的意思是,在某些情况下,这个宏会失败吗

我是否可以使用此宏替换标准库函数,如
itoa()

例如:

int main()
{
    int a=56;
    char ch[]=INTTOSTR(56);
    char ch1[10];
    itoa(56,ch1,10);
    printf("%s %s",ch,ch1);
    return 0;
}
INTTOSTR(53.5);
上述程序按预期运行。

有趣的是,这个宏甚至可以将
float
值转换为字符串

例如:

int main()
{
    int a=56;
    char ch[]=INTTOSTR(56);
    char ch1[10];
    itoa(56,ch1,10);
    printf("%s %s",ch,ch1);
    return 0;
}
INTTOSTR(53.5);
效果很好

到目前为止,我在所有项目中都在使用
itoa
函数将int转换为string。我可以在所有项目中自信地替换itoa吗。因为我知道使用宏的开销比函数调用小。

宏在编译时执行(确切地说是在编译前),所以您可以将源代码中的文字数字转换为字符串,而不是存储在变量中的数字

在您的示例中,
INTTOSTR(56)
使用预处理器的字符串化操作符,最终导致
“56”
。如果你对一个变量调用它,你会得到变量名而不是它的内容。

在C中,你可以使用itoa,或者如果你非常想避免它,可以使用snprintf,例如:

snprintf(my_str, sizeof(int), "%i", my_int);
宏的问题在于您考虑的是常量,但当然,当您需要使用包含整数的变量时,宏将被破坏。您的宏将尝试字符串化宏名称,而不是它将保留的值


如果你对常量没问题,你的宏是“好的”,否则它会被标记。

你的宏不会将整数转换成字符串,它会将文本转换成字符串文本,这是非常不同的

文字是代码中的任何普通数字或值定义。当你做
intx=10
整数文本中的数字
10
,而
x
是变量,
int
是类型<代码>常量字符*ten=“10”还定义了一个文本,在本例中是一个字符串文本,其值为
“10”
和一个名为
ten
的变量,该变量指向定义该文本的地址。宏实际上所做的是在任何实际编译开始之前更改文本的表示方式,从整数文本更改为字符串文本

因此,实际的更改是在编译之前完成的,只是在源代码级别。宏不是函数,无法检查内存,并且您的转换无法处理变量。如果您尝试:

int x = 10;
const char* ten = INTTOSTR(x);
如果发现变量
ten
实际上包含值“x”,您会非常困惑。这是因为x被视为一个文本,而不是一个变量

如果你想知道发生了什么,我建议你让你的编译器停止预处理,在你的代码被真正编译之前查看输出。如果传递-E标志,则可以在GCC中执行此操作


PS.关于浮点值转换的明显“成功”,它只是显示了宏的危险:它们不是类型安全的。它并不将53.5视为浮点,而是将其视为由字符5、3、、表示的标记。和源代码中的5。

您是否尝试了
INTTOSTR(a)
INTTOSTR(一些常量)
-Oops。这基本上是一个普通的字符串化宏,除了只用于整数,这不是太有用,特别是考虑到它接受其他东西。C++11有一个函数用于此。关于宏有几个问题。哦,是的,它不是转换变量:(实际上有趣的是,这个宏唯一能工作的东西就是你可以用引号括起来的东西。是的,先生,我注意到了,它不是转换变量:(是的,我明白了,我在想我已经开发出了一些真正有用的东西,甚至没有在变量上尝试过。