none
C/C++中的printf()输出结果分析 RRS feed

  • 问题

  • 请问

    printf("%d\n");

    printf("%x\n");

    printf("%f\n");

    printf("%lf\n");

    printf("%c\n");

    的输出结果均为什么呢?当我运行输出的时候我就不知道怎么解释这个输出结果,请帮忙解释下,谢谢。当输出列表的时候没有输出参数。

    2011年8月2日 15:23

答案

  • 你好,

     

    很抱歉误解了您的意思。

    以下是printf()方法的实现:

    #define stdout (&__iob_func()[1])

     

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

    /*stdout 'PRINT', 'F'ormatted */

    {

        va_list arglist;                 // 定义 可变参数列表指针

        int buffing;                     

        int retval;

     

        _VALIDATE_RETURN( (format != NULL), EINVAL, -1);

        va_start(arglist, format);          // 从参数表中取得第一个引数

        _lock_str2(1, stdout);

        __try {

            buffing = _stbuf(stdout);

           retval = _output_l(stdout,format,NULL,arglist);// 打印输出

            _ftbuf(buffing, stdout);

        }

        __finally {

            _unlock_str2(1, stdout);

        }

        return(retval);

    }

     

    由此可以见,printf是从堆栈中从内存的高地址向低地址读取到数据,由于在debug模式下,编译器会自动为我们初始化数据,因此在debug模式下printf显示结果为初始化后的结果。如果我们在release模式下,printf就会从堆栈取出没有初始化后的数据,即脏数据。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Rob Pan 2011年8月12日 8:17
    2011年8月9日 8:27

全部回复

  • 输出结果不一定,可能会导致程序崩溃

    printf是变长参数,运行时会查找当前在线程栈中的第一个数据来填那个值,如果是%s这样的指针类型,线程栈中的第一个数据不是有效指针地址的话就会崩溃,否则,输出那个数据,但是那个数据对你来说算是一个随机的数据


    0xBAADF00D
    2011年8月3日 1:07
    版主
  • 你好,

     

    通常情况下

    printf("%d\n");                 //  有符号10进制整数

    printf("%x\n");                 //  无符号的16进制数字,并以小写abcdef表示

    printf("%f\n");                  //  浮点数

    printf("%lf\n");                 //  双精度浮点数

    printf("%c\n");                  //   单个字符

     

    此外还有:

    i 有符号10进制整数

    o 无符号8进制整数

    X 无符号的16进制数字,并以大写ABCDEF表示

    E/e 用科学表示格式的浮点数

    g 使用%f%e表示中的总的位数表示最短的来表示浮点数 G g格式,但表示为指数

    u 无符号10进制整数

    s 字符串

    S wchar_t字符(宽字符)类型字符串


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年8月4日 7:04
  • 请问

    printf("%d\n");

    printf("%x\n");

    printf("%f\n");

    printf("%lf\n");

    printf("%c\n");

    的输出结果均为什么呢?当我运行输出的时候我就不知道怎么解释这个输出结果,请帮忙解释下,谢谢。当输出列表的时候没有输出参数。


    易isprime
    2011年8月5日 13:39
  • 我知道有这么多的格式控制符,但是我如果在输出列表中不提供任何的变量。只有像printf("%d\n");这样的语句,编译运行也会输出结果,我想问的是这个输出结果该怎么解释。谢谢诶。
    2011年8月5日 17:08
  • 你好,

     

    很抱歉误解了您的意思。

    以下是printf()方法的实现:

    #define stdout (&__iob_func()[1])

     

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

    /*stdout 'PRINT', 'F'ormatted */

    {

        va_list arglist;                 // 定义 可变参数列表指针

        int buffing;                     

        int retval;

     

        _VALIDATE_RETURN( (format != NULL), EINVAL, -1);

        va_start(arglist, format);          // 从参数表中取得第一个引数

        _lock_str2(1, stdout);

        __try {

            buffing = _stbuf(stdout);

           retval = _output_l(stdout,format,NULL,arglist);// 打印输出

            _ftbuf(buffing, stdout);

        }

        __finally {

            _unlock_str2(1, stdout);

        }

        return(retval);

    }

     

    由此可以见,printf是从堆栈中从内存的高地址向低地址读取到数据,由于在debug模式下,编译器会自动为我们初始化数据,因此在debug模式下printf显示结果为初始化后的结果。如果我们在release模式下,printf就会从堆栈取出没有初始化后的数据,即脏数据。


    Rob Pan [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Rob Pan 2011年8月12日 8:17
    2011年8月9日 8:27