首页 > 其他分享 >从零开始学嵌入式技术之C语言09:数组

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

时间:2024-08-02 10:24:45浏览次数:14  
标签:arr 元素 int 09 嵌入式 数组 printf 长度 C语言

一:数组的概念

(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

        本章内容到此结束啦

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

标签:arr,元素,int,09,嵌入式,数组,printf,长度,C语言
From: https://blog.csdn.net/mkk521/article/details/140845475

相关文章

  • 深入理解C语言中的结构体
    目录引言一.结构体的基本概念1.结构体的声明2.结构体变量的创建和初始化3.结构体成员访问操作符4.结构体的特殊声明1.匿名结构体2.嵌套结构体3.结构体自引用4.typedef声明二、结构体内存对⻬1.对⻬规则2.为什么存在内存对⻬?3.修改默认对齐数三、结构体......
  • C语言中的条件判断与分支选择:深入解析if, else, else if与switch
    引言在C语言编程中,条件判断与分支选择是构建复杂逻辑、实现不同场景下代码执行路径分流的基石。if、else、elseif以及switch语句作为C语言提供的强大工具,让我们能够根据条件表达式的真假值,灵活地控制程序的执行流程。本文将带您深入探索这些判断语句的语法细节、使用场景及最佳......
  • C语言运算符深度解析--超详细
    引言在C语言的浩瀚宇宙中,运算符如同点亮星辰的魔法棒,它们不仅连接着数据的海洋,更驱动着程序的逻辑流转。从基础的算术运算到复杂的位操作,每一个运算符都承载着特定的功能,是构建程序逻辑的基石。掌握C语言的运算符,就如同手握开启编程世界大门的钥匙,让你能够自如地编写出高效、精准......
  • C++和C语言if else
    一、if。if(/*表达式*/)//如果表达式成立,执行大括号里的代码。如果表达式不成立,执行大括号下面的代码。{//代码}二、else。 else//else一般和if配对,如果if表达式不成立,执行else。如果if表达式成立,不执行else{//代码} 所以执行如上代码输出的是"1是单数"。......
  • 嵌入式软件--C语言高级 DAY 8 函数
    函数是C语言尤为重要的知识点,再嵌入式的学习过程中,对51和32的单片机的学习是重中之重。一、函数的基本概念1.介绍函数是一种可重复使用的代码块,用于执行特定的任务或操作。函数允许我们将代码逻辑组织成独立的单元,从而提高了代码的可读性、可维护性和重用性。一个C程序可......
  • 酸奶配面包的c语言世界(3)
    第三讲:分支与循环(上)写自己的东西不要做留声机不要做写满字的纸要做孤天的鹤                    ——24.7.291.if语句if语句的语法形式:if(表达式)语句c语言中,0表示假,非0表示真表达式为非0(真),那么语句执行,表达式为0(假),则语......
  • 嵌入式开发C语言学习day26-华清作业8.1
    思维导图作业//使用两个线程完成两个文件的拷贝,分支线程1拷贝前一半,分支线程2拷贝后一半,主线程回收两个分支线程的资源#include<myhead.h>#defineMAX1024structBuf{charfile1[20];charfile2[20];intsize;};//进程1拷贝前半内容void*copy......
  • 图的遍历及其C语言实现
    目录1.为什么需要两种遍历方法?2.深度优先搜索(DeepthFirstSearch,DFS)思想:具体过程:伪代码:时间复杂度:3.广度优先搜索(BreadthFirstSearch,BFS) 思想:具体过程: 伪代码: 时间复杂度:图示: ​编辑 C语言代码演示1.为什么需要两种遍历方法?解决不同问题:DFS适用......
  • 重头开始嵌入式第八天(字符串,二维数组)
    今天继续介绍字符数组以下是一些常见的C语言字符串处理函数的介绍、函数本体、返回值、用法及实现示例: 以下是 puts 和 gets 函数的介绍、函数本体、返回值、用法及实现示例:字符处理函数puts() 函数-函数意思:将字符串输出到标准输出(通常是屏幕)并换行-函数......
  • 重头开始嵌入式第九天(函数)
    今天继续学习字符串viodbzero(void*s,size_tn)功能:将s开始的n个字节,清除为0二维字符数组:一维字符串的数组接下来进入今天的正题,函数。函数 在C语言中,函数是一段用于完成特定任务的独立代码块。下面我们来详细地阐述其特点和基本要素: 函数声明:函数声明明确了......