数组

一、数组概述

数组:

  • 由一组相同数据类型的数据组成的集合。
  • 数组其实就是用户向内核申请的一块空间,只不过内核提供的这块空间的内存地址是连续的
  • 目的就是方便用户存储数据和访问数据。
    二、数组定义
    数组的定义格式:
    数据类型 数组名[元素个数];

元素个数可以是常量、常量表达式、运算符+操作对象

数组所占内存大小=数据类型*元素个数

三、数组初始化

数据类型 数组名[元素个数]={元素1,元素2,元素3,.......元素n};

数组初始化的方式

1、循环遍历初始化

2、数组下标初始化

3、定义时初始化

  • 元素个数可以省略,处理器会自动计算数组所需要的内存大小,但是一般需要在定义数组的同时进行初始化。
  • 数组在定义的时候进行初始化,声明之后不可以对数组进行初始化,要初始化数组中元素的值,只能通过数组下标的方式进行初始化
  • 如果对数组初始化时,未被赋初值的元素默认为0
  • 可以在初始化时,用下标对数组元素进行初始化赋值

四、数组元素的访问

  • 数组的下标是从0开始的,到元素个数-1结束
  • 数组名代表数组第一个元素的地址

数组元素与指针的关系:

E1[E2]==(E1+E2)--> (E2+E1)-->E2[E1]

如果E1是数组名,E2是整型常量,则E1[E2]可以等价于 E2[E1],这两种方式都可以访问数组中的元素。

数组名与sizeof()单独相遇时,不表示数组首元素地址,表示数组本身

数组名与&相遇时,不表示数组首元素地址,表示数组本身

地址不可以自增自减和赋值,因为地址是常量,要访问相应地址下的元素的值,可以使用指针

五、数组大小

//数组中元素的个数

数组中元素的个数==数组容量 / 数组中元素

//数组大小

sizeof(数组名);

sizeof(数组元素数据类型)*元素个数

六、数组清空

1、bzero()

//头文件 #include <string.h>

//函数原型 void bzero(void *s,size_t n)

//功能描述 清除参数s指向的地址的区域前n个字节

//返回值 无返回值

清空整个数组:

int buf[10]={0,1,2,3,4,5,6,7,8,9};

bzero(buf,sizeof(buf));

2、memset()

//头文件 #include <string.h>

//函数原型 void *memset(void *s,int c,size_t n);

//功能描述 可以向参数s指向的地址对应的内存的前n个字节z中填充指定字节,待填充字节由用户指定

//返回值 函数返回参数s指向的内存地址

清空整个数组:

int buf[10]={0,1,2,3,4,5,6,7,8,9};

memset(buf,0,sizeof(buf));

七、数组越界(溢出)----产生内存错误(段错误)

段错误在编译时不会报错,也不会发出警告,只有在程序运行阶段才会导致内存错误

八、段错误的原因

1、访问了没有权限访问的内存空间---野指针(NULL)

2、数据发生溢出,如数组越界

3、栈溢出--递归过深、局部变量占用过多空间

4、使用未初始化的指针或变量

5、在只读内存区域进行写操作

6、使用了已经释放的内存

7、多线程环境下访问共享内存时未正确同步

8、程序运行时发生内存损坏或者内存泄漏

9、硬件故障或操作系统错误导致内存访问异常

九、字符型数组

初始化字符数组:

char buf[5] = "abcde";

//不可靠 在末尾加上'\0'

//"abcde"是字符串常量,已经出现数组越界的情况,发生段错误

char buf[5] ={'a','b','c','d','e','\0'};

//对元素单独赋值是可靠的

//如果数组的容量刚好和字符串常量中的有效字符的数量一致时,就会导致数组越界,因为字符串常量的末尾有一个转义字符'\0',也是需要占用1个字节的存储单元。

十、数组型数组(多维数组)

1、数组的定义规则:

数组名[元素数量] + 元素类型

2、二维数组定义格式 :

元素类型 数组名称[元素数量][元素数量]

3、数组元素的访问

通过下标的方式或者地址的方式进行访问

(1)下标方式:E1[E2]

int buf[3][4];

(2)地址方式:E1[E2]--->*(E1+E2)

buf[1][1] ==> * ( ( *(buf + 1) ) + 1 )

十一、柔性数组(变长数组)

用户定义一个数组,但是在定义数组的时候没有想清楚数组的元素数量,所以使用一个变量来代替数组元素个数

但是注意:当数组的内存一旦确定,则不会因为变量发生变化导致数组长度变化!

十二、匿名数组

匿名数组一般都是在函数参数中或者在多维数组中使用,很少单独使用。

如:

二维数组 int buf[3][4]; ---> buf[3] 数组的每个元素的类型是 int [4]就是匿名数组。

十三、零长数组

数组的长度可以是0,但是由于数组长度是0,所以操作系统是不会提供内存单元给数组的!但是用户可以访问

数组的长度可以是0,但是由于数组长度是0,所以操作系统是不会提供内存单元给数组的!