一级棒(Eachfun)
一级棒 - 编程园地 - 编程感想 - 也说整数和无符号整数
RSS订阅
也说整数和无符号整数
发表时间:2005-05-30 00:00:00 关键词:编程,C++,VC,MFC,int,整数,无符号整数

  我们学C/C++时,都学到“整数”和“无符号整数”,都知道它们在表达范围上有区别。近来有人在论坛上讨论这两者在互相矛盾时究竟怎么处理,比如代码行“unsigned int a = -3;”,a的值究竟是多少?是有符号的还是无符号的?
  要懂清这个知识,我们首先要明白计算机内存、CPU对数据进行存储、处理的实质。
  实际上,在C中“unsigned int”和“int”在存储上没有任何区别,在处理上也没有任何区别,唯一有区别的是程序员的感觉。

  下面我们来做几个实验:

  实验一、
  printf("%d\t%d\t%u\t%u\n",3,-3,3,-3);
  printf("%d\t%d\t%u\t%u\n",3,4294967293,3,4294967293);
  通过运行可以发现两个问题,1、同样是常数“-3”,在不同的控制符(“%d”和“%u”)的控制下可以得出不同的显示结果;2、不同的数“-3”和“4294967293”在同样的格式控制符下输出结果是一样的。
  其实printf()函数只做两个事:1、接受指定的参数;2、按指定的格式输出。这个实验之所以得到这样的结果,本质原因是:“-3”和“4294967293”这两个数对于计算机来说本身就没区别。

  实验二、再看下面的程序:
  int i = 3;
  unsigned int j = 3;
  printf("%d\t%d\t%u\t%u\n",i,j,i,j);
  i -= 6;//-3
  j -= 6;//注意:超出范围,按理说这行将报错
  printf("%d\t%d\t%u\t%u\n",i,j,i,j);
  i = 4294967293;//注意,超出范围,按理这行将报错
  j = 4294967293;
  printf("%d\t%d\t%u\t%u\n",i,j,i,j);
  以上这个例子有两行错误的代码,但是从编译到连接再到运行都没有报错,充分说明这些数据完全可以在CPU和内存中处理、存放。唯一能识别它们的,就是“%d”和“%u”这样的控制符。

  实验三、再来看更直接的错误:
  const int i = -3;
  const int j = 4294967293;//超出范围,按理将报错
  const unsigned int ui = -3;//超出范围,按理将报错
  const unsigned int uj = 4294967293;
  printf("%d\t%d\t%d\t%d\n",i,j,ui,uj);
  printf("%u\t%u\t%u\t%u\n",i,j,ui,uj);
  如果说实验二说明CPU处理数据不区分有整数与无符号整数的话,那么实验三就是直接挑战了编译系统。那两行明显错误的代码依然一路绿灯地通过了编译、连接和运行。

  以上实验的结果并不奇怪,因为在内存里,“-3”和“4294967293”压根儿就是一回事。printf()函数之所有不会混淆,并不是printf()函数有鉴别功能,而是程序员规定了格式:“%d”或“%u”。
  除了printf()函数以外,其它任何函数、语句也是这样的:它们只按照内存地址取数,根本就不管那个位置存的是什么数。
  不要怪C,这不是它的缺点,而是优点。只有这样,C才能保证它的灵活性。大家都知道,我们在C里面可以利用指针来传递参数,还可以再通过指针和偏移量来访问相邻内存单元。那么,你凭什么让C帮你记住整个内存里面存放的数据类型?
  再比如,你要做一个游戏修改器,你在内存里进行“大海捞针”,并且要把玩家的生命值、金钱值改成天文数字时,你又怎么会知道那个游戏采用什么类型来存放数据?换句话说,你在不知道数据类型的情况下要把它们改成天文数字,如果C没有这样的灵活性,你将无法进行。

  下面的代码更能让你理解C的这一特点:
union TheNumber
{
  int i;
  unsigned int ui;
  float f;
  char c[4];
};

void ViewNumber(TheNumber *t)
{
  printf("整数:%d,  无符号整数:%u,  浮点:%6.4f,  ",t->i,t->ui,t->f);
  t->c[3] = 0;//防止内存溢出
  printf("字符串:%s\n",t->c);
}

void main(void)
{
  TheNumber t;
  t.i = -2345;
  ViewNumber(&t);
  strcpy(t.c,"aaa");
  ViewNumber(&t);
  t.f = 3.1415926f;
  ViewNumber(&t);
}

  话再说回来,C++不同于C,它引入了cin和cout两个类,使用cin和cout进行数据输入输出时,程序员不须要规定格式,个人认为,cin和cout虽然从某种意义上减轻了程序员的负担,但却降低了C语言的灵活性。

本站特约顾问律师常州东晟律师事务所朱立律师(电话13915029670,QQ646146109)提醒您:
本站文章皆为作者原创,其它媒体(包括但不限于报刊、杂志、网站、电视、电台)未经作者书面许可严禁转载(或部分摘录)!
发表评论
称呼:
QQ:
邮箱:
链接:
内容:
搜索: 百度搜索 Google搜索
Copyright©2000 - 2008 Eachfun.Com, All Rights Reserved 一级棒网络
苏ICP备05080156号
一级棒建站系统 http://www.eachfun.com 一级棒版权所有,未经许可不得商用!