You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译器中格式说明符的工作原理:以C语言%s格式说明符为例

How the %s Format Specifier Works in C Compilation & Runtime

Great question! Let's break down exactly what happens with %s—from the moment you write your C code to when the output hits your terminal. I'll use your examples to make this concrete.

First: What the Compiler Does

The compiler doesn't actually "understand" what %s means in terms of output—that's the job of the printf function at runtime. But it does handle a few key things:

  • String Literal Storage: Any string you write (like "Hello %s" or "World !") gets packed into a read-only section of your program's memory (usually called .rodata in assembly). Your examples show this as .LC0: .string "World !" and .LC1: .string "Hello %s"—each line here is just the compiler assigning a memory address to your string, along with its raw byte data (including the hidden \0 terminator at the end of every C string).
  • Preparing the printf Call: The compiler converts your printf line into machine code that passes two pointers to the printf function:
    1. The address of the format string ("Hello %s").
    2. The address of the string you want to insert ("World !").
    • If you have compiler warnings enabled (like -Wall), it'll also check that your format specifiers match the argument types (e.g., it'll yell at you if you pass an integer instead of a string pointer for %s).

Then: What printf Does at Runtime

This is where %s actually does its magic. When printf runs:

  1. It starts reading the format string one character at a time.
  2. For regular characters (like H, e, l, l, o, and the space), it just sends them straight to your terminal.
  3. When it hits the % character, it knows to switch to "format specifier mode":
    • It looks at the next character (s) and knows: "Okay, I need to take the next argument from the list, which is a pointer to a string."
    • It grabs that pointer (the address of "World !"), then starts reading characters from that memory address. It outputs each character until it hits the \0 terminator (the hidden end marker the compiler added to your string).
  4. Once it finishes handling %s, it goes back to reading the format string (though in your example, there's nothing left after %s).

Let's Walk Through Your Example

For your code printf("Hello %s", "World !");:

  • The compiler stores "World !" at address .LC0 and "Hello %s" at .LC1.
  • At runtime, printf gets .LC1 as its first argument. It outputs Hello , then sees %s.
  • It grabs .LC0 (the address of "World !"), outputs every character from that address until \0, resulting in World !.
  • Put it all together, you get Hello World ! printed to your screen.

A quick note: If you pass a pointer to a chunk of memory that doesn't have a \0 terminator, printf will keep reading and outputting garbage until it randomly hits a \0 somewhere in memory—this is a common source of bugs (buffer overflows)!

内容的提问来源于stack exchange,提问作者Lasan Nishshanka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:01:50