目录
数组:一组相同元素的集合
一维数组
声明:
数据类型 数组名称[常量表达式];
常量表达式:必须是一个大于零的整数常量。
举个例子
int main()
{
char arr1[10]; //类型为 char 的包含 10 个元素的数组 arr1
int arr2[1 + 9]; //类型为 int 的包含 10 个元素的数组 arr2
long arr3[1 * 10]; //类型为 long 的包含 10 个元素的数组 arr3
float arr4[100 / 10]; //类型为 float 的包含 10 个元素的数组 arr4
double arr5[110 % 100]; //类型为 double 的包含 10 个元素的数组 arr5
return 0;
}
注:数组创建,在C99标准之前, [ ] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数 组的概念。
初始化:
数组的初始化是指,在声明数组的同时给数组的内容一些合理初始值(初始化)。
完全初始化:
完全初始化数组时,数组中的常量表达式可以省略。会按照所给予的元素个数,自动确定数组大小
例
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]); //计算元素个数
printf("%d", sz);
return 0;
}
不完全初始化
在初始化数组的时候,部分元素初始化,其余元素将自动补为0
int main()
{
int arr[10] = { 1,2,3,4,5 }; //申请10个整型的空间,只对前五个元素初始化。
int i = 0;
for(i=0;i<10;i++)
printf("%d", arr[i]);
return 0;
}
全局数组:
全局数组的初始化与全局变量有几分相似,当全局数组被声明但未初始化时,会被自动初始话为全零
int arr[10]; //创建一个全局数组
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
printf("%d", arr[i]); //打印数组的全部元素
return 0;
}
字符数组
char类型的数组中除了可以存放字符意外,也可以存放字符串
字符串存放与字符大致相似,但还是有一些不同
int main()
{
char arr[] = { 'h','e','l','l' ,'o',' ','w','o','r','l','d'};
char ch[] = "hello world";
int sz_arr = sizeof(arr)/sizeof(arr[0]); //计算arr数组的元素个数
int sz_ch = sizeof(ch) / sizeof(arr[0]); //计算ch 数组的元素个数
printf("arr数组的大小为=> %d\n", sz_arr);
printf("ch 数组的大小为=> %d\n", sz_ch);
return 0;
}
字符数组中存储的都是 --hello world--为何相差一个元素呢?
打开监视查看一下就会发现
相较于arr来说,ch中多储存了一个 \0。
在字符串的结尾,计算机会自动加上一个\0。
使用:
通过下标引用操作符[]与元素下标,可以实现对数组中函数的使用
(只能逐个引用数组元素,不能一次引用整个数组。)
下标:数组中每个元素都有自己的下标,下标是从0开始依次增大的
举个例子
int main()
{
char arr[] = "abcdefgh";
printf("%c\n", arr[0]); //打印下标为 0 的元素
printf("%c\n", arr[1]); //打印下标为 1 的元素
printf("%c\n", arr[2]); //打印下标为 2 的元素
printf("%c\n", arr[3]); //打印下标为 3 的元素
printf("%c\n", arr[4]); //打印下标为 4 的元素
printf("%c\n", arr[5]); //打印下标为 5 的元素
printf("%c\n", arr[6]); //打印下标为 6 的元素
printf("%c\n", arr[7]); //打印下标为 7 的元素
return 0;
}
总结:
- 数组是使用下标来访问的,下标是从0开始。
- 数组的大小可以通过计算得到。
int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);
内存中的存储
数组在内存中是连续存放的
可以通过数组中各个元素的地址来观察
int main()
{
int arr[10] = { 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; ++i)
printf("&arr[%d] = %p\n", i, &arr[i]);
return 0;
}
可以发现每个元素的地址间相差四个字节。该数组是整型数组,可以很清晰的得知。
数组在内存中是连续存放的
注:数组名是首元素地址
arr[i] 也可以理解为 (arr+i)*
二维数组
声明
二维数组的声明与一维数组有几分相似
数据类型 数组名称[常量表达式][常量达式];
举个例子
int arr1[3][4]; 类型为 int 的包含 12(3*4) 个元素的数组 arr1
char arr2[3][5]; 类型为 char 的包含 15(3*5) 个元素的数组 arr2
double arr3[2][4]; 类型为 int 的包含 8(2*4) 个元素的数组 arr3
初始化
数据类型 数组名称[常量表达式1][常量达式2];
表达式一可以理解为 行 数
表达式二可以理解为 列 数
举个例子
int arr[3][4] = {1,2,3,4};
可以理解为声明一块三行四列的空间,依次像其中存数据,行满后存到下一行。
注:为不完全初始化,未初始化的空间补零。
以这个例子为前提,一下几个例子就好理解许多了
int arr[3][4] = {{1,2},{4,5}};
二维数组中,行数是可以省略的。会按照初始化的行数,自动确定行数的大小
int arr[][4] = {{2,3},{4,5}};
使用
二维数组的使用也是依靠下标的
以一个函数解释
int main()
{
int row = 0;
int col = 0;
int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (row = 0; row < 3; row++)
{
for (col = 0; col < 4; col++)
{
printf("arr[%d][%d]=%2d ", row, col, arr[row][col]);
}
printf("\n");
}
return 0;
}
可以通过行下标与列下标来锁定元素,以达到使用的效果
内存中的存储
二维数组在内存中也是连续存放的
#include <stdio.h>
int main()
{
int arr[3][4];
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
return 0;
}
虽然在理解二维数组时,常常把二维数组理解成一个平面,起始在内存中还是连续存放的
如下图所示
数组越界
通过下标调用函数时,需要注意下标的范围,以避免出现越界的情况
以一维数组为例子
数组存在n个元素,那么下标的范围为0 ~n-1,当下标小于0或大于n-1时便属于越界访问了,超出了数组合法空间的访问。
二维数组同理