如果我写printf("%%%s","hello")
,它是如何被编译器解释的?启发我,有人。
答案 0 :(得分:13)
编译器简单地将此解释为使用两个字符串作为参数调用printf
(但请参阅Zack的注释)。
字符串("%%%s"
和"hello"
)直接复制到可执行文件中,编译器保持原样。
printf
代表'print formatted'。调用此函数时,至少需要一个参数。第一个参数是格式。下一个参数是这种格式的“参数”。它们的格式与第一个参数中指定的格式相同。
我编写了一个示例并使用-S
运行Clang / LLVM:
$ emacs printftest.c
$ clang printftest.c -S -o printftest_unopt.s # not optimized
$ clang printftest.c -S -O -o printftest_opt.s # optimized: -O flag
#include <stdio.h>
int main() {
printf("%%%s", "hello");
return 0;
}
; ...
_main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $0, %eax
movl $0, -4(%rbp)
movl %eax, -8(%rbp)
xorb %al, %al
leaq L_.str(%rip), %rdi
leaq L_.str1(%rip), %rsi
callq _printf ; printf called here <----------------
movl %eax, -12(%rbp)
movl -8(%rbp), %eax
addq $16, %rsp
popq %rbp
ret
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "%%%s"
L_.str1:
.asciz "hello"
; ...
; ...
_main:
pushq %rbp
movq %rsp, %rbp
leaq L_.str(%rip), %rdi
leaq L_.str1(%rip), %rsi
xorb %al, %al
callq _printf ; printf called here <----------------
xorl %eax, %eax
popq %rbp
ret
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "%%%s"
L_.str1:
.asciz "hello"
; ...
正如您所看到的(在__TEXT,__cstring,cstring_literals
部分和 callq
到printf
),LLVM(一个非常非常好的编译器)做不优化printf("%%%s", "hello");
。 :)
答案 1 :(得分:7)
“%%”表示打印实际的“%”字符; %s表示从参数列表中打印字符串。所以你会看到“%hello”。
答案 2 :(得分:1)
%%将打印文字'%'字符。