在c语言里数组长度是固定的么(不讨论柔性数组)比如int a[5]={0,1,2,3,4}

如上定义以后,为什么 a[5]=5;这样赋值以后也是可以的,但是用sizeof(a)得到的还是20呢,可以给a[5]赋值这是不是代表它长度可变,,,虽然数组在汇编里就是一个地址然后往后不断偏移偏移,,可是老师讲数组都一再强调数组下标不能越界……往解答一二

8个回答

C语言里面,所谓的长度固定,是因为分配给它的内存只有5个int的空间,
1.你的电脑和编译器上,一个int应该是4个字节,5个不就是20个字节的内存嘛。但是5个元素的数组下标只能到4吧,
a[5]岂不是别人家的内存空间么?
2.数组名a就是一个不可变的指针(a是指针,但是a不能被赋值,比如a++), a永远是数组的首地址(一生一世,永世不移)
但是通过指针方式 *(a+3)这样子是阔以的,因为a+3并没修改a的值啊
3.对于指针,有一种运算符叫[] , []中的数字叫做偏移量,根据类型不同,每次偏移的距离不一样,比如int类型,你的int是32位(4字节),
那么a[0]就是从首地址向后偏移0个字节的内容,也就是首地址的内容
4. a[5]=26; 是指给从a(首地址开始),向后偏移5个int的字节数,如果你的数组定义的时候是5个元素,下标最大是4,a[4]是最后一个
C语言访问a[5]不会报错,但是你随便动用别人家的内存地址,就不怕系统不稳定,系统崩溃么?
这一块内存空间是空闲的算运气好,如果不空闲呢? 最好不要随便动别人家的内存嘛,你申请的内存你可以改,别人家的不要动。

zuoside__lord
陆狸狸 所以这个行为是勉强可以的,但是可能会引发后果可能会修改别的值咯,谢啦 还有真的好像会冒出奇奇怪怪数字呢,
大约 2 年之前 回复

C语言环境下如下理解:
1. int 不同编译器可能分配不同的字节,一般是分配4个字节
2. int a[5] 申请int型的数据类型,物理地址分配5个int型大小的空间5x4=20 字节. a数组通过指针的方式依次访问对应物理地址中的数值。定义时[5]的意思是5个int型数据,所以对应的可访问序列为:0,1,2,3,4 。超出这个可访问序列(下标),则称为越界
3. a[2] = 5 ,正常在可访问序列内是可被赋值的。意思是下标2处对应的物理地址赋值为5.
4. a[5] = 5 ,可以正常赋值的原因是,编译器可以找到a[5] 对应的物理地址,一般局部变量是在堆上实现地址申请的,因此一般数组是连续的物理地址。所以a[0]..a[4]的物理地址都能访问到,而a[5]也就是a[4]后边的一个int型字长的物理地址,对其做赋值处理自然是没问题的。但该操作不被保护。
5. 越界赋值报错的原因。一般越界地址是不被保护的,因此越界的物理地址极有可能分配给其他的变量来使用,此时就会产生冲突报错甚至程序崩溃等。
6. C语言是可以直接操作物理地址的,所以如上越界赋值是正确的。但当前的编译器会报错,会告诉你这么操作是错误的,会引起内存异常等等问题。

最后:越界是一个伴随每一个c系开发人员的重要问题,所以从已开始养成越界和释放的习惯是很好的。

yanghuatian
yanghuatian 回复zuoside__lord: 笔误,局部变量是在栈上,栈上申请的的地址连续。全局变量在堆上。
大约 2 年之前 回复
zuoside__lord
陆狸狸 等等,局部变量不是应该是栈上的么,,,,,由于你写得非常条理分明的样子 所以我一个字一个字看 : )
大约 2 年之前 回复
zuoside__lord
陆狸狸 谢谢 ,你讲得很详细了,我明白了,
大约 2 年之前 回复

数组长度是固定的。之所以可以a[5]=5是因为,C语言不对下标的合法性(是否越界)做出检查。这么做会造成什么后果(没事,还是会侵犯另一个变量,或者访问违例),是不可预料的。

数组的长度是在定义的时候确定的,不同编译器对于数组越界的处理也是不一样的,一般而言数组的长度是不可以改变的。有一些编译器对于数组越界,
是不处理,继续放后面。但是会对后面的数据进行改变。还有一些编译器就是程序遇到未知错误而终止。但不管是哪一种,都需要注意数组的下标是不是
越界。对于汇编而言数组的定义也是在定义的时候确定,可能对于越界不做处理,但是自己要注意,越界了,会替换其他数据,也会让自己犯迷糊,总不会
想在下标大于数组空间的地方找有用的数据吧。

a[5]=5,这个语句是给数组a的下标为5的元素赋值为5,与数组长度没有关系;
sizeof(a)这个语句,是表示a数据占用字节的长度,如果你的数组类型是int数组,数据中有5个元素,则长度正好20;
如果你的数组类型是char数组,sizeof(a)才是5。

想求数组长度,最好定义一个宏,#define LEN(a) sizeof(a)/sizeof(a[0])

LEN函数就可以求任意数组的长度了。

这个就是c语言的灵活性,a[5]有的时候是可以读出数值的,但是如何a[5]指向的地址是非法地址,那么就会发生错误。正常使用时,千万不要这么使用,建议看一下c语言编程规范。里面会讲不规范编程,可能造成的后果。

ayuan_23 回答较全面了,补充一下,把数组名a理解成指针是可以的,需要注意的是:数组名a编译后是一个常量,对应着机器指令中的立即数,
指针往往是变量,还需要寻址一次的,虽然指针和数组名都可以用*(a+3)和a[3]两种方式访问,但内存寻址方式上还是不同的。

数据大小的确是固定的,原因很简单,因为系统要为数组分配储存空间(只会为数组分配一次),如果不是固定的,就会出现空间容量的悬浮,造成不能存储数据的后果

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐