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
keil51下使用sprintf问题的更多相关文章
- 在Linux下使用sprintf代替atoi实现整型转化为char*
程序中需要用到将整型转化为char*类型,然后将两个char*类型的变量拼接.将整型转化为char*自然想到了itoa函数: 头文件:#include <stdio.h> char *it ...
- [c/c++] programming之路(4)、常量和变量
一.打开多个程序(温习) #include<stdio.h> #include<stdlib.h> void main(){ ; ]; scanf("%d" ...
- 【Ruby】【基础】
# [Ruby 块]=begin1 块由大量代码构成2 块中代码包含在{}内3 从与其相同名称的函数调用4 可以使用yield语句调用块=enddef test p '在test方法内' yield ...
- PHP微信公众号开发之自动回复
先把源码类发出来 <?php /** 自己封装 微信 开发api */ header('Content-type: text/html; charset=utf-8');#设置头信息 class ...
- gcc和vs在c的一些区别
1.switch中每个标签后面的命令在gcc中需要{}括起来以指明作用域. 2._itoa是非标准的c和c++扩展函数,在linux下可以使用sprintf(string, "%d &q ...
- C++ operator关键字详解
C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换. 类型转换操作符(type conversion operator)是一种特殊的类成员函数,它定义将类类型值转 ...
- 雷林鹏分享:Ruby 字符串(String)
Ruby 字符串(String) Ruby 中的 String 对象存储并操作一个或多个字节的任意序列,通常表示那些代表人类语言的字符. 最简单的字符串是括在单引号(单引号字符)内.在引号标记内的文本 ...
- C语言新手写扫雷攻略2
接下来是游戏的功能设计,要有扫雷的基本功能,左键点击雷区,右键红旗标记,并且可以统计雷数,可以重新开始,以下是游戏的功能初始 void Game(void) { while (1) { if (FLA ...
- C++程序结构---1
C++ 基础教程Beta 版 原作:Juan Soulié 翻译:Jing Xu (aqua) 英文原版 本教程根据Juan Soulie的英文版C++教程翻译并改编. 本版为最新校对版,尚未定稿.如 ...
随机推荐
- WPF不同线程之间的控件的访问
原文:WPF不同线程之间的控件的访问 WPF不同线程之间的控件是不同访问的,为了能够访问其他线程之间的控件,需要用Dispatcher.Invoke执行一个新的活动即可. 例如: public voi ...
- [折半搜索][哈希]POJ1186方程的解数
题目传送门 这道题明显N数据范围非常小,但是M很大,所以用折半搜索实现搜索算法的指数级优化,将复杂度优化到O(M^(N/2)). 将搜出的两半结果用哈希的方式合并(乘法原理). Code: #incl ...
- 如何补装oracle的sample schema
SQL>@ORACLE_HOME/rdbms/admin/utlsampl.sql; 似乎不够完整,等待补充.
- Linux5下安装MySQL过程记录
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页 回到顶级页面:PostgreSQL索引页 [作者 高健@博客园 luckyjackgao@gmail. ...
- 【转载】进程内COM与进程外COM
原文:http://www.cnblogs.com/jyz/archive/2009/03/08/1406229.html 1.进程内和进程外Com COM/DCOM 组件可以在DLL 或EXE 文档 ...
- ASP.NET Core开发期间部署到IIS自定义主机域名并附加到进程调试
在.NET Framework环境下,我们经常会这么做 把一个web项目不经过发布直接部署到IIS里去,配置上主机名,修改一下hosts文件,就可以用自定义的域名来访问我们的应用程序,使用附加到进程( ...
- java 迭代器只遍历了一次的解决方案
/** * 注意:因为迭代器只能遍历一次 所以每次用完都要重新填充一次 否则会出现只替换了一次检查配置项的情况 * templateJsonIterator = templateJsonObject. ...
- SpringBoot实现监听redis key失效事件
需求: 处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态 解决方案1: 可以利用redis天然的key自动过期机制,下单时将订单id写入redis,过期时间30分钟,30分钟后检查订单状态 ...
- 最安全的聊天工具——Cryptocat
关于Cryptocat Cryptocat 是啥?Cryptocat,俗称 "加密猫",是一款非常注重安全的聊天软件. 美国前中情局员工斯诺登在躲避美国政府追捕过程中,就是使用 C ...
- mysql 优化之 doublewrite buffer 机制
是什么? doublewrite buffer是mysql 系统表空间的一块存储区域. 有什么用? 在Innodb将数据页写到数据存储文件之前,存储从Innodb缓存池刷过来的数据页.且只有将数写入d ...