易截截图软件、单文件、免安装、纯绿色、仅160KB

[C/C++] 把一个整型整数转成字符串

问题描述:写一个函数,接受一个整数(假定用int表示),输出该整数的字符串形式。采用如下函数原型:
void itoa ( int val, buf* );
这里假定buf足够大以容纳任何int类型数值的字符串。
这个问题,初看好像没有什么难度。如果是0,就直接输出'0';如果是正数,就通过取模(%)和求商(/)运算可以逐位取得该整数的数字,并把它们放到buf中去;如果是个负数,就先转成正的,然后在最后输出时加入负号。按照这个思路,可以写下如下代码:
void itoa_flawed(int val, char* buf)
{
// deal with special case
if(val == 0)
{
buf[0] = '0';
buf[1] = '\0';
return;
}
bool negative = (val < 0);
int abs_val = negative ? -val : val;
unsigned int char_cnt = 0;
while(abs_val > 0)
{
buf[char_cnt] = abs_val % 10 + '0';
char_cnt ++;
abs_val = abs_val / 10;
}
if(negative) buf[char_cnt++] = '-';
//reverse the string
unsigned int i = 0;
while(i < char_cnt / 2)
{
char temp = buf[i];
buf[i] = buf[char_cnt-i-1];
buf[char_cnt-i-1] = temp;
i++;
}
buf[char_cnt] = '\0';
}
 
一切看起来都没有问题。但是,如果我们这样调用该函数的话,猜猜会输出什么:
char buf[40];
itoa_flawed(1 << 31,buf);
cout<<buf;

我们得到的是"-"。这是为什么呢?大家请注意第11行代码。当我们求一负数的绝对值时,如果还是用原来大小的有符号类型时,可能会产生溢出!我们知道,int类型只能表示-231
~ 231
-1
之间的数值。如果我们对-231
求绝对值并把它存放到int类型的变量中,会发生什么情况?分析到这里,大家都应该清楚了吧!
这个bug是很隐蔽的。我在网上看到的代码基本上都和上面给出的差不多,没有考虑这个可能的溢出问题。修正的办法,就是用更大的类型来存放绝对值。观察到绝对值是非负的,我们可以用一个unsigned int
来表示绝对值,这样就不会有问题了。
这个题目给我的启示是,虽然看起来简单的题目,也可能有很大的陷阱。如果这是一道面试题的话,估计完全做对的不多,可能也包括现场的我在内。


相关文档:

C 数据结构题目答案分享

大学已经来到了最重要的时期了,我不能再一事无成了。光说没用,所以就在这里写下文章,以记录我的成长历程。
这学期刚好学到数据结构,那就将题目分析的过程及代码写下来,供以后自己取舍。因本人水平一般,所以代码并不一定是最优的,但是我会努力改进,做最好的自己! ......

[VC]函数调用约定解析(C/C++)

C/C++函数调用约定和函数名称修饰规则探讨
作者:星轨(oRbIt)
 
使用C/C++语言开发软件的程序员经常碰到这样的问题:有时候是程序编译没有问题,但是链接的时候总是报告函数不存在(经典的LNK
2001错误),有时候是程序编译和链接都没有错误,但是只要调用库中的函数就会出现堆栈异常。这些现象通常是出现在C和C ......

C语言编写linux下的守护进程

利用
下载的这段代码,成功实现了守护进程,原来守护进程是很简单的事情。
  在main函数中执行
  init_daemon();//初始化为Daemon
  就可以把进程变成守护进程
  
#include
#include
#include
#include
#include
void
 init_daemon(void
)
{
int
 pid;
int
 i;
if
(pid=fork()) ......

C/C++中的64位整数(__int64 and long long)

  在做ACM题时,经常都会遇到一些比较大的整数。而常用的内置整数类型常常显得太小了:其中long 和 int
范围是[-2^31,2^31),即-2147483648~2147483647。而unsigned范围是[0,2^32),即
0~4294967295。也就是说,常规的32位整数只能够处理40亿以下的数。
  那遇到比40亿要大的数怎么办呢?这时就要用到C++的64位扩展 ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号