今天遇到一个有趣的关于在C中定义char[]变量时的一个问题,程序大致如下:
int main()
{
int t;
char ch_t[32];
t=1000;
itoc(100, ch_t); //把100用二进制字符串显示出来
printf("100 is %s./n", ch_t);
printf("t is %d./n", t);
}
void itoc(int number, char * bstr)
{
int size=8*sizeof(int);
int i;
for(i=size-1;i>=0;i--,number>>=1)
{
bstr[i]=(1 & number)+'0';
}
bstr[size]='/0';
}
看起来变量t并没有受到什么影响,打印结果应该是"t is 1000.", 但事实上打印结果为"t is 768"。是什么改变了变量t? 函数itoc(int, int)并没有接受变量t的指针。仔细观察发现,原来问题出在ch_t[]变量上。程序的原义是让ch_t存储二进制字符串,但因为字符串最后一个字符应该为'/0',所以在函数itoc中的最后一行进行了这种操作,但问题就出在ch_t的长度定义错误,应该是32+1才对。
修改main函数,使其打印t, ch_t两个变量的地址:
int main()
{
int t;
char ch_t[32];
t=1000;
printf("t's addr: %p./n",&t);
printf("ch_t's addr: %p./n",&ch_t);
itoc(100, ch_t); //把100用二进制字符串显示出来
printf("100 is %s./n", ch_t);
printf("t is %d./n", t);
}
结果为
t's addr: 0012FF7C.
ch_t's addr: 0012FF5C.
两个变量地址长度相差0x20(32字节长度),注意ch_t的地地址在t的前面。
由于ch_t数组的长度少定义了一位,字符串结尾符'/0'被存到了t变量的低8位中,导致1000(1111101000)被修改为768(1100000000)。