C 数组
C 数组
数组及其特性:整型数组所具有的特征其他类型数组都具有,故以整型数组示例
1)定义一个数组:类型名数组名[数组元素个数]
- 类型名: char,int,float,double,char *,int *,float *,double *
- 数组名:只要符合c语言标识符规范即可 .
- 数组元素个数:可以使常量,⽐如4,5等只要能够有确定值的表达式就可以
2)定义一个有10个整型元素的数组 int arr[10];等价于int arr[2*5];
定义一个有10个字符元素的数组:
char str[10];
char是数组类型或者叫作数组元素类型,str是数组的名字,该数组有10个元素定义其他类型的数组依上例可以推出来,如float,double,char *,int *, float *,double *以此类推
3)数组是由多个相同类型的数据构成的一个集合,这就涉及到到究竟如何引用每一个数组元素.数组元素引⽤
⽅式如下:
数组名字[数组下标]
注意: 所有数组的元素都是从0开始的,所以程序员数羊总是感觉少一只.
例如定义一个数组
int array[5];
通过上面的数组定义可以知道该数组有5个整型元素,引用方式如下:
array[0] //数组第1个元素
array[1] //数组第2个元素
array[2] //数组第3个元素
array[3] //数组第4个元素
array[4] //数组第5个元素
该数组中每一个元素都可以当作一个整型变量来用
数组是多个同种类型数据的一个集合 ,访问数组每一个元素时可以使用循环 ,恰好让循环计数器变量来做数组的下标,如下面遍历打印数组 :
int arr[5],i;
for(i=0; i<5; i++) {
printf(“%d\n”,arr[i]);//i的值随着循环次数在递变
}
数组的下标都是有范围的 :
- int a[100]; //下标的范围是0~99
- int b[55]; //下标的范围是0~54
c语言标准中定义了按照规范操作能实现什么功能 ,但没说不按照规范做会有什么后果 .所以一般不讨论如果不按照规范做会有什么后果 ,因为没有什么实际意义 .但是有些时候不小心没有按照规范操作而导致整个程序进⾏不下去,还是需要去排除错误的 ,从这一点出发某些时候错误反馈也是必要的 ,即根据错误反馈来定位出错的位置.
下面讨论一个数组常见错误 :
数组引用元素时下标超过了合法范围 ,如上面的array数组合法下标为0,1,2,3,4但是引用数组元素时用了这些合法范围以外的下标,如-1,-2,5,6等等,一般管这种错误叫作内存越界 ,即在内存存储上超出了你有权限操作的内存后果是无法预料的,正因为这个错误导致的结果无法预料 ,所以编译器检查不出来或者是编译器压根就不管这种情况.一般编译程序时还发现不了 ,一执行就出(段错误):
Segment default
Bus error
遇到这些错误首先需要考虑的是内存操作出错了 ,即非法访问内存.非法的访问或操作内存又被叫做内存越界 .存在内存越界的程序的结果是不可预测的 ,即使执行的结果是正确的 ,就程序本本身而言程序是有 Bug的.保证程序没有内存越界是程序员的责任 .
4)整型数组初始化
(1)完全初始化
在数组定义的同时为数组的所有元素赋值
int test[5]={11,22,33,44,55};
这样
test[0]对应内存存储空间的存放的值为11
test[1]对应内存存储空间的存放的值为22
test[2]对应内存存储空间的存放的值为33
test[3]对应内存存储空间的存放的值为44
test[4]对应内存存储空间的存放的值为55
特例:
int data[]={11,22,33,44,55};
这种初始化的方式也有,只不过操作系统会根据初始化数据的个数为数组自动分配恰好能够存储这些数据的内存空间大小.所以data数组有5个整型元素
(2)部分初始化
被初始化的元素是有确定的值,未被初始化的元素被系统设置为数值0
例如: int arr[10]={1,2,3,4};
这时该数组的10 个元素依次为:
1 2 3 4 0 0 0 0 0 0
特例: 极端的部分初始化,如int arr[10]={};
这种方法很常见,数组所有元素被系统设置为0指定初始化,如int arr[10]={[1]=4,[2]=5};相当于把下标为1的元素初始化为4,把下标为2的元素初始化为5,未被初始化的元素被系统自动设为0
(3)其他类型的初始化也都遵循上述原则
注意:数组只有在初始化的时候可以整体赋值,单就赋值而言数组是不能被整体赋值的
(4)数组名字:数组的名字是一个常量,即首元素的地址.
(5)数组存储特性:
数组元素的地址在内存存储是连续的 ,无论是一维数组,二维数组还是三维数组