一道好题

  今天在看linux C 语言编程时遇到一道很不错的题目,觉得有必要记录下来并在讲解上作适当延申。

     题如下:问最终输出多少?ps:在原题的基础上我增加了        printf("a_sizeof = %d\n",sizeof(a));

#include<stdio.h>

void main()
{
	int i = 0;
	char a[1000];
	
	for(i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	
	printf("a_strlen = %d\n",strlen(a));
	printf("a_sizeof = %d\n",sizeof(a));
	
	system("pause");
}

最终打印输出的是:a_strlen = 255

         a_sizeof = 1000

关于这个题,主要涉及到一下几个方面:

1.数据类型与类型转换

  a 是一个char型数组,长度为1000,每个元素的取值范围为 -128~127(-2^7 ~ 2^7 - 1);

  i 是一个int型变量,取值范围为-2^31 ~ 2^31 - 1;

  a[i] = -1 - i;运算过程中,首先 (-1 - i)得到一个int 型数据,最后转换成char型,赋给a[i];

2.数据计算机中的存储及加减运算

  在计算机内存中,任何数据都是以二进制的补码形式存储的,这样做的一个好处就是减法可以当作加法来做,补码相加,舍去进位;

  补码计算:整数的补码与其原码 反码相同,如 十进制 +4,原码 0000 0100,反码 0000 0100,补码 0000 0100;

       负数的补码,反码加1,得到补码,如十进制-1,原码 1000 0001,除符号位外其余位按位取反得到反码 1111 1110,反码加1得到补码 1111 1111,即 0xFF;

       特例:在8位有符号数据类型中,-128 的原码 反码和补码都为1000 0000

  对于有符号数,二进制最高位用作正负数标识,整数最高位为0,负数最高为1,

3.strlen() 和 sizeof()

  strlen() 用于计数字符串中字符的个数(即字符串长度),直到遇到'\0'停止,并返回计数值(不包含'\0');

  sizeof() 用于计算变量占用内存空间的大小。

 

经过上面的简单讲解,现在来看看上面问题结果的由来吧!

  先来看看,经过for循环后,数组a中各元素的值:

  i的值  a[i]的值   a[i]在内存中的存储形式

   0   -1 - 0       1111 1111   即 0xFF  -1

   1   -1 - 1    1111 1110 即 0xFE  -2

   2   -1 - 2    1111 1110 即 0xFD  -3

  ……   ……       ……

  127  -1 - 127   1000 0000  即 0x80    -128

  128  -1 - 128   0111 1111  即 0x7F    127 溢出(下同)

  129     -1 - 129         0111 1110  即 0x1E    126

  ……  ……      ……

  254  -1 - 254   0000 0001 即 0x01  1

  255  -1 - 255   0000 0000 即 0x00    0

  256  -1 - 256   1111 1111即 0xFF  -1

  ……  ……      ……

 

注意,a[255] = 0,即为ascii中的空格字符,strlen(a)计数到a[255]后停止,并返回计数结果255.

posted @ 2015-04-19 15:10  Waming  阅读(377)  评论(0编辑  收藏  举报