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

软件和网站开发以及相关技术探讨
回复
StayHungry
帖子: 2
注册时间: 2013-03-23 23:44
系统: lubuntu

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

#1

帖子 StayHungry » 2013-05-07 23:00

【问题描述】
如果连续声明两个数组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]相同。


望各位前辈指教,多谢了^_^
头像
sighforever
帖子: 234
注册时间: 2007-08-07 18:14

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

#2

帖子 sighforever » 2013-05-09 12:16

简直吐槽不能了

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

建议好好读读 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看看地址就好了。

但总之要记住的是使用超出地址范围的数组元素是灰常危险的用法,是各种莫名其妙的问题的根源之一。
什么是历史?历史是魔术师箱子里那只变来变去的小白鸽;
什么是真相,真相只是观众最愿意看到的硬币的那一面。
头像
bzimage
帖子: 716
注册时间: 2006-03-14 10:25

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

#3

帖子 bzimage » 2013-05-09 15:47

楼上多点宽容么,谁都从新手过来的。
基本上楼主需要看看c语言下字符串的定义和使用。
StayHungry
帖子: 2
注册时间: 2013-03-23 23:44
系统: lubuntu

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

#4

帖子 StayHungry » 2013-05-11 8:16

多谢指教!
回复