【C语言】数组超详解(一维,二维)

目录

前言:

一,一维数组

1.1 什么是数组(array)?

1.2 数组初始化及使用

1.3一维数组在内存中的存储

二,二维数组

2.1 二维数组的创建和初始化

2.2 二维数组的使用

2.3 二维数组的存储

三,数组越界

四,数组名


前言:

学习编程,有些知识画图比较容易理解,我们也要学会画图分析,这样更能加深我们的理解。下面我就用图和代码注释的方式来讲解数组这部分的内容,当然还有一些柔性数组,指针数组,函数指针数组这些稍有点难度的指数我会放在进阶讲。接下来的几篇文章会跟你们讲解数组的练习实例,例如三子棋,扫雷。

话不多说,先来一张美图,直接开始。

一,一维数组

1.1 什么是数组(array)?

数组是一组相同类型元素的集合(注意:相同类型

格式如下:

type_t  arr_name [const]
//type_t 是指数组的元素类型
//arr_name 是指数组的名字
//const 是来指定数组的大小,一般是常量表达式,但在c99中某些编译器可以用变量指定,但数组不能初始化

如:我们创建一个包含5个元素的int型数组,数组的元素有1,2,3,4,5. 

        我们再创建一个包含5个元素的char型数组,数组的元素有a,b,c,d,e.

int arr1[5] = {1, 2, 3, 4, 5};  
char arr2[5] = {'a','b','c','d','e'};

1.2 数组初始化及使用

初始化是指,在创建数组的同时给数组的内容一些合理的初始值。代码如下:

int arr1[3] = {1, 2, 3};
int arr2[10] = {1, 2, 3, 4};
char arr3[] = {'a','b','c'};
char arr4[] = {"abc"};
char arr5[10] = {"abc"}; 

我们观察上面的代码:arr2里面有4个元素,但创建的时候有10个空间,那么其余6个空间的元素是会什么?arr3 和 arr4 里面的元素数量是相同的吗?

这些问题,我调试了一下,你们看看结果:

 从上图得知:

             数组 arr2 中没有给初始值的部分都变成了"0"。arr5也是,后面默认为“\0”(“\0”ASCII码值为0)。

             数组 arr3 和 arr4 显然不一样,arr4 有 4 位,最后一位是“ \0 ” ,arr4中用双引号括住的“abc”是字符串,在数组中字符串后面默认加上“\0”,arr3里用单引号的是单个字符,后面不会跟“\0 ”。

数组使用如下:

#include <stdio.h>
int main()
{
    int arr[10] = {0};  //arr不完全初始化
    int sz = sizeof(arr) / sizeof(arr[0]);    //用sizeof()计算数组元素个数,这里sz是10;
    int i = 0;        
    for(i = 0; i < sz; i++)  //对数组内容赋值,数组下标是从0开始
    {
        arr[i] = i;
    }
    for(i = 0; i < sz; i++) //输出数组的内容
    {
        printf("%d ",arr[i]);
    }
    return 0;
}

重点:

        1,数组是使用下标来访问,下标是从0开始。

        2,数组的大小可以通过计算获得。 

int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);//将计算的个数放在sz中

1.3一维数组在内存中的存储

 一维数组在内存中的存储是连续存放的吗?让我们观察下面打印数组地址的例子:

 观察可知:

随着数组下标的增长,元素的地址,也有规律的递增(每次增加4字节是因为整形占4个字节)

因此可得出结论:数组在内存中是连续存放的。

二,二维数组

2.1 二维数组的创建和初始化

//数组的创建
int   arr1[2][3];
char  arr2[4][3];
float arr3[3][3];
//数组的初始化
int   arr1[2][3] = {{1,2,3},{4,5,6}};
char  arr2[4][3] = {{1,2,3},{},{},{4,5,6};
float arr3[3][3] = {0};

我们可以这样理解二维数组:

 arr[2][3]: 第一个表示行数,有两行,第二个表示列数,有三列。行数可以没有,但列数必须要有。

例如:        int  arr[3][ ] = {1,2,3,4,5,6} 是非法的,编译器直接报错,因为编译器确定不了列数。

                int   arr[ ][3] = {1,2,3,4,5,6} 可以运行,编译器根据列数来推出行数为2。

2.2 二维数组的使用

二维数组的使用也是通过下标的方式。

看下面代码:

#include <stdio.h>
int main()
 {
    int arr[3][4] = {0}; //初始化为0
    int i = 0;
    for(i=0; i<3; i++)   //每列有3行     输入值
    {
        int j = 0;
        for(j=0; j<4; j++) //每行有4列
        {
            arr[i][j] = i*4+j;
        }
    }
    for(i=0; i<3; i++) //每列有3行      输出值
    {
        int j = 0;
        for(j=0; j<4; j++) //每行有4列
        {
            printf("%d ", arr[i][j]);
        }
    }
    return 0;
 }

2.3 二维数组的存储

二维数组在内存中的存储也是连续存放的吗?让我们观察下面打印数组地址的例子:

 通过结果我们可以分析到,其实二维数组在内存中也是连续储存的。

三,数组越界

注意: 
        数组的下标是有范围限制的。
        数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
        所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问

        C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以我们写代码时,最好自己做越界的检查。

#include <stdio.h>
int main() 
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    for(i=0; i<=10; i++)
    {
        printf("%d\n", arr[i]);  //当i等于10的时候,越界访问了 
    }
    return 0; 
}

  二维数组的行和列也可能存在越界。 

四,数组名

看下面例子,能更好地理解数组名。

 这两个地址居然一模一样。这是不是表示数组名就是数组首元素的地址了呢?

如果数组名是首元素地址,那么:

int  arr[10] = {0};

printf("%d\n",sizeof(arr));

为什么输出结果是:40?

下面两点需要我们注意了:

        1,sizeof(数组名),计算的是整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。

        2,&数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

        3,除去上面两点之外,所有的数组名,表示数组首元素的地址。

好了,到这就结束了,希望对你有帮助,如果有不足之处,请多多指教。

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会背雨霖铃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值