3.数组

为什么数组要从0开始变好,而不是1开始呢?
 
数组是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据结构
  随机访问
  插入、删除数据很低效
 
 
 
 
 
面试题
数组和链表的区别?
链表适合插入、删除,时间复杂度为O(1);数组支持随机访问,根据小标随机访问的时间复杂度为O(1)
 
数组的内存寻址公式
 
a[i]_address = base_address + i * data_type_size
 
 
 
 
 
警惕数组的访问越界
1 int main(int argc, char* argv[]){
2 int i = 0;
3 int arr[3] = {0};
4 for(; i<=3; i++){
5 arr[i] = 0;
6 printf("hello world\n");
7 }
8 return 0;
9 }

 

 
 
  这行代码会无限打印”hello world”,而不是只打印三行。
 
  因为i = 3时,a[3]会数组访问过界。在c语言中,只要不是访问受限的内存,所有内存空间都是可以自由访问的。
  根据前面寻址公式,a[3]会被定位到不属于数组的内存地址上,正好是变量i的存储地址上。(如果用来编译这段程序的编译器按照内存地址递减的方式给变量分配内存,栈是向下增长的,首先压栈的i,a[2],a[1],a[0])所以,a[3] = 0 相当于i = 0 的语句。
 
 
  对比之下Java 本身就会做越界检查
 
容器能否完全替代数组?
  相比于数字,java中的ArrayList封装了数组的很多操作,并支持动态扩容。一旦超 过存储容量,扩容 时比较耗内存,因为涉及到内存申请和数据搬移。
 
数组适合的场景:
  1) Java ArrayList 的使用涉及装箱拆箱,有一定的性能损耗,如果特别关注性能,可 以考虑数组
  2) 若数据大小事先已知,并且涉及的数据操作非常简单,可以使用数组
  3) 表示多维数组时,数组往往更加直观。
  4) 业务开发容器即可,底层开发,如网络框架,性能优化,选择数组。
 
开头解答:
  数组的‘下标’确切定义应是‘offset’偏移量,结合寻址公式知道arr[0]的地址便是首地址,a[k]k便表示偏移量。若是以1开始为数组下标,则
 
  a[k]_address = base_address + (k-1)*type_size
 
  cpu便多了一次计算。
  其实这个问题还有一些历史原因导致。
posted @ 2019-03-04 20:11  夏天换上冬装  阅读(167)  评论(0编辑  收藏  举报