printf的原型和实现

时间:2013-12-05 14:18:41

标签: c variadic-functions

我开始想知道如何声明printf函数,它总是收到一个字符串作为第一个参数(好吧,const char*),然后其余的参数可以是各种类型的,可变数量的它们以不同的顺序给出。

这是否意味着为每种可能性声明和覆盖printf函数?这对我来说没有多大意义,所以它真的像这样工作还是它的方式不同?

此外,该功能如何实施?如果它过于复杂,我只想知道它在内部是如何工作的。

4 个答案:

答案 0 :(得分:5)

  

如何声明printf函数

printfvariadic function,它自C99以来声明如下:

​int printf( const char *restrict format, ... );
                                         ^^^

...或省略号表示存在可变数量的参数,我们将使用 va_start va_arg va_end 宏和 va_list 类型来访问参数。

  

该功能是如何实现的?

以及上面链接的文档中给出了一个非常简单的printf示例如下并修改为在 C 中工作:

#include <stdio.h>
#include <stdarg.h>

void simple_printf(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);

    while (*fmt != '\0') {
        if (*fmt == 'd') {
            int i = va_arg(args, int);
            printf( "%d\n", i ) ;
        } else if (*fmt == 'c') {
            int c = va_arg(args, int);
            printf( "%c\n", (char)c ) ;
        } else if (*fmt == 'f') {
            double d = va_arg(args, double);
            printf( "%f\n", d ) ;
        }
        ++fmt;
    }

    va_end(args);
}

int main()
{
    simple_printf("dcff", 3, 'a', 1.999, 42.5); 
}

答案 1 :(得分:0)

printf的原型是:

int printf(const char *restrict format, ...);

此功能(参数...)称为可变参数功能。你也可以在stdarg.h的帮助下完成这项工作。

这是一个开始:C FAQ: Variable-Length Argument Lists

答案 2 :(得分:0)

每个标准库都有相应的头文件,其中包含该库中所有函数的函数原型以及函数所需的各种数据类型和常量的定义。 printf的标头为<stdio.h>,其中包含原型

int printf( const char *restrict format, ... );

答案 3 :(得分:0)

这是一个俗气的小程序,它显示printf的原型为:

int printf ( const char * format, ... );

(并且不需要其他人显示的restrict关键字)。

请注意,此处的printf与OUT一起使用,包括否则需要的stdio.h头文件。这是因为只需为printf函数声明 prototype 即可使编译器满意,因为它告诉该函数原型确实存在,并且由于{的定义(实现)的目标代码{1}}也恰好存在于其他地方,链接器在编译后链接时很高兴。

但是请注意,C ++需要使用printf来防止C ++编译器使用name-mangling函数名。有关我使用和测试的所有编译命令,请参见代码上方的注释。还要注意,打印“真实”的东西只是为了踢球,因为我正在测试一些东西。

hello_world.c

extern "C" {}

示例输出:

  

$ gcc -Wall -o hello_world hello_world.c && ./hello_world
  世界你好
  真== 1? = 1,“ true == 1”? = true