C语言:数组

1. 数组的概念

数组是一组相同类型的元素的集合,其中,有两个关键点。

1.数组中存放了一个或者多个数据,数组的元素个数不能为0.

2.一个数组中的所有数据的类型是相同的。

数组分为一维数组和多维数组,多维数组中较为常见的是二维数组。

2. 一维数组

2.1 数组创建

数组的创建语法如下:

type arr_name[常量值];

type指数组中存储的数据的类型,可以是int、float、char、short等,也可以是自定义的类型。

 arr_name指数组的名字,名字可以任取,最好是根据实际情况取有意义的名字。

[ ]中常量值用于控制数组的大小,即储存数据的上限,根据实际需求来规定。

2.2 数组的初始化

与创建变量时相似,在创建数组的时候,我们需要给定⼀些初始值,这种就称为初始化。

在初始化数组时,我们一般使用大括号,将要存放的数据放在大括号中。

//完全初始化
int arr[4] = { 1 , 2 , 3 , 4 };

//部分初始化
int arr[4] = { 1 };//将第一项初始化为1,其他项默认初始化为0

//省略数组大小
int arr[]  { 1 , 2 , 3 , 4 };//初始化后系统将会自动计算数组大小
 
//错误的初始化
int arr[4] = { 1 , 2 , 3 , 4 , 5};//初始化的项数多余数组大小

2.3 数组的类型

数组也拥有类型,其类型就是去掉数组名的部分。

int arr1[10];
char arr2[6];
float arr3[5];

数组arr1的类型为int [10]。

数组arr2的类型为char[6]。

数组arr1的类型为float [5]。

3. 一维数组的使用

学习了⼀维数组的基本语法,⼀维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们如何 使⽤⼀维数组呢?

3.1 数组下标

C语言规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下标就相当于数组元素的编号,如下:

int arr[5] = {1,2,3,4,5};

//数组元素 1 2 3 4 5
//元素下标 0 1 2 3 4

在C语⾔中数组的访问提供了⼀个操作符 [ ] ,这个操作符叫:下标引用操作符。

利用下标引用操作符我们可以轻松访问数组中的元素:

#include 

int main()
{
    int arr[6] = {1,2,3,4,5,6};
    printf("%d ",arr[3]);
    printf("%d ",arr[5]);
    return 0;
}

3.2 打印数组元素

当我们想要访问整个数组的元素时,只需要产生所有的数组元素下标,进而就能访问所有的数组元素:

#include 

int main()
{
    int i;
    int arr[6] = {1,2,3,4,5,6};
    for(i = 0;i < 6;i++)
    {
        printf("%d ",arr[i]);
    }
    return 0;
}

3.3 数组的输入

我们也可以根据自己的需求自己给数组输入元素:

#include 

int main()
{
    int i;
    int arr[6] = {0};
    for(i = 0 ;i < 6 ;i++)
    {
        scanf("%d",&arr[i]);
    }
    for(i = 0 ;i < 6 ;i++)
    {
        printf("%d",arr[i]);
    }
    return 0;
}

4. 一维数组在内存中的存储

有了前面的知识,我们使用数组基本就没有什么障碍了,但如果我们要深入了解数组,我们最好能了解一下数组在内存中的存储。

打印数组中各个元素的地址:

#include 

int main()
{
    int i;
    int arr[6] = {0};
    for(i = 0 ;i < 6 ;i++)
    {
        printf("&arr[%d] = %p\n",i,&arr[i]);
    }
    return 0;
}

 这是打印结果:

&arr[0] = 000000859C3FFA30
&arr[1] = 000000859C3FFA34
&arr[2] = 000000859C3FFA38
&arr[3] = 000000859C3FFA3C
&arr[4] = 000000859C3FFA40
&arr[5] = 000000859C3FFA44

其中,我们可以发现,数组元素的地址是随着下标变大而增大的,并且相邻的两个元素之间相差4,这是因为一个int类型的数据占据4个字节。所有,我们可以得出结论:数组在内存中是连续存放的。

5. sizeof 计算数组元素个数

在实际运用中,我们常常想知道数组的大小,而C语言中一个办法可以直接计算出数组大小。

sizeof 中C语言是⼀个关键字,可以计算类型或者变量大小,其实sizeof也可以用来计算数组的大小。

例如:

#include 

int main()
{
    int arr[6] = {0};
        printf("%d\n",sizeof(arr));
    return 0;
}

输出结果为24,单位为字节,sizeof()计算的是数组在内存中所占的空间大小。

我们知道,数组中的元素类型是相同的,所以,只需要知道一个元素所占据的字节大小,再用数组总大小除以这个值,就可以得到元素个数,也就是数组大小。

#include 

int main()
{
    int arr[6] = {0};
    printf("%d\n",sizeof(arr)/sizeof(arr[0]));
    return 0;
}

此时,输出为6,表示数组大小为6。

6. 二维数组的创建

6.1 二维数组的概念

前面学习的数组被称为一维数组,数组的元素都是内置类型的,如果我们把一维数组做为数组的元 素,这时候就是二维数组,二维数组作为数组元素的数组被称为三维数组,二维数组以上的数组统称为多维数组。

6.2 二维数组的创建

二维数组的创建语法如下:

type arr_name[常量值1][常量值2];

//例如:
int arr1[3][4]

int代表了这个二维数组中的元素类型为整型。

arr1为数组名。

3代表了3行;4代表了4列,即每一行有4个元素。

6.3 二维数组的初始化

//完全初始化
int arr[3][3] = {1,2,3, 2,3,4, 3,4,5};

    1 2 3
    2 3 4
    3 4 5


//不完全初始化
int arr[3][3] = {1,2};//第一行第一、二个元素分别初始化为1、2,其余均默认初始化为0

    1 2 0
    0 0 0
    0 0 0


//分行初始化
int arr[3][3] = {{1,2},{2,3},{3,4}};

    1 2 0
    2 3 0
    3 4 0

//初始化时可以省略行,但不可以省略列
int arr[][3] = {{1,2},{2,3},{3,4}}

    1 2 0
    2 3 0
    3 4 0

7. 二维数组的使用

 7.1 二维数组的下标

访问二维数组与访问一维数组相似,都是通过下标来访问数组元素,不过二维数组需要两个下标才能锁定唯一的元素。

与一维数组相同,二维数组的下标也是从0开始:

#include 

int main()
{
    int i,j;
    int arr[3][3] = {1,2,3, 2,3,4, 3,4,5};
    for(i = 0;i < 3;i++)
    {
        for(j = 0;j < 3;j++)
        {
            printf("arr[%d][%d] = %d ",i,j,arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}
//输出结果

arr[0][0] = 1 arr[0][1] = 2 arr[0][2] = 3 
arr[1][0] = 2 arr[1][1] = 3 arr[1][2] = 4 
arr[2][0] = 3 arr[2][1] = 4 arr[2][2] = 5 

7.2 二维数组的输入与输出

与一维数组的输入方式相似,区别在于二维数组多了一个需要确定的下标:

#include 

int main()
{
    int i,j;
    int arr[3][3] = {0};
    for(i = 0;i < 3;i++)
    {
        for(j = 0;j < 3;j++)
        {
            scanf("%d",&arr[i][j]);
        }
        printf("\n");
    }
    for(i = 0;i < 3;i++)
    {
        for(j = 0;j < 3;j++)
        {
            printf("arr[%d][%d] = %d ",i,j,arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

8. 二维数组在内存中的存储

我们来看看二维数组的储存规则是否与一维数组相同:

打印各个元素的地址:

#include 

int main()
{
    int i,j;
    int arr[3][3] = {0};
    for(i = 0;i < 3;i++)
    {
        for(j = 0;j < 3;j++)
        {
            printf("&arr[%d][%d] = %p\n",i,j,&arr[i][j]);
        }
    }
    return 0;
}
&arr[0][0] = 000000FBBC9FFDD0
&arr[0][1] = 000000FBBC9FFDD4
&arr[0][2] = 000000FBBC9FFDD8
&arr[1][0] = 000000FBBC9FFDDC
&arr[1][1] = 000000FBBC9FFDE0
&arr[1][2] = 000000FBBC9FFDE4
&arr[2][0] = 000000FBBC9FFDE8
&arr[2][1] = 000000FBBC9FFDEC
&arr[2][2] = 000000FBBC9FFDF0

我们可以发现与一维数组元素的地址相对比,二维数组元素的地址也是随下标增大而增大,相邻元素的地址相差4,与一维数组相同,因此,二维数组的元素也是连续存储的。

9. C99中的变长数组

在C99标准之前,C语言在创建数组的时候,数组的大小只能使用常量、常量表达式来指定,或者是在初始化数组的时候,省略数组大小。这样的语法限制,让我们创建数组就不够灵活,有时候数组大了浪费空间,数组小了又不够用。

而C99则给出了一个名为变长数组(variable-lengtharray,简称VLA)的新特性,允许我们使用变量指定数组大小。

int n = a+b;
int arr[n];

上面示例中,数组arr就是变⻓数组,因为它的长度取决于变量n的值,编译器没法事先确定,只有运行时才能知道n是多少。

变长数组的根本特征就是数组长度只有运行时才能确定,因此变长数组不能初始化。它的好处是程序员在开发时,不需要随意为数组指定⼀个估计的长度,程序可以在运行时为数组分配精确的长度。有一个比较迷惑的地方是,变长数组的意思是数组的大小是可以使用变量来指定的,在程序运行的时候,根据变量的大小来指定数组的元素个数,而不是说数组的大小是可变的。数组的大小⼀旦确定就不能再变化了。

是否拥有这个功能与编译器有关系,有兴趣可以自己进行尝试。

你可能感兴趣的:(c语言)