C中的printf不占用内存?

printf是否占用了堆栈中的内存?

 printf("Hello world"); 

"Hello world"有一个恒定的地址吗?

请帮我理解。

编辑:

我们为printf传递的参数是否存储在本地指针变量中。 如果我使用一个数组来存储50个字符串文字,它需要堆栈内存,但如果我使用printf它不占用内存 – 就是我所听到的。 但我不知道printf如何不像我们声明的数组那样占用内存。

请帮我理解!

这取决于您的平台的调用约定以及标准库的实现方式。

例如,采取以下计划:

 #include  int main(void) { printf("Hello, World\n"); return 0; } 

和以下命令行来编译它:

 gcc -S -std=c99 -pedantic -Wall -Werror syscall.c 

在使用gcc 2.96的32位Red Hat盒子(i686)上,我们得到以下机器代码:

       1 .file“syscall.c”
       2 .version“01.01”
       3 gcc2_compiled。:
       4。节.rodata
       5 .LC0:
       6 .string“Hello,World \ n”
       7。文字
       8。4
       9 .globl主要
      10. .type main,@ function
      11主要:
      12 pushl%ebp
      13 movl%esp,%ebp
      14 subl $ 8,%esp
      15 subl $ 12,%esp
      16 pushl $ .LC0
      17打电话给printf
      18 addl $ 16,%esp
      19 movl $ 0,%eax
      20离开
      21回复
      22 .Lfe1:
      23 .size main,.Lfe1-main
      24。“GCC:(GNU)2.96 20000731(Red Hat Linux 7.2 2.96-112.7.2)”

第16行将字符串文字的地址压入堆栈,然后调用printf

这是使用gcc 4.1.2在64位SLES 10盒(x86_64)上以相同方式编译的相同代码:


       1 .file“syscall.c”
       2。节.rodata
       3 .LC0:
       4 .string“Hello,World”
       5。文字
       6 .globl主要
       7 .type main,@ function
       8主要:
       9 .LFB2:
      10 pushq%rbp
      11 .LCFI0:
      12 movq%rsp,%rbp
      13 .LCFI1:
      14 movl $ .LC0,%edi
      15个看跌期权
      16 movl $ 0,%eax
      17离开
      18回
 ;;
 ;; 其他内容不包括在内
 ;;

在这种情况下,第14行将字符串文字的地址写入寄存器%edi ),而不是将其推入堆栈。 另请注意,此版本的gcc足够智能,可以实现,因为我传递的是char *类型的单个参数,它可以替换对puts的调用。

在任何一种情况下,您在拨打电话时都会创建一个新的堆栈帧; 不同之处在于堆栈框架中的内容。 在Red Hat框中,它将包含字符串文字的地址; 在SLES 10盒子上,它不会。

字符串文字,即"Hello world" ,占用内存,但不在堆栈上,而是在只读静态段中。 除了read-only memory ,其余的都是实现细节。

没有必要相同的字符串文字占用相同的内存(因此地址不保证是恒定的),但它们可能。

在C语言中,字符串文字具有静态存储持续时间 。 这意味着它们在程序的整个持续时间内存在(并且指向它们的指针仍然有效); 这与通常在调用帧堆栈上实现的自动局部变量相反。