c - memcpy 到宏中定义的字符串缓冲区

标签 c string macros memcpy

我正在使用 avrx 构建一个在自定义微型设备上运行的软件,但我仍然是 C 语言的新手。 如 makefile 所示,它使用“c99 加 GCC 扩展”。 今天终于碰到了老同事写的一段代码,看得我莫名其妙:

#define SOMEDATA    "ABC"
void main(void)
{
    memcpy(SOMEDATA, "OK", sizeof("OK"));
    printf(SOMEDATA);//it works just fine?!?!?  

    memcpy(SOMEDATA, "VERY_LONG", sizeof("VERY_LONG"));
    printf(SOMEDATA);//well, now it go nuts. all i see is some random data.
}

为什么? 为什么 main() 中的逻辑会这样?我曾经认为 MACROs 就像常量一样,不能修改。

最佳答案

在你的代码中

  memcpy(SOMEDATA, "OK", sizeof("OK"));

相同
  memcpy("ABC", "OK", sizeof("OK"));

是一种非常不寻常的尝试修改字符串文字的方式。它导致undefined behavior .与其他情况相同,正如我们所知,UB 的结果是任何结果。

也就是说,

   printf(SOMEDATA);

可能有效,但不是很好的做法,如果不需要转换,使用 puts()fputs() 会更安全。

最后,

I used to thought that MACROs acts like constant and cannot be modified.

嗯,您可能对#define 语句感兴趣。 #define 语句是在编译时发生的文本替换。如果将文字(或常量)值用作 define 语句,是的,它不能更改(遵循常量或文字的属性)但如果 define 语句定义变量名,则该变量,如果可修改的左值,肯定可以修改。

TL;DR #define 语句是文本替换,它们的改变取决于替换列表中的元素。

关于c - memcpy 到宏中定义的字符串缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44391061/

相关文章:

macros - 仅使用 LISP 原语定义 defmacro 函数?

C main 中的最大尺寸

c - 在 Turbo C 中覆盖背景的移动对象

c - 如何切换字符串大小写?

swift - 在 Swift 3 中迭代和操作字符串

c++ - 我希望 cin 读取到 '\n' 但我不能使用 getline

c# - 是否有用于 Java 或 C# 的宏工具?

c - 如何在 vigenere cipherkey cs50 pset2 中重用(循环) key

c - 机器人的微 Controller 选择和编程

vb.net - 字符串 3 位小数