编译器中格式说明符的工作原理:以C语言%s格式说明符为例
%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.rodatain 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\0terminator at the end of every C string). - Preparing the
printfCall: The compiler converts yourprintfline into machine code that passes two pointers to theprintffunction:- The address of the format string (
"Hello %s"). - 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).
- The address of the format string (
Then: What printf Does at Runtime
This is where %s actually does its magic. When printf runs:
- It starts reading the format string one character at a time.
- For regular characters (like
H,e,l,l,o, and the space), it just sends them straight to your terminal. - 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\0terminator (the hidden end marker the compiler added to your string).
- It looks at the next character (
- 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.LC0and"Hello %s"at.LC1. - At runtime,
printfgets.LC1as its first argument. It outputsHello, then sees%s. - It grabs
.LC0(the address of"World !"), outputs every character from that address until\0, resulting inWorld !. - 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

