首页 > 其他分享 >C语言 10 数组

C语言 10 数组

时间:2024-09-06 09:49:47浏览次数:4  
标签:10 arr int 31 30 C语言 fib 数组

简单来说,数组就是存放数据的一个组,所有的数据都统一存放在这一个组中,一个数组可以同时存放多个数据。

一维数组

比如现在想保存 12 个月的天数,那么只需要创建一个 int 类型的数组就可以了,它可以保存很多个 int 类型的数据,这些保存在数组中的数据,称为元素

// 12个月的数据全部保存在了一起
int arr[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

可以看到,数组的定义方式也比较简单:

类型 数组名称[数组大小] = {数据1, 数据2...};
  • 后面的数据可以在一开始的时候不赋值
  • 数组大小必须是整数

注意数组只能存放指定类型的数据,一旦确定是不能更改的。

因为数组声明后,会在内存中开辟一块连续的区域,来存放这些数据,所以类型和长度必须在一开始就明确。

创建数组的方式有很多种:

// 直接声明int类型数组,容量为10
int a[10];   

// 声明后,可以赋值初始值,使用{}囊括,不一定需要让10个位置都有初始值,比如这里仅仅是为前三个设定了初始值
// 注意,跟变量一样,如果不设定初始值,数组内的数据并不一定都是0
int b[10] = {1, 2, 4};   

// 也可以通过 [下标] = 的形式来指定某一位的初始值
// 注意下标是从0开始的,第一个元素就是第0个下标位置,比如这里数组容量为10,那么最多到9
int c[10] = {1, 2, [4] = 777, [9] = 666}; 

// 也可以根据后面的赋值来决定数组长度
int c[] = {1, 2, 3};  

基本类型都可以声明数组:

#include <stdio.h>

int main() {
    // 多个字符
    char str[] = {'A', 'B', 'C'};   

    // 实际上字符串就是多个字符的数组形式
    char str2[] = "ABC";  
}

那么数组定义好了,如何去使用它呢?比如现在需要打印 12 个月的天数:

#include <stdio.h>

int main() {
    int arr[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    for (int i = 0; i < 12; i++) {
        // 直接通过数组 名称[下标] 来访问对应的元素值
        int days = arr[i];   
        printf("2022年 %d 月的天数是:%d 天\n", (i + 1), days);
    }
}
2022年 1 月的天数是:31 天
2022年 2 月的天数是:28 天
2022年 3 月的天数是:31 天
2022年 4 月的天数是:30 天
2022年 5 月的天数是:31 天
2022年 6 月的天数是:30 天
2022年 7 月的天数是:31 天
2022年 8 月的天数是:31 天
2022年 9 月的天数是:30 天
2022年 10 月的天数是:31 天
2022年 11 月的天数是:30 天
2022年 12 月的天数是:31 天

当然也可以对数组中的值进行修改:

#include <stdio.h>

int main() {
    int arr[] = {666, 777, 888};
    // 比如现在想要让第二个元素的值变成999
    arr[1] = 999;
    // 打印一下看看是不是变成了999
    printf("%d", arr[1]);
}
999

和变量一样,如果只是创建数组但是不赋初始值的话,因为是在内存中随机申请的一块空间,有可能之前其他地方使用过,保存了一些数据,所以数组内部的元素值并不一定都是 0:

#include <stdio.h>

int main() {
    int arr[10];
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
}
10566448 0 -962063554 32758 1 0 10566394 0 10566554 0

不要尝试去访问超出数组长度位置的数据,虽然可以编译通过,但是会给警告,这些数据是毫无意义的:

#include <stdio.h>

int main() {
    int arr[] = {111, 222, 333};
    // 不能去访问超出数组长度的元素,很明显这里根本就没有第四个元素
    printf("%d", arr[3]);
}
42

多维数组

数组不仅仅只可以有一个维度,也可以创建二维甚至多维的数组,简单来说就是,存放数组的数组:

// 可以看到,数组里面存放的是数组
int arr[][2] = {{20, 10}, {18, 9}};

存放的内层数组的长度是需要确定的,存放数组的数组和之前一样,可以根据后面的值决定

比如现在要存放 2020 - 2022 年每个月的天数,那么此时用一维数组就不方便了,可以使用二维数组来处理:

// 2020年是闰年,2月有29天
int arr[3][12] = {{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};

这样,就通过二维数组将这三年每个月的天数都保存下来了。

那么二维数组又该如何去访问呢?

#include <stdio.h>

int main() {
    // 2020年是闰年,2月有29天
    int arr[3][12] = {{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
                      {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                      {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
    // 比如现在想要获取2020年2月的天数,首先第一个是[0]表示存放的第一个数组,第二个[1]表示数组中的第二个元素
    printf("%d", arr[0][1]);   
}
29

当然除了二维还可以上升到三维、四维:

int arr[2][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}};

多维数组比较复杂,使用得也比较少,这里就不深入研究了。

实战:冒泡排序算法

现在有一个 int 数组,但是数组内的数据是打乱的,现在通过 C 语言,实现将数组中的数据按从小到大的顺序进行排列。

这里使用冒泡排序算法来实现,此算法的核心思想是:

  1. 假设数组长度为 N
  2. 进行 N 轮循环,每轮循环都选出一个最大的数放到后面
  3. 每次循环中,从第一个数开始,让其与后面的数两两比较,如果更大,就交换位置,如果更小,就不动

动画演示:https://visualgo.net/zh/sorting?slide=2-2

#include <stdio.h>

// 冒泡排序
int main() {
    // 乱序数组
    int arr[10] = {16, 5, 7, 32, 59, 10, 64, 1, 38, 41};
    // 遍历数组元素
    for (int i = 0; i < 10; i++) {
        // 是否交换
        _Bool flag = 0;
        // 循环实现交换
        for (int j = 0; j < 10 - i; j++) {
            // 比较当前元素和下一个元素
            if (arr[j] > arr[j + 1]) {
                // 交换两个元素
                int temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
                // 发生了交换,设为1
                flag = 1;
            }
        }
        // 如果都没有发生交换,说明已经排好序了,跳出循环
        if (flag == 0) {
            break;
        }
    }
    // 打印排序后数组
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
}

实战:斐波那契数列解法其二

学习了数组,再来看看如何利用数组来计算斐波那契数列,这里采用动态规划的思想。

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

可以在一开始创建一个数组,然后从最开始的条件不断向后推导,从斐波那契数列的规律可以得知:

fib[i] = fib[i - 1] + fib[i - 2](这里fib代表斐波那契数列)

得到这样的一个关系(递推方程)就好办了,要求解数列第i个位置上的数,只需要知道i - 1i - 2的值即可,这样,一个大问题,就分成了两个小问题,比如现在要求解斐波那契数列的第 5 个元素:

  • fib[4] = fib[3] + fib[2]现在我们只需要知道fib[3]fib[2]即可,那么我们接着来看:
  • fib[3] = fib[2] + fib[1]以及fib[2] = fib[1] + fib[0]
  • 由于fib[0]fib[1]我们已经明确知道是1了,那么现在问题其实已经有结果了

现在设计一个 C 语言程序,利用动态规划的思想解决斐波那契数列问题。

#include <stdio.h>

// 斐波那契数列解法其二
int main() {
    // 斐波那契数列的元素位置
    int index = 6;
    // 根据位置建立数组
    int arr[index];
    // 第一个元素固定为1
    arr[0] = 1;
    // 第二个元素固定为1
    arr[1] = 1;
    // 遍历数组
    for (int i = 2; i < index; i++) {
        // 根据斐波那契数列定义,从第三项开始,每一项都等于前两项之和
        arr[i] = arr[i - 1] + arr[i -2];
    }
    // 打印数组元素
    printf("%d", arr[index - 1]);
}

标签:10,arr,int,31,30,C语言,fib,数组
From: https://www.cnblogs.com/skysailstar/p/18399642

相关文章

  • GAMES101(0~1作业)
    搭建虚拟机环境安装OracleVMVirtualBox虚拟机,安装虚拟硬盘,配置Linux Ubuntu-64bit系统,启动虚拟机,发生冲突错误:将Vmware虚拟设备取消挂起状态,关机确保Hyper-V完全关闭:bcdedit/sethypervisorlaunchtypeoff重启计算机安装增强功能,未找到iso错误:ISO下载地址:Indexof......
  • 【代码随想录训练营第42期 Day51打卡 - 岛屿问题 - 卡码网 99. 岛屿数量 100. 岛屿的
    目录一、做题心得二、题目与题解题目一:99.岛屿数量题目链接题解1:DFS 题解2:BFS 题目二:100.岛屿的最大面积题目链接题解:DFS 三、小结一、做题心得今天打卡的是经典的岛屿问题:分别从两个方向进行探讨--深搜(DFS)与广搜(BFS)。作为这两大基本搜索最经典的例题,今天......
  • P1000 超级玛丽游戏
    #include<iostream>usingnamespacestd;intmain(){ cout<<"********\n"; cout<<"************\n"; cout<<"####....#.\n"; cout<<"......
  • OWASP TOP10 漏洞解析:访问控制崩溃
    一、定义访问控制崩溃,指的是访问控制策略没有被正确地执行,导致用户可以在他们的预期权限之外进行操作。这种缺陷通常会导致未授权的信息被泄露、修改、销毁,或者让用户执行了超出其权限限制的业务功能。表现形式,也就是我们常说的越权漏洞。越权分为:水平越权:A、B两个用户......
  • 力扣 88.合并两个有序数组
    思路:比较两个数组中最大的数(数组是非递减的),选取大的那个,从nums1的最后边赋值..../***@param{number[]}nums1*@param{number}m*@param{number[]}nums2*@param{number}n*@return{void}Donotreturnanything,modifynums1in-placeinstead.......
  • P3688 [ZJOI2017] 树状数组 题解
    P3688[ZJOI2017]树状数组题解记录一下做这道题的心路历程,说明在没有事先知道“九条是求成了后缀和”的情况下如何发现,以及解释一些部分分的做法。sub1,18pts:暴力搜索无脑枚举,复杂度\(\mathcalO(n^m)\)。代码:#include<bits/stdc++.h>#defineintlonglong#defineloop......
  • AT_arc151 题解 & 数组字典序大小比较求方案数
    很好的一题,做的时候没有一点思路,看了题解。看来做过的题目还是太少了,记录一下经验。注意到$1\leN\le2\times10^5$和$1\leM\le10^9$,如此庞大的数据,dp是肯定不行的。当字典序$A<B$时,当且仅当存在$i$,使得$\forallx\in[1,i)$,$A_x=B_x$且$A_i<B_i$。那么我们对于$......
  • 洛谷P1032 [NOIP2002 提高组] 字串变换
    ac代码:#include<bits/stdc++.h>usingnamespacestd;constintN=15;structnode{ stringstr; intstep;};stringa,b;stringorginal[N];stringtranslated[N];intn,ans;map<string,int>ma;stringtrans(conststring&str,inti,i......
  • C语言习题--程序改错
     1.待修改代码#include<stdio.h>#include<stdlib.h>#include<string.h>intmain(){ char*src="hello,world"; char*dest=NULL; intlen=strlen(src); dest=(char*)malloc(len); ch......
  • 章10——面向对象编程(高级部分)——抽象类
    介绍更多意义在于其设计意义。供子类参考的一个模板。注意细节final、private、static与重写矛盾,不可与abstract共用!补充说明static方法可以被继承,不可以被重写,若父子方法名相同,则会隐藏derive类派生类方法,调用base类基类方法。静态方法时编译时绑定的,而方法重写是运行时......