《小菜狗 C 语言入门 + 进阶笔记》(24)数组入门 -- 保证入门【很重点】

《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介

暂时无法在飞书文档外展示此内容

1、引入

变量的出现使得我们可以存放单个的数据,那假设我们有⼀组数据,比如:某个班级的数学成绩有 30 个数据,我们就需要创建 30 个变量去存储码?如果是一个年段上千个数据,会不会太复杂了?

这时候 C 语⾔中给了⼀个数组的概念,可以让我们创建⼀块连续的空间来存放⼀组数据。

2、数组概念

数组是⼀组相同类型元素的集合

  • 固定大小的
  • 相同类型的
  • 元素的顺序集合

数组的定义并不是声明一个个单独的变量,比如 runoob0、runoob1、...、runoob99,而是声明一个数组变量,使用 runoob[0]、runoob[1]、...、runoob[99] 来代表一个个单独的变量。

我们把这样的一组数据的集合称为数组(Array),它所包含的每一个数据叫做数组元素(Element),所包含的数据的个数称为数组长度

3、数组声明

基本语法:

type arrayName [index]

type 为数据类型, arrayName 为数组名称,index 为下标

如下:

数据类型  数组名  [下标]

这个数组也叫做一维数组。数组在创建的时候可以指定数组的大小和数组的元素类型。

  • 下标 必须是一个大于零的整数常量
  • 数据类型 可以是任意有效的 C 数据类型,可以是 char、short、int、float 等,也可以⾃定义的类型;
  • 数组名根据实际情况,起的有意义就⾏;

例如,要声明一个类型为 int 的包含 5 个元素的数组 balance,声明语句如下:

int balance[5];
//现在 balance 是一个可用的数组,可以容纳 5 个类型为 int 的数字。

4、数组初始化

根据使用的用途不同,对数组赋值可以在:

  • 先定义数组再给数组赋值;
  • 也可以在定义数组的同时初始化赋值,称为初始化数组。

使用符号:

数组元素的值使用大括号,将数据放在大括号{ }中,各个值之间以,分隔。

简单举例:

把同一个类型为 int 的 5 个值 1,2,3,4,5 ,存入 a 数组里,如下所示:

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

注意:大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。

底下这是错误的!
int a[5] = {1,2,3,4,5,6};

数组的初始化注意总结:

(1) 可以逐个初始化数组,也可以使用一个初始化语句,如下所示:

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

与底下写法是等价的:

double balance[5];
balance[0] = 1000.0;
balance[1] = 2.0;
balance[2] = 3.4;
balance[3] = 7.0;
balance[4] = 50.0;

上述的语句把数组中第五个元素的值赋为 50.0。所有的数组都是以 0 作为它们第一个元素的索引,数组的最后一个索引是数组的总大小减去 1。

以下是上面数组的图形表示:
在这里插入图片描述

(2) 只能给元素逐个赋值,不能给数组整体赋值。例如给 10 个元素全部赋值为 1,只能写作:

int a[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

而不能写作:

int a[10] = 1;//错误写法

(3) 如只给部分元素赋值。当{ }中值的个数少于元素个数时,只给前面部分元素赋值。

例如:

int a[10] = {12,19,22,993,344};

表示只给 a[0]~a[4] 5 个元素赋值,而后面 5 个元素自动初始化为 0。

当赋值的元素少于数组总体元素的时候,剩余的元素自动初始化为 0

  • 对于 short、int、long,就是整数 0
  • 对于 char,就是字符 '\0'
  • 对于 float、double,就是小数 0.0

我们可以通过下面的形式将数组的所有元素初始化为 0:

int nums[10] = {0};
char str[10] = {0};
float scores[10] = {0.0};

由于剩余的元素会自动初始化为 0,所以只需要给第 0 个元素赋值为 0 即可。

(4) 如给全部元素赋值,那么在定义数组时可以不给出数组长度。例如:

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

等价于

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

也就是如果省略掉了数组的大小,数组的大小则为初始化时元素的个数

总结小举例:

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

//不完全初始化
//第⼀个元素初始化为1,剩余的元素默认初始化为0
int arr2[6] = {1};

//错误的初始化 - 初始化项太多
int arr3[3] = {1, 2, 3, 4};

//错误的初始化 - 初始化不是使用()
int arr4[] = (1,2,3,4);

5、数组下标

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

如下:

int arr[10] = {1,2,3,4,5,6,7,8,9,10};

在这里插入图片描述

可以看出:

下标从 0 开始,数组有 10 个元素,最后⼀个元素的下标是 9。

数组的访问提供了⼀个操作符 [],这个操作符叫:下标引用操作符

比如我们访问下标为 7 的元素,我们就可以使用 arr[7] ,想要访问下标是 3 的元素,就可以使用 arr[3] 。

6、访问数组元素

存放在数组的值被称为数组的元素(Element)

数组元素可以通过数组名称加索引(下标)进行访问。例如:

double salary = balance[9];

上面的语句将把数组中第 10 个元素的值赋给 salary 变量

在学习过程中,我们经常会使用循环结构将数据放入数组中(也就是为数组元素逐个赋值),然后再使用循环结构输出(也就是依次读取数组元素的值),下面我们就来演示一下如何将 0~4 这十个数字放入数组中:

#include <stdio.h>
int main()
{
    int nums[5];
    int i;
   
    //将 0~4放入数组中
    for (i=0; i<5; i++) {
        nums[i] = i;
    }
   
    //依次输出数组元素
    for (i=0; i<5; i++) {
        printf("%d ", nums[i]);
    }
   
    return 0;
}

运行结果:

0 1 2 3 4

详细解释:

这里的 0、1、2、3、4 就是数组下标nums[0]、nums[1]、nums[2]、nums[3] 、nums[4] 就是数组元素

而且:

变量 i 既是数组下标,也是循环条件;将数组下标作为循环条件,达到最后一个元素时就结束循环。数组 nums 的最大下标是 4,也就是不能超过 5,所以我们规定循环的条件是 i<5,一旦 i 达到 5 就得结束循环。

7、数组的类型

去掉数组名留下的就是数组的类型。

int arr1[10];
int arr2[12];
char ch[5];

arr1 数组的类型是 int [10] ;

arr2 数组的类型是 int [12] ;

ch 数组的类型是 char [5] ;

8、数组的输入

根据某些需求,可以给数组输入想要的数据,如下:

注意:代码中 arr[i] 相当于一个变量,所以 scanf 参数是 & + arr[i],别复合了就懵逼了亲。

#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++)
    {
        scanf("%d", &arr[i]);
    }
    for (i=0; i<10; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

运行结果:

2 1 4 3 6 5 8 7 0 9
2 1 4 3 6 5 8 7 0 9

9、获取数组长度

数组长度可以使用 sizeof 运算符获取数组的长度

例如:

int numbers[] = {1, 2, 3, 4, 5};
int length = sizeof(numbers) / sizeof(numbers[0]);

实例:

#include <stdio.h>

int main() {
    int array[] = {1, 2, 3, 4, 5};
    int length = sizeof(array) / sizeof(array[0]);

    printf("数组长度为: %d\n", length);

    return 0;
}

输出结果:

数组长度为: 5

10、数组内存

所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。

数组是一个整体,它的内存是连续的;也就是说,数组元素之间是相互挨着的,彼此之间没有一点点缝隙。

如图:
在这里插入图片描述

打印数组元素的地址:

#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("&arr[%d] = %p\n ", i, &arr[i]);
    }
    return 0;
}

输出结果:

&arr[0] = 01558ED0
&arr[1] = 01558ED4
&arr[2] = 01558ED8
&arr[3] = 01558EDC
&arr[4] = 01558EE0
&arr[5] = 01558EE4
&arr[6] = 01558EE8
&arr[7] = 01558EEC
&arr[8] = 01558EF0
&arr[9] = 01558EF4

从输出的结果分析:

数组随着下标的增长,地址是由小到大变化的,并且我们发现每两个相邻的元素之间相差 4(因为⼀个整型是 4 个字节)。

得出结论:

数组在内存中是连续存放的,随着数组下标的增长,地址是由低到高变化的。这就为后期我们使用指针访问数组奠定了基础。

因此:

数组内存是连续的 这一点很重要,特别强调。

连续的内存为指针操作(通过指针来访问数组元素)和内存处理(整块内存的复制、写入等)提供了便利,这使得数组可以作为缓存(临时存储数据的一块内存)使用。

大家如果可能不理解是什么意思,等后边学了指针和内存自然就明白了。

11、初学注意项

(1)数组中每个元素的数据类型必须相同,对于int a[4];,每个元素都必须为 int。

(2)数组长度 length 是整数或者常量表达式,例如 10、20*4 等,这样在所有编译器下都能运行通过;如果 length 中包含了变量,例如 n、4*m 等,编译时就会报错。

(3)访问数组元素时,下标的取值范围0 ≤ index < length,过大或过小都会越界,导致数组溢出,发生不可预测的情况。

《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介


每日一更!

公众号、优快云等博客:小菜狗编程笔记

谢谢点赞关注哈!目前在飞书持续优化更新~

日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小菜狗编程笔记

你的鼓励将是我最大的动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值