winterw 发表于 2014-9-30 15:02:28

为什么keil用%d打印整型数值是不准确的?

不知道是不是我弄错了,这个现象很奇怪。

源码如下:
/*------------------------------------------------------------------------------
HELLO.C

Copyright 1995-1999 Keil Software, Inc.
------------------------------------------------------------------------------*/

#include <REG52.H>                /* special function register declarations   */
                                  /* for the intended 8051 derivative         */

#include <stdio.h>                /* prototype declarations for I/O functions */


#ifdef MONITOR51                         /* Debugging with Monitor-51 needs   */
char code reserve _at_ 0x23;         /* space for serial interrupt if   */
#endif                                 /* Stop Exection with Serial Intr.   */
                                       /* is enabled                        */


/*------------------------------------------------
The main C function.Program execution starts
here after stack initialization.
------------------------------------------------*/
void main (void) {
        char k=35;
/*------------------------------------------------
Setup the serial port for 1200 baud at 16MHz.
------------------------------------------------*/
#ifndef MONITOR51
    SCON= 0x50;                        /* SCON: mode 1, 8-bit UART, enable rcvr      */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload      */
    TH1   = 221;                /* TH1:reload value for 1200 baud @ 16MHz   */
    TR1   = 1;                  /* TR1:timer 1 run                        */
    TI    = 1;                  /* TI:   set TI to send first char of UART    */
#endif
       
/*------------------------------------------------
Note that an embedded program never exits (because
there is no operating system to return to).It
must loop and execute forever.
------------------------------------------------*/
while (1) {
    P1 ^= 0x01;                     /* Toggle P1.0 each time we print */
    printf ("Hello World,k=%d\n",k);   /* Print "Hello World" */
}
}



工程是keil安装后的C:\Keil\C51\EXAMPLES\HELLO 中的工程,拿来直接编译的,通过simulator模拟,从串口看时如下的结果:

明明k初始化为k=35,但是为什么打印的时候是8960呢,我计算了一下,8960为35的256倍,当初始化k=1时,打印的printf出来的k=256。
谁知道这是为什么吗?

takashiki 发表于 2014-9-30 15:05:36

改成printf ("Hello World,k=%d\n",(int)k);试试

winterw 发表于 2014-9-30 15:08:29

自己回一下:
重新测试了一下,看来强制类型转换出了问题。
需要变量类型与printf中的转义类型统一才行。
即: int k=1;时,printf("k=%d\n",k); 输出的值才是正确的k=1,而不是256。

大家用的时候都是这样吗?

XIVN1987 发表于 2014-9-30 15:10:36

char是8位的,要用%bd,不能用%d

C51这点和标准C不一样。。

ahong2hao 发表于 2014-9-30 15:15:55

刚刚试了一下,在MDK5.0里,不会出现LZ的问题。
估计是C51的定义不同吧。

winterw 发表于 2014-9-30 15:20:08

takashiki 发表于 2014-9-30 15:05
改成printf ("Hello World,k=%d\n",(int)k);试试

这招是可以的。

winterw 发表于 2014-9-30 15:21:32

XIVN1987 发表于 2014-9-30 15:10
char是8位的,要用%bd,不能用%d

C51这点和标准C不一样。。

想当然的以为一样了。
谢谢兄弟提醒。

shandong 发表于 2014-9-30 15:22:10

应该是与编译环境有关

winterw 发表于 2014-9-30 15:23:18

ahong2hao 发表于 2014-9-30 15:15
刚刚试了一下,在MDK5.0里,不会出现LZ的问题。
估计是C51的定义不同吧。

多谢帮忙测试。
估计是我使用的keil版本太老了,新的版本已经修改了bug。

cpwander 发表于 2014-9-30 15:28:37

d int Signed decimal number.
The optional characters b or B may immediately precede the type character to respectively specify char types for d, i, u, o, x, and X.

XIVN1987 发表于 2014-9-30 15:34:40

winterw 发表于 2014-9-30 15:23
多谢帮忙测试。
估计是我使用的keil版本太老了,新的版本已经修改了bug。
...


不是这样的,这个是C51自己的规定,新版C51也是这样的

MDK是ARM的开发工具,跟51单片机的C51没有关系

winterw 发表于 2014-9-30 15:41:18

cpwander 发表于 2014-9-30 15:28
d int Signed decimal number.
The optional characters b or B may immediately precede the type charac ...

Yep,you're right.I should be serious. no zuo no die.

winterw 发表于 2014-9-30 15:43:32

XIVN1987 发表于 2014-9-30 15:34
不是这样的,这个是C51自己的规定,新版C51也是这样的

MDK是ARM的开发工具,跟51单片机的C51没有关系 ...

你又帮我纠正了一个keil for arm 和keil for 51的概念。
再次表示感谢。

winterw 发表于 2014-9-30 15:48:05

XIVN1987 发表于 2014-9-30 15:34
不是这样的,这个是C51自己的规定,新版C51也是这样的

MDK是ARM的开发工具,跟51单片机的C51没有关系 ...

看了这张图终于明白了keil的众多版本是做什么用的了。

两个嘴巴笑110 发表于 2014-10-1 21:13:43

我想问一下LZ,你是在开发单片机的时候使用的printf吗?

那如果使用的话,要另外加什么重映射的函数呢?还是有什么设置呢?

LZ可以告诉我一下吗?我只在STM32中使用printf函数,在51中还没有使用过printf函数。

gujiamao_love 发表于 2014-10-1 22:01:45

两个嘴巴笑110 发表于 2014-10-1 21:13
我想问一下LZ,你是在开发单片机的时候使用的printf吗?

那如果使用的话,要另外加什么重映射的函数呢?还 ...

补充映射,怎么到串口上。

gujiamao_love 发表于 2014-10-1 22:02:45

到底是编译器还是c51的问题,我用IAR一直这么用的,没有问题。

两个嘴巴笑110 发表于 2014-10-1 22:03:00

gujiamao_love 发表于 2014-10-1 22:01
补充映射,怎么到串口上。

就是和STM32一样,要加入printf的重映射函数吧?

gujiamao_love 发表于 2014-10-1 22:09:03

两个嘴巴笑110 发表于 2014-10-1 22:03
就是和STM32一样,要加入printf的重映射函数吧?

是的,但是51还是不要用printf吧,占用的资源较多。

xwkm 发表于 2014-10-2 00:12:27

Keil C少用吧。SDCC就没这么纠结了

winterw 发表于 2014-10-2 18:15:45

两个嘴巴笑110 发表于 2014-10-1 21:13
我想问一下LZ,你是在开发单片机的时候使用的printf吗?

那如果使用的话,要另外加什么重映射的函数呢?还 ...

void Uprintf(char *str,...)
{
        char xdata buf;
        unsigned char xdata i = 0;
        xdata va_list ptr;
        va_start(ptr,str);
        memset(buf,0,sizeof(buf));
        vsprintf(buf,str,ptr);

        while(buf)
        {
                Serial_SendChar(buf);
                i++;
        }
}
我重新实现了一下printf函数。
页: [1]
查看完整版本: 为什么keil用%d打印整型数值是不准确的?