为什么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。
谁知道这是为什么吗?
改成printf ("Hello World,k=%d\n",(int)k);试试 自己回一下:
重新测试了一下,看来强制类型转换出了问题。
需要变量类型与printf中的转义类型统一才行。
即: int k=1;时,printf("k=%d\n",k); 输出的值才是正确的k=1,而不是256。
大家用的时候都是这样吗?
char是8位的,要用%bd,不能用%d
C51这点和标准C不一样。。 刚刚试了一下,在MDK5.0里,不会出现LZ的问题。
估计是C51的定义不同吧。 takashiki 发表于 2014-9-30 15:05
改成printf ("Hello World,k=%d\n",(int)k);试试
这招是可以的。
XIVN1987 发表于 2014-9-30 15:10
char是8位的,要用%bd,不能用%d
C51这点和标准C不一样。。
想当然的以为一样了。
谢谢兄弟提醒。
应该是与编译环境有关 ahong2hao 发表于 2014-9-30 15:15
刚刚试了一下,在MDK5.0里,不会出现LZ的问题。
估计是C51的定义不同吧。
多谢帮忙测试。
估计是我使用的keil版本太老了,新的版本已经修改了bug。
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.
winterw 发表于 2014-9-30 15:23
多谢帮忙测试。
估计是我使用的keil版本太老了,新的版本已经修改了bug。
...
不是这样的,这个是C51自己的规定,新版C51也是这样的
MDK是ARM的开发工具,跟51单片机的C51没有关系 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. XIVN1987 发表于 2014-9-30 15:34
不是这样的,这个是C51自己的规定,新版C51也是这样的
MDK是ARM的开发工具,跟51单片机的C51没有关系 ...
你又帮我纠正了一个keil for arm 和keil for 51的概念。
再次表示感谢。 XIVN1987 发表于 2014-9-30 15:34
不是这样的,这个是C51自己的规定,新版C51也是这样的
MDK是ARM的开发工具,跟51单片机的C51没有关系 ...
看了这张图终于明白了keil的众多版本是做什么用的了。
我想问一下LZ,你是在开发单片机的时候使用的printf吗?
那如果使用的话,要另外加什么重映射的函数呢?还是有什么设置呢?
LZ可以告诉我一下吗?我只在STM32中使用printf函数,在51中还没有使用过printf函数。 两个嘴巴笑110 发表于 2014-10-1 21:13
我想问一下LZ,你是在开发单片机的时候使用的printf吗?
那如果使用的话,要另外加什么重映射的函数呢?还 ...
补充映射,怎么到串口上。 到底是编译器还是c51的问题,我用IAR一直这么用的,没有问题。 gujiamao_love 发表于 2014-10-1 22:01
补充映射,怎么到串口上。
就是和STM32一样,要加入printf的重映射函数吧? 两个嘴巴笑110 发表于 2014-10-1 22:03
就是和STM32一样,要加入printf的重映射函数吧?
是的,但是51还是不要用printf吧,占用的资源较多。 Keil C少用吧。SDCC就没这么纠结了 两个嘴巴笑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]