数组是用来存储一系列数据,但它往往被认为是一系列
相同类型的变量
所有的数组都是由连续的内存
位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
数组中的特定元素可以通过索引访问
,第一个索引值为 0
。
数组可以从定义,赋值和使用
三个方面来讲述
在 C 中要声明一个数组,需要指定元素的类型
和元素的数量
,如下所示:
格式:type arrayName [ arraySize ];
arraySize 必须是一个大于零的整数常量
,type 可以是任意有效的 C 数据类型。
错误?: int count = 10;
????????? int arr2[count];//数组可以正常创建?
注意:此时是不可以创建的,因为count是变量,而[]内只能是常量
如要声明一个类型为 double
的包含 10 个元素
的数组 balance
,声明语句如下:
double balance[10];
定义完成后在内存中的样子:
在 C 中,可以逐个初始化数组
,也可以使用一个初始化语句
,如下所示:
大括号 { } 之间值的数目不能大于
在数组声明时在方括号 [ ] 中指定的元素数目。
数组的大小可以省略,数组的大小为初始化时元素的个数。因此,如果:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
等价于
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
?
对于字符串数组
char arr1[] = "abc";//字符数组可以不写大括号,用""来表示
char arr2[3] = { 'a','b','c' };
在arr1中,在内存中有4个数组元素,除了字符’a’,‘b’,'c’之外,还有一个字符串的结束标志'\0'
求数组的长度
int arr[10];
int len = sizeof(arr)/sizeof(arr[0]);
数组的遍历
#include<stdio.h>
int main()
{
int arr[10] = { 0 };//数组的不完全初始化
int len = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i < len; i++){
arr[i] = i; //数组的赋值
}
//数组的遍历
for (int j = 0; j < len; j++){
printf("%d ", arr[j]);
}
return 0;
}
以int数组为例:
有了一维数组的基础,二维数组就比较容易理解了
int arr[3][4];
char arr[3][5];
double arr[2][4];
int x[3][4];
二维数组如果有初始化,行可以省略,列不能省略
为每行指定值
来进行初始化。下面是一个带有 3 行 4 列的数组。int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
数组的遍历
#include <stdio.h>
int main ()
{
/* 一个带有 5 行 2 列的数组 */
int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
int i, j;
/* 输出数组中每个元素的值 */
for ( i = 0; i < 5; i++ ) //外层遍历行
{
for ( j = 0; j < 2; j++ )
{
printf("a[%d][%d] = %d\n", i,j, a[i][j] );
}
}
return 0;
}
二维数组在内存中也是连续存储
的
在 C 语言中,
数组名表示数组的地址
,即数组首元素的地址
。当我们在声明和定义一个数组时,该数组名就代表着该数组的地址。
int myArray[5] = {10, 20, 30, 40, 50};
在这里,myArray 是数组名,它表示整数类型的数组,包含 5 个元素。myArray 也代表着数组的地址,即第一个元素的地址。
数组名本身是一个常量指针
,意味着它的值是不能被改变
的,一旦确定,就不能再指向其他地方。
我们可以使用&运算符来获取数组的地址
,如下所示
int myArray[5] = {10, 20, 30, 40, 50};
int *ptr = &myArray[0];
int *ptr = myArray;
在上面的例子中,ptr 指针变量被初始化为 myArray 的地址,即数组的第一个元素的地址。
需要注意的是,虽然数组名表示数组的地址,但在大多数情况下,数组名会自动转换为指向数组首元素的指针
。这意味着我们可以直接将数组名用于指针运算
例如在函数传递参数或遍历数组时:
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]); // 数组名arr被当作指针使用
}
}
int main() {
int myArray[5] = {10, 20, 30, 40, 50};
printArray(myArray, 5); // 将数组名传递给函数
return 0;
}
数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的, 所以程序员写代码时,最好自己做越界的检查。
#include <stdio.h>
int main()
{
int i, a[10];
for(i = 1; i <= 10; ++i)
a[i] = 0;
return 0;
}
数组中的下标从0开始,那么在上面代码中只能访问:a[1]、a[2]、a[3]、a[4]、a[5]、a[6]、a[7]、a[8]、a[9];当i自加到10时,a[10]属于数组下标越界
。