分页: 1 / 1

^_^新手请教一个关于数组的问题

发表于 : 2013-05-07 23:00
StayHungry
【问题描述】
如果连续声明两个数组a[n]和b[n],a[n]的地址和b[0]的地址一样了。
这样如果做一些输出,比如puts(a),就会把a和b都输出了。

【请问】
这是怎么回事?如何避免这样的问题?

【代码】
gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

代码: 全选

#include<stdio.h>

main()
{
char a[5],b[5];

int i;
for (i = 0;i < 5;i++){
a[i]='a';
b[i]='b';
}

puts(a);

}

>输出:aaaaabbbbb

【By the way】
我是在我手机上用tcc编写c时发现这个问题的,tcc要颠倒声明顺序,先声明b数组,再声明a数组。
这样才能让b紧跟在a后,形成&a[5]与&b[0]相同。


望各位前辈指教,多谢了^_^

Re: ^_^新手请教一个关于数组的问题

发表于 : 2013-05-09 12:16
sighforever
简直吐槽不能了

你这个问题是最基本的问题,你应该好好去看看书。看书,懂不。我要是你的老师一定罚你超书一百遍啊一百遍

建议好好读读 c++ primer Arrays and Pointers 这一章,一共就35页,俩小时也读完了。

好吧,简单说问题主要处在c++ 里面的字符数组本身不能当作字符串使用的,字符串必须使用'\0'结尾

puts 的参数是char * ,是要你输入一个字符数组型的字符串,不是仅仅是个字符数组就可以了。

使用不带'\0'的字符数组做字符串是危险的做法,会带来莫名其妙的bug.

你的程序可以这么改

代码: 全选

...

for (i = 0;i < 4;i++)
{
    a[i]='a';
    b[i]='b';
}

a[4] = ‘\0’;
b[4] = '\0';
...
关于你说的那个a[n] 等于b的问题,本质上在于数组的名称实际存储的是数组的地址,a[5] 已经超出a这个数据的范围了,a后面你恰好定义的是b,所以取得了b这个数组。

当然理论上是这样,但是实际上的效果受很多因素的影响,尤其是编译器的优化和实现方式,比我我这里编译器自动做对齐,就不会出现你的这个现象。你可以用printf打印&a[5]和&b看看地址就好了。

但总之要记住的是使用超出地址范围的数组元素是灰常危险的用法,是各种莫名其妙的问题的根源之一。

Re: ^_^新手请教一个关于数组的问题

发表于 : 2013-05-09 15:47
bzimage
楼上多点宽容么,谁都从新手过来的。
基本上楼主需要看看c语言下字符串的定义和使用。

Re: ^_^新手请教一个关于数组的问题

发表于 : 2013-05-11 8:16
StayHungry
多谢指教!