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

编译器中格式说明符的工作机制:以C语言%s为例解析

How Format Specifiers (like %s) Work in C: Compilation & Runtime Breakdown

Great question! Let’s walk through exactly how format specifiers such as %s operate, using your examples to clarify the compilation step and then diving into the runtime logic that makes the substitution happen.

Compilation Phase: What the Compiler Does (Not What You Might Think)

First, let’s clear up a common misconception: the compiler does NOT replace %s with your actual string during compilation. Instead, it handles two key tasks:

  1. Storing string literals in memory

    • Any string literal in your code (like "Hello %s" or "World !") gets packed into a read-only data section of the executable (your assembly examples show this as .LC0 and .LC1, which are compiler-generated labels for these string locations). The .string assembly directive just writes the ASCII bytes of the string into memory, including the literal %s characters—no substitution happens here.
    • For your example, the assembly output:
      .LC0: .string "World !"
      .LC1: .string "Hello %s"
      
      Simply means "World !" lives at the memory address labeled .LC0, and "Hello %s" lives at .LC1.
  2. Preparing the printf call

    • The compiler generates assembly code to pass the addresses of these strings as arguments to printf. Depending on the system’s calling convention (e.g., x86-64 System V or x86 cdecl), it’ll either load these addresses into registers or push them onto the stack, then issue a call to the printf function from the C standard library.
    • The compiler doesn’t parse the format string’s %s here—it just treats it as part of the first argument’s data.

Runtime Phase: How printf Handles %s

The actual magic of replacing %s with your string happens when the program runs, inside the printf function itself. Here’s the step-by-step:

  1. Traversing the format string

    • printf starts at the address of the format string (.LC1 in your example) and reads each character one by one:
      • When it hits regular characters (like H, e, l, l, o, ), it writes them directly to standard output.
      • When it encounters a % character, it knows to look at the next character to determine the format specifier.
  2. Processing %s specifically

    • When it sees s after the %, printf knows it needs to output a null-terminated string. It uses the macros from <stdarg.h> (like va_arg) to fetch the next argument from the variable argument list—which is the address of "World !" (.LC0).
    • printf then starts reading characters from that address, writing each one to standard output, until it hits the null terminator (\0) that marks the end of the string.
  3. Finishing up

    • After processing the %s and the rest of the format string, printf returns the number of characters written, and your program continues execution.

Putting It All Together With Your Example

For your code:

printf("Hello %s", "World !");
  • Compilation: The compiler stores "Hello %s" at .LC1 and "World !" at .LC0, then sets up the call to printf with these two addresses as arguments.
  • Runtime: printf outputs "Hello ", then sees %s, fetches the address of "World !", outputs those characters, resulting in the final output: Hello World !.

内容的提问来源于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 07:58:15