从零开始学嵌入式技术之C语言09:数组

一:数组的概念

(1)概念

        数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个标识符命名,并通过编号(索引,亦称为下标或角标)的方式对这些数据进行统一管理。      

  1. 数组名:本质上是一个标识符常量,命名需要符合标识符规范。
  2. 元素:同一个数组中的元素必须是相同的数据类型。
  3. 下标(索引、角标):从0开始的连续数字。
  4. 数组的长度:表示元素的个数。

 (2)特点

  1. 创建数组时会在内存中开辟一整块连续的空间,占据的空间的大小,取决于数组的长度和数组中元素的类型。
  2. 数组中的元素在内存中是依次紧密排列的且有序的。
  3. 数组一旦初始化完成,其长度就是确定的,数组的长度一旦确定,就不能修改。
  4. 我们可以直接通过索引(下标)获取指定位置的元素,速度很快。

 二:数组操作

(1)数组的定义

        方式一:先指定元素的个数和类型,再进行初始化

// 定义数组,数组名字是 arr1,元素类型是 int,元素个数是 3 个  
int arr1[3];

// 定义完成后再给元素赋值
arr1[0] = 100;
arr1[1] = 200;
arr1[2] = 300;

         方式二:指定元素的类型和个数并同时进行初始化

// 定义完数组直接进行初始化
int arr2[3] = {4,5,6};

         方式三:指定元素的类型,不指定元素个数,同时进行初始化

// 没有指定元素个数,系统会自动计算
int arr3[] = {7,8,9,10};

 (2)访问数组元素

        通过“数组名[下标]”可以访问数组中的元素,案例如下

#include <stdio.h>

int main()
{
    // 定义 4 个元素的数组
    int nums[4] = {10, 20, 30, 40};

    // 修改第二个元素的值
    nums[1] += 100;

    // 读取元素的值
    printf("第一个元素的值:%d\n", nums[0]); // 第一个元素的值:10
    printf("第二个元素的值:%d\n", nums[1]); // 第一个元素的值:120
    printf("第三个元素的值:%d\n", nums[2]); // 第一个元素的值:30
    printf("第四个元素的值:%d\n", nums[3]); // 第一个元素的值:40

    return 0;
}

(3)数组越界

#include <stdio.h>

int main()
{
    // 操作数组的时候不要越界操作
    int arr[5] = {10, 20, 30, 40, 50};
    // 正常访问
    printf("%d\n", arr[0]);
    printf("%d\n", arr[1]);
    printf("%d\n", arr[2]);
    printf("%d\n", arr[3]);
    printf("%d\n", arr[4]);
    // 下面操作越界操作
    printf("越界%d\n", arr[5]);
    printf("越界%d\n", arr[-2]);
    // 越界操作数组:访问的时候返回垃圾值[随机、很佛系]
    // 切记以后开发的时候,数组不越界操作
    return 0;
}

(4)计算数组长度

        数组长度(元素个数)是在数组定义时明确指定且固定的,我们不能在运行时直接获取数组长度,但是,我们可以通过sizeof 运算符间接计算出数组长度,计算步骤如下:

        使用sizeof运算符计算出整个数组的字节长度。

        由于数组成员是同一类型,每个元素字节长度相等,用整个数组的字节长度除以单个元素的字节长度就可以得到数组的长度。

#include <stdio.h>

int main()
{
    // 计算一下子数组的长度(元素个数)
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    // // 检测数组所占用的字节大小
    // // 数组所占用的字节数(内存),每一个元素所占用的字节大小之和!!!
    printf("%zu\n", sizeof(arr) / sizeof(int));
    printf("%d\n", sizeof(arr) / sizeof(arr[0]));

    return 0;
}

(5)遍历数组

        遍历数组是指按顺序访问数组中的每个元素,以便读取或修改它们,编程中一般使用循环结构对数组进行遍历。

#include <stdio.h>

int main()
{
    // 定义数组
    int arr[10] = {12, 2, 31, 24, 15, 36, 67, 108, 29, 51};
    
    // 计算数组长度
    int len = sizeof arr / sizeof arr[0];

    // 遍历数组中的元素
    printf("遍历数组中的元素:\n");
    for (int i = 0; i < len; i++)
    {
        printf("%d: %d \n", i, arr[i]);
    }

    return 0;
}

三:​​​​​​​字符数组

        用来存放字符的数组称为字符数组,也可以称为字符串。字符串的输入输出格式占位符是 %s。

        字符串结尾,会自动添加一个 \0 作为字符串结束的标志,所以字符数组最后一个元素必须是 \0。

        \0 是ASCII码表中的第0个字符,用NUL表示,称为空字符,该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在C语言中仅作为字符串的结束标志。

(1)​​​​​​​字符数组(字符串)的定义

        方式一:最后一个元素设置成 \0

        在给某个字符数组赋值时,赋值的元素个数小于字符数组的长度,则会自动在后面加 '\0', 表示字符串结束; 赋值的元素的个数等于该数组的长度(或不指定数组长度),则不会自动添加 '\0'。

#include <stdio.h>

int main()
{

    // 字符数组(字符串)几种定义形式
    // Hello,Word!
    // 第一种字符 数组的声明方式1
     char str[12] = {'H', 'e', 'l', 'l', 'o', ',', 'W', 'o', 'r', 'd', '!', '\0'};
    // 第二种形式:人家会自动在后面添加上\0
     char str1[4] = {'a', 'b', 'c'};
    //  第三种形式
    char str2[4] = {'J', 'a', 'c', 'k'};

    // 输出打印看一下:字符数组,字符串 %s
     printf("%s\n", str);
     printf("%s\n", str1);
     printf("%s\n", str2); // str2=>Jackacb,找就近的结束符才结束!!!

    return 0;
}

 方式二:简化写法

#include <stdio.h>

int main()
{
    char str1[] = {"I am happy"}; // 后面自动添加 \0
    char str2[] = "I am happy";   // 省略{}号,后面自动添加 \0

    printf("\n str1=%s", str1);
    printf("\n str2=%s", str2);

    return 0;
}

(2)字符数组(字符串)的访问和遍历

        字符数组(字符串)的访问和遍历,按照一般数组的方式访问和遍历即可。

#include <stdio.h>

int main()
{
    // 定义字符串
    char greeting[] = "Hello";

    // 计算字符串长度
    int len = sizeof greeting / sizeof greeting[0];

    printf("%s \n", greeting);
    printf("数组长度:%d \n", len);
    printf("第3个字符: %c \n", greeting[2]);
    printf("\n");

    // 遍历字符串
    for (int i = 0; i < len; i++)
    {
        printf("%c \n", greeting[i]);
    }

    return 0;
}

四:​​​​​​​多维数组

(1)介绍

        如果数组的元素还是数组,这样的数组就称为多维数组。这种多层次的结构允许我们以表格或矩阵的方式组织数据,其中每个维度都对应于不同的行、列或更多的维度,使数据更加结构化和有组织。

        多维数组可以分为二维数组、三维数组、四维数组 …… 等,这里我们以二维数组为例进行演示。

(2)二维数组

三种定义方法

#include <stdio.h>

int main()
{
    // 定义二维数组第一种写法:先定义行数、列数,在进行赋值
    int arr[3][4];
    // 在进行赋值
    arr[0][0] = 10;
    arr[0][1] = 20;
    arr[0][2] = 30;
    arr[0][3] = 40;
    arr[1][0] = 50;
    arr[1][1] = 60;
    arr[1][2] = 70;
    arr[1][3] = 80;
    arr[2][0] = 90;
    arr[2][1] = 100;
    arr[2][2] = 110;
    arr[2][3] = 120;

    // 定义二维数组:先定义行、列,同时赋值
    int arr1[3][4] = {
        {10, 20, 30, 40},
        {50, 60, 70, 80},
        {90, 100, 110, 120}};

    // 定义二维数组第三种写法:编译自动给分出行与列
    int arr2[3][4] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120};

    // 定义二维数组的第四种写法
    // 元素的个数可以整除列的情况下,可以省略行数
    int arr3[][6] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120};

    return 0;
}

(3)二维数组的访问和遍历

        访问二维数组的元素,需要使用两个下标(索引),一个用于访问行(第一维),另一个用于访问列(第二维),我们通常称为行下标(行索引)或列下标(列索引)。

        遍历二维数组,需要使用双层循环结构。

#include <stdio.h>

int main()
{
    int arr[3][4] = {
        {10, 20, 30, 40},
        {50, 60, 70, 80},
        {90, 100, 110, 120}};
    // 双层循环语句遍历,外层遍历行数、内层遍历列数
    int row = 3, col = 4;
    // 遍历行数
    for (int i = 0; i < row; i++)
    {
        // 遍历列数
        for (int j = 0; j < col; j++)
        {
            printf("%d行%d列:[%d]\t", i + 1, j + 1, arr[i][j]);
        }
        // 换行
        printf("\n");
    }
    return 0;

        用矩阵形式(如3行4列形式)表示二维数组,是逻辑上的概念,能形象地表示出行列关系。而在内存中,各元素是连续存放的,不是二维的,是线性的。

        C语言中,二维数组中元素排列的顺序是按行存放的。即:先顺序存放第一行的元素,再存放第二行的元素。

(4)​​​​​​​应用案例

        现在有三个班,每个班五名同学,用二维数组保存他们的成绩,并求出每个班级平均分、以及所有班级平均分,数据要求从控制台输入。

#include <stdio.h>

int main()
{
    // 定义二维数组,将来记录3个班级,15孩子成绩!!
    double arr[3][5];
    // 双重循环语句,给二维数组赋值
    // 代表三行,每行是一个班级
    int row = 3;
    // 代表五列,每一列代表孩子
    int col = 5;
    // 外层代表行数-每隔班级
    for (int i = 0; i < row; i++)
    {
        // 内层代表列-每一个孩子
        for (int j = 0; j < col; j++)
        {
            printf("请你输入%d班级,第%d学生的成绩", i + 1, j + 1);
            scanf("%lf", &arr[i][j]);
        }
    }


    //   保存某一个班级总分
    double classSum = 0, totalSum = 0;

    // 计算出每隔班级平均分、学校平均分
    for (int i = 0; i < row; i++)
    {
        // 每一次记录当前班级总分的时候,要把上一次班级总分清零
        classSum = 0;
        for (int j = 0; j < col; j++)
        {
            classSum += arr[i][j];
        }
        printf("%d的成绩总分:%lf,平均分数为:%lf\n", i + 1, classSum, classSum / col);
        // 累加每一个班级总分
        totalSum += classSum;
    }

    printf("这个学校个人平均分:%lf", totalSum / (row * col));

    return 0;
}

五:本章练习

(1)第一题

        从终端循环输入5个成绩,保存到double数组,并输出。

#include <stdio.h>
// (1)从终端循环输入5个成绩,保存到double数组,并输出。
int main()
{
    double achievement[5];
    for (int i = 0; i < 5; i++)
    {
        printf("请输入第%d个成绩", i+1);
        scanf("%d", &achievement[i]);
    }
    for (int j = 0; j < 5; j++)
    {
        printf("%d\t",achievement[j]);
    }
    

    return 0;
}

(2)第二题

        一个养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg。请问这六只鸡的总体重是多少?平均体重是多少?

#include <stdio.h>
// (2)一个养鸡场有6只鸡,它们的体重分别是
// 3kg,5kg,1kg,3.4kg,2kg,50kg。
// 请问这六只鸡的总体重是多少?平均体重是多少?
int main()
{
    double chicken[6] = {3, 5, 1, 3.4, 2, 50};
    double sum = 0, average = 0;
    for (int i = 0; i < 6; i++)
    {
        sum += chicken[i];
    }
    average = sum / 6;
    printf("总体重为:%.2lf\n", sum);
    printf("平均体重为:%.2lf", average);

    return 0;
}

(3)第三题

        创建一个char类型的26个元素的数组,分别放置'A'-'Z‘。使用for循环访问所有元素并打印出来。

#include <stdio.h>
// 创建一个char类型的26个元素的数组,
// 分别放置'A'-'Z‘。使用for循环访问所有元素并打印出来。
int main()
{
    char zimu[26];
    for (int i = 0; i < 26; i++)
    {
        zimu[i] = 65 + i;
    }
    for (int j = 0; j < 26; j++)
    {
        printf("%c\n", zimu[j]);
    }

    return 0;
}

(4)第四题

        请求出一个数组的最小值,并得到对应的索引。

        

#include <stdio.h>
// 请求出一个数组的最小值,并得到对应的索引
int main()
{
    int a;

    printf("请输入你想创造的数组大小");
    scanf("%d", &a);
    double num[a];
    for (int i = 0; i < a; i++)
    {
        printf("请输入第%d个数字", i + 1);
        scanf("%lf", &num[i]);
    }
    

    double mini = num[0];
    int index = 0;
    for (int i = 0; i < a; i++)
    {
        if (num[i] < mini)
        {
            mini = num[i];
            printf("%d\n",mini);
            index = i;
        }
    }
    printf("最小的数字为:%.2lf\n", mini);
    printf("数字索引序号为:%d\n", index);
    return 0;
}

(5)第五题

        如何计算数组的长度?

     答案:

  1.  使用sizeof运算符计算出整个数组的字节长度。
  2. 由于数组成员是同一类型,每个元素字节长度相等,用整个数组的字节长度除以单个元素的字节长度就可以得到数组的长度。

 (6)第六题

        字符数组(字符串)的最后一个元素是什么?

        答案:\0

        本章内容到此结束啦

        关注我一起成为嵌入式大佬

  • 47
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值