keil51下使用sprintf问题

测试环境:keil c51 + STC89C52
说明:

1.keil的不定参数只有15个字节
也就是说sizeof(...) 加起来总共不能超过15字节,否则会出错

2.当不定参数中有常数时,你也会得不到你想要的结果,字符串除外

例:
 unsigned char count_sec=2, count_min=3, count_hour=4;
 xdata char buf[12] = "";
 sprintf(buf, "%2d:%2d:%2d", count_hour, count_min, count_sec);
则转换完的结果是不正确的。
解决方式1:
unsigned char count_sec=2, count_min=3, count_hour=4;
改成:
unsigned int count_sec=2, count_min=3, count_hour=4;
相同的代码在VC6.0下却是正常,为何?
printf("%d\n",12);
printf("%d\n",1234);
/****************KEIL C51**************************/
143: printf("%d\n",12); 
C:0x098D 7BFF MOV R3,#0xFF
C:0x098F 7A0A MOV R2,#0x0A
C:0x0991 7902 MOV R1,#0x02
C:0x0993 75390C MOV 0x39,#0x0C
C:0x0996 12057D LCALL PRINTF(C:057D)
144: printf("%d\n",1234); 
C:0x0999 7BFF MOV R3,#0xFF
C:0x099B 7A0A MOV R2,#0x0A
C:0x099D 7902 MOV R1,#0x02
C:0x099F 753904 MOV 0x39,#0x04
C:0x09A2 753AD2 MOV 0x3A,#0xD2
C:0x09A5 12057D LCALL PRINTF(C:057D)

/******************VC++6.0***************************/
155: printf("%d\n",12);
00401628 push 0Ch
0040162A push offset string "%d\n" (00426034)
0040162F call printf (00411040)
00401634 add esp,8
156: printf("%d\n",1234);
00401637 push 4D2h
0040163C push offset string "%d\n" (00426034)
00401641 call printf (00411040)
00401646 add esp,8
/*************************************************/

这个时候你会发现,为什么keil c51会错了,因为它没有内存对齐
输入常数12的时候,占一个字节,他就给你分配一个字节,输入1234的时候占2个字节
他就给你分配两个字节
而VC++6.0就不一样了,你输入的常数起码都给分配4个字节,所以在你取数据的时候,
取四个字节就不会错了,keil呢,该取几个呢?不知道?所以数据会出错

参考自:http://hi.baidu.com/bnsd_/item/91d926c13a17f44ea8ba9467

时间: 2024-11-06 03:32:08

keil51下使用sprintf问题的相关文章

keil的51和ARM共存方法

Keil和MDK共存,按照以下步骤:1 先安装 Keil C51,安装目录改为:"D:\Keil51"(我是安装在D盘的)2 再安装RealView MDK,目录:"D:\Keilarm"3 把Keil51下的C51这个文件夹全部复制到 Keilarm下4 把Keil51下的 UV4(或者UV3)下的所有文件复制粘贴到 Keilarm下的UV4文件夹里,注意,如果提示有 重复 的文件,是否覆盖时,一律选择否,即不覆盖.5 把Keil51下的Tools.ini文件 内

C语言新手写扫雷攻略2

接下来是游戏的功能设计,要有扫雷的基本功能,左键点击雷区,右键红旗标记,并且可以统计雷数,可以重新开始,以下是游戏的功能初始 void Game(void) { while (1) { if (FLAG == 1) { GameBegin();//绘制出游戏界面并判断是否玩过和重新开始 GamePlay();//游戏过程的函数 if (AGAIN == 1) { AGAIN = 0; continue; } } FLAG = 0; if (m.uMsg == WM_LBUTTONDOWN)//鼠

雷林鹏分享:Ruby 字符串(String)

Ruby 字符串(String) Ruby 中的 String 对象存储并操作一个或多个字节的任意序列,通常表示那些代表人类语言的字符. 最简单的字符串是括在单引号(单引号字符)内.在引号标记内的文本是字符串的值: 'This is a simple Ruby string literal' 如果您需要在单引号字符串内使用单引号字符,那么需要在单引号字符串使用反斜杠,这样 Ruby 解释器就不会认为这个单引号字符会终止字符串: 'Won\'t you read O\'Reilly\'s book

关于sprintf函数不同环境下的执行结果

作者:iamlaosong 今天发现sprintf函数的一个问题,不同环境下同样语句执行结果是不一样的.一个时间字符串,要求是6位,不足6位时前面补0,用下面语句实现: strcpy(tt,"2345"); printf("==%s==",tt); sprintf(t1,"%06s",tt); printf("==%s==",t1); 上述语句VC的执行结果:==2345====002345== 同样语句Linux下执行结果:

openCV学习笔记(5):使用sprintf函数实现在窗口连续显示同一文件夹下的图片

一.环境: vs2010 + opencv2.3.1 二.程序: #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; using namespace std; int main() { Mat colorImage; //Mat depthImage; //////////////////

在 linux 下用 C 寫 socket 程式

十幾年沒有寫 C 了,這可以說是重新學習,底下的程式是改寫自 W.Richard Stevens 的名著 - Networking APIs: Sockets and XTI,改寫的原因有二: (1) 在我的開發環境 scientific linux 7.0 上沒辦法正常 compile,可能是因為 Stevens 的程式是在 UNIX 上寫的,與 linux 上略有不同; (2) Stevens 用 #define 將許多常用的函式重新定義,對於初學者來說,反而會被混淆,我將這些函式還原為原始

itoa函数,sprintf函数

itoa函数 itoa 为c语言的一个函数.itoa 函数是一个广泛应用的,从非标准扩展到标准的C语言.它不能被移植,因为它不是标准定义下的C语言,但是,编译器通常在一个不遵循程式标准的模式下允许其通过header ,因为它是一个从逻辑对应到标准库的函数.itoa 取整数输入值,并将其转换为相应进制数字的字符串. 用法: itoa(i ,num ,10 ); i ---- 需要转换成字符串的数字 num ---- 转换后保存字符串的变量 10 ---- 转换数字的基数(即进制).10就是说按10

c语言学生管理系统链表(dev vs2012下可以运行)

struct student { char name[10]; char sex[5]; long int num;//学号 int xuhao; int age; float score[3]; float averange; char DJ;//存放等级哦 struct student *next; };//定义结构体变量保存 名字 性别 年龄 成绩] 结构体声明 int n;//存放学生人数 int man;//存放统计的男生数 float JY(float a)//校验成绩使范围0-10

matlab从文件夹名中获得该文件夹下所图像文件名

function [s,nameC]=get_FileNameFromFolderPath(path) % 函数调用:[s,nameC]=get_FileNameFromFolderPath(path) % 函数功能:从文件夹名中获得该文件夹下所图像文件名 % 函数输入:path 为文件夹路径 % 函数输出:s 表示状态,当为0时表示正确 % nameC 表示获得的图像名的胞体cell % 函数历史:v0.0 @2013-01-27 created by Aborn cmd = sprintf(