在 printf ( "%d", 5 ); 5存储在内存中吗?

In printf ( "%d", 5 ); is 5 stored in the memory?

#include <stdio.h>
char* func ();
int main ( )
{
   char *p;
   p=func();
   printf("%c",*p);
}
char* func()
{

    return "hello";
}

这里,printf 打印出"h",这意味着创建了指向"hello" 的指针,并且将字符串"hello" 存储在内存中。 同样,在printf("%d", 5)中,'5'是否存储在内存中?

您打印的只是一个字符,以便打印出存储在内存位置的整个字符串

printf("%s",p);

%s 格式说明符确保打印字符,直到找到 [=12=] 字符

你的问题非常依赖于平台,但大多数理智的编译器不应该将 5 存储在你代码的任何数据部分,只读或其他 - 它应该简单地在 printf 呼叫.

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

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

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

函数调用中的整型字面量很可能会通过一次操作放入堆栈。您可以从被调用函数(即 printf)中访问 5 的内存地址,但是当函数 returns 它将被弹出堆栈。

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

在声明中

printf( "%d", 5 );

格式字符串后的参数作为 C 可变参数 传递,由形式参数列表中的三个句点 ... 指定。这意味着就编译器而言,没有特定类型是 1 预期的,除了不允许非 POD class 类型的实际参数。这也意味着在它们被传递之前,值被 提升 为更小的类型集,对于通常高达 int 的整数,对于高达 double.

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

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


1) 聪明的编译器可以知道printf等常见的标准库函数,并解释格式字符串等。 g++ 就是这样做的。在旧的 C 时代,这是一个名为 lint.

的单独程序的功能

5和"hello"的区别在于"hello"是一个数组,所以它是作为参数传递的,并以指针形式作为结果返回(作为指向第一个元素的指针).函数的 int 参数,如 printf,是按值传递的,内存可能仅在函数调用期间存在。

编译后的代码可能(而且通常会)只是将常量 5 压入该参数的堆栈。有内存,好吧,但它是机器指令中的位域,而不是数据字。

如果您有调试器,在调用时反汇编代码以了解我的意思可能对您来说很有趣。例如,在 x86 处理器上,操作码名称很容易大致找出发生了什么。

在那个 printf 调用中,您会看到格式字符串作为指向常量数据内存中存储字符串的指针被推送,但是 5 可能是 "immediate" 推送值 5。("Immediate" 汇编中的数据意味着该值在指令本身中,而不是从数据存储器中单独获取。)

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