您的位置:首页 > 编程语言 > C语言/C++

从一段小小的C语言程序说起(1)

2010-11-05 14:48 295 查看
既然是从一个C语言程序,那么就先把这程序贴出来,确实是一个很简单一眼就能看出肯定有问题的程序。




#include <stdio.h>
int main(void)
{
	char i[4];
	scanf("%d %d", i, i+1);
	printf("i = %d/n", *i + *(i + 1));
	return 0;
}





第一个问题:


在运行中,如果输入300和200后,结果为什么会输出-12?


这个问题不难回答,其实在编译的时候gcc编译器就给出了两句警告也说明了这个问题。








也就是在输入的时候发生了截取,以下程序可以很好的说明情况。




#include<stdio.h>
int main()
{
    char i [4];
    scanf("%d %d",i,i+1);
    printf("%d, %d/n", *i, *(i+1));
    printf("%2x, %2x/n", *i, *(i+1));
    printf("i = %d",*i + *(i+1));
    return 0;
}





输入:300 200 //12c c8

截取为:2c c8 //44 -56

结果为:-12


注:这里用截取只是好理解,实际上是污染了后面的内存空间


可能有人看不懂,那以-56为例说明如下:

10111000 //-56的原码

11000111 //反码

11001000 //补码,即c8



--------------------------------------------------------------------------------------------------------



第二个问题:




这里还有一个问题,只是因为数值输入的比较小,一个300,一个200,这个问题没有体现出来,就是这样输入对后面内存空间的“污染”问题(请允许我这里使用污染这个词,没想到更合适的)。




//把这句输入拆成两句单步调试
//scanf("%d %d",i, i+1);
scanf("%d",i);
scanf("%d",i+1);



会发现输入第一个300时,这时的数组i的内存空间是这样的i[0]:44 i[1]:1 i[2]:0 i[3]:0


解释起来很简单,300的二进制0000 0001 0010 1100(按4字节),依次对号入座就可以了


那么输入200时从i[1]开始,200的二进制0000 0000 1100 1000,再次对号入座


现在的数组i的内存空间就成了我们看到的


i[0]:44 i[1]:-56 i[2]:0 i[3]:0




所以当输入的数值过大时,问题就来了,i[2]和i[3],最可怕的是可能不存在的所谓i[4]也被无奈赋值了




:如有差错,欢迎拍砖




------------------------------------------------------------------------------------------------------





转载我博客文章郑重声明:技术性网站著名原创作者即可转载,商业性网站必须经过我的同意才能转载,否则追究责任——


pang123hui的博客:




CSDN
http://blog.csdn.net/pang123hui/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: