的printf( “%%% S”, “你好”)

时间:2011-03-25 18:45:53

标签: objective-c c

如果我写printf("%%%s","hello"),它是如何被编译器解释的?启发我,有人。

3 个答案:

答案 0 :(得分:13)

编译器简单地将此解释为使用两个字符串作为参数调用printf(但请参阅Zack的注释)。

这在编译时发生(即编译器执行此操作):

字符串("%%%s""hello")直接复制到可执行文件中,编译器保持原样。

这在运行时发生(即C标准库在应用程序运行时执行此操作):

printf代表'print formatted'。调用此函数时,至少需要一个参数。第一个参数是格式。下一个参数是这种格式的“参数”。它们的格式与第一个参数中指定的格式相同。

img


关于优化

我编写了一个示例并使用-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

C代码

#include <stdio.h>

int main() {
  printf("%%%s", "hello");
  return 0;
}

printftest_unopt.s(未优化)

; ...
_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"
; ...

printftest_opt.s(已优化)

; ...
_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部分 callqprintf),LLVM(一个非常非常好的编译器)做优化printf("%%%s", "hello");。 :)

答案 1 :(得分:7)

“%%”表示打印实际的“%”字符; %s表示从参数列表中打印字符串。所以你会看到“%hello”。

答案 2 :(得分:1)

%%将打印文字'%'字符。