在printf(“%d”,5); 是5存储在内存中?

#include  char* func (); int main ( ) { char *p; p=func(); printf("%c",*p); } char* func() { return "hello"; } 

这里,printf打印“h”,这意味着创建了一个指向“hello”的指针,并且字符串“hello”存储在内存中。 同样,在printf(“%d”,5)中,存储在存储器中的是“5”吗?

您的问题非常依赖于平台,但是大多数理智的编译器不应该在代码的任何数据部分中存储5 ,只读或其他 – 它应该在printf调用之前简单地压入堆栈。

编辑:我实际上刚刚检查过,GCC做了一些更有趣的事情:

它完全避免了64位机器上的堆栈,并且由于可用的众多而使用直接寄存器。 它仍然不会将5存储在操作码本身中。

您打印的内容只是一个字符,用于打印存储在内存位置的整个字符串

 printf("%s",p); 

%s格式说明符确保打印字符,直到找到\0字符

如果您想确保检查编译器的adsembler语言输出。

最有可能函数调用中的整数文字将通过单个操作放在堆栈上。 您可以从被调用函数(即printf)中访问5的内存地址,但是当函数返回时,它将从堆栈中弹出。

5和“hello”之间的区别在于“hello”是一个数组,因此它作为参数传递并以指针forms返回(作为指向第一个元素的指针)。 函数的int参数(如printf )按值传递,并且内存可能仅在函数调用期间存在。

编译后的代码可以(并且通常会)将常量5推送到该参数的堆栈上。 有记忆,好吧,但它是机器指令中的一个字段而不是数据字。

如果你有一个调试器,你可能会有兴趣在调用时反汇编代码看看我的意思。 例如,在x86处理器上,操作码名称很容易就可以近似地找出正在发生的事情。

在该printf调用中,您将看到格式字符串被推送为指向常量数据存储器中存储字符串的指针,但5可能是值“5”的“立即”推送。(汇编中的“立即”数据)表示该值在指令本身中,而不是与数据存储器分开获取。)

最重要的是,在执行函数期间,只保证堆栈的内存存在于堆栈中。

在发布这个答案之后,问题从C ++改为C.我不打算追逐一个不断变化的问题,但我将这个答案保留原样,因为它可能对读者有用。

在声明中

 printf( "%d", 5 ); 

格式字符串后面的参数作为C variadic参数传递,由forms参数列表中的三个句点...指定。 这意味着就编译器而言,没有特定类型是预期的,除了不允许非POD类类型的实际参数。 它还意味着在它们被传递之前,值被提升为一组较小的类型,对于通常最多为int ,以及对于浮点数最多为double整数。

5通常是机器代码指令的一部分,该指令将该值推送到机器的运行时堆栈上。

作为指令的一部分,它位于“内存”中,但它不需要是一个可以作为该数值值轻松访问的独立部分,它甚至不需要是C ++对象所在的普通数据存储器(某些微控制器使用)哈佛架构有单独的代码和数据存储器,可能,但我不知道,他们有C ++编译器)。


1 )智能编译器可以了解常见的标准库函数,例如printf ,解释格式字符串等。例如,g ++就是这样做的。 在旧的C时代,这是一个名为lint的独立程序的function。