当前位置: 首页 > news >正文

7.数组(一维数组、二维数组、C99中的变长数组、二分查找法)

数组

    • 1.数组的概念
    • 2.一维数组
      • 2.1 一维数组的创建
      • 2.2 一维数组的类型
      • 2.3 一维数组的初始化
      • 2.4 一维数组的下标
      • 2.5 一维数组的输入与输出
      • 2.6 一维数组在内存中的存储
      • 2.7 利用sizeof()计算数组元素的个数
    • 3.二维数组
      • 3.1 二维数组的概念
      • 3.2 二维数组的创建
      • 3.3 二维数组的初始化
      • 3.4 二维数组的下标
      • 3.5 二维数组的输入与输出
      • 3.6 二维数组在内存中的存储
    • 3.C99中的变长数组
    • 4.二分查找法(也称折半查找法)

1.数组的概念

数组是一组相同类型元素的集合,其特点有
1.数组存放的是1个或者多个数据,但是数组元素个数不能为0
2.数组中存放的多个数据,类型是相同的
数组分为一维数组和多维数组,多为数组一般以二维数组为主。

2.一维数组

2.1 一维数组的创建

格式:数据类型 数组名[常量值];
例 int num[10];

2.2 一维数组的类型

去掉数组名剩下的就是数组类型,例 int num[10]; 其数组类型为int [10]
数组元素的数据类型 可以是char、int、float等 数组内的元素数据类型都相同

2.3 一维数组的初始化

//完全初始化
int num[5] = {1,2,3,4,5};//不完全初始化,除了1 2 3,剩下的其余元素都默认为0
int num[5] = {1,2,3};//初始化1 2 3,长度也为3
int num[] = {1,2,3};

2.4 一维数组的下标

在C语⾔中数组的访问提供了⼀个操作符[ ] ,这个操作符叫:下标引用操作符
注意区分 定义数组时 和 调用数组元素时 [ ] 内常量的区别
定义时里面的常量表示元素的个数
调用时里面的常量表示数组下标,也就是索引位
数组下标是从0开始数起的
在这里插入图片描述

举例:

//注意区分 定义数组时 和 访问数组元素时 []的区别
int num[5] = {1,2,3,4,5};//这里num[5]表示的是数组长度为5
printf("数组下标为4的值:%d", num[4]);//这里num[4]表示的是访问数组下标为4的数组元素

输出结果
在这里插入图片描述

2.5 一维数组的输入与输出

输出

//输出
int main() {int arr[9] = {1,2,3,4,5,6,7,8,9};for (int i = 0; i < 9; i++)//这里小于9是因为长度为9的数组 下标范围为0~8{printf("arr[%d] = %d\n",i,arr[i]);}return 0;
}

输出结果
在这里插入图片描述


输入

//输入
int main() {int arr[9];for (int i = 0; i < 9; i++){scanf("%d",&arr[i]);}for (int i = 0; i < 9; i++)//这里小于9是因为长度为9的数组 下标范围为0~8{printf("arr[%d] = %d\n",i,arr[i]);}return 0;
}

输入结果
在这里插入图片描述

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

一维数组在内存中的存储地址,随着下标增长,由小变大
数组在内存中是连续存放的,以整型数组为例,每两个相邻的数组元素之间相差4(因为一个整型是4个字节)

int main() {int arr[9] = {1,2,3,4,5,6,7,8,9};for (int i = 0; i < 9; i++){printf("arr[%d] = %p\n",i,&arr[i]);}return 0;
}

输出结果(32位(x86)环境下)
在这里插入图片描述

16进制的形式表示内存中存储的地址,每个数据元素之间都差4,因为是int类型的数据元素

2.7 利用sizeof()计算数组元素的个数

sizeof()函数是C语言中的一个关键字
作用:计算类型或者变量的大小
单位是字节(byte)

因为数组中的所有元素的数据类型都是相同的,所以每个数据元素的大小相同
即:所占内存空间总大小 / 对应数组元素的数据类型 = 数组内元素的个数

int main() {int arr[10] = {0};//这里我们就非完全初始化数组,所以我们不知道数组有多少个元素个数printf("数组 int arr[10] 所占内存空间的总大小:%zd 字节\n",sizeof(arr));printf("数组 int arr[10] 其中一个数组元素所占内存空间的大小:%zd 字节\n",sizeof(arr[0]));//所占内存空间总大小 / 对应数组元素的数据类型 = 数组内元素的个数int sum = sizeof(arr) / sizeof(arr[0]);printf("数组中元素的个数:%d", sum);return 0;
}

输出结果
在这里插入图片描述

3.二维数组

3.1 二维数组的概念

二维数组:相当于把一维数组做为数组元素,此时就是二维数组
依此类推,三维数组就是二维数组被做为数组元素的数组
二维数组以上的数组都统称为多维数组

3.2 二维数组的创建

格式:数据类型 数组名[常量值1][常量值2];
例:
int num[10][10];
第一个10表示 数组有10行
第二个10表示 每一行有10个数组元素

3.3 二维数组的初始化

// 不完全初始化
int arr1[3][3] = {1,2,3};
int arr2[3][3] = {0};// 完全初始化
int arr3[3][3] = {1,2,3, 4,5,6, 7,8,9};//按照行初始化
int arr4[3][3] = {{1,2,3},{4,5,6},{7,8,9}};//初始化时可以省略行,但是不能省略列
int arr5[][3] = { 1,2 };
int arr6[][3] = { 1,2,3,4,5};
int arr7[][3] = { {1,2},{4,5},{7,8} };

3.4 二维数组的下标

二维数组中行的下标从0开始,列的坐标也是从0开始
初始化时可以省略行,但是不能省略列
int man[可以省略][不能省略];

3.5 二维数组的输入与输出

输入

	//输入for (int i = 0; i < 3; i++)//行号{for (int j = 0; j < 3; j++)//列号{scanf("%d ", &arr[i][j]);//记得加&}}

输出

	//输出for (int i = 0; i < 3; i++)//行号{for (int j = 0; j < 3; j++)//列号{printf("%d ", arr[i][j]);}printf("\n");}

3.6 二维数组在内存中的存储

二维数组每一行内部的每个元素都是相邻的
以整型为例
每两个相邻的数组元素之间相差4个字节(因为一个整型是4个字节)
跨行连接处的每个元素也都是只差4个字节,所以二维数组在内存中也是连续存放的

int main() {int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };for (int i = 0; i < 3; i++)//行号{for (int j = 0; j < 3; j++)//列号{printf("arr[%d][%d] = %p\n", i, j, &arr[i][j]);}printf("\n");}return 0;
}

输出结果
在这里插入图片描述

3.C99中的变长数组

在C99标准之前,C语言在创建数组的时候,数组大小必须得用常量或常量表达式来表示,或者初始化数组的时候省略数组大小,直接自己输入数组元素。

1.用常量来表示数组大小
int arr[5];
2.省略数组大小,开始直接自己输入元素
int arr[] = {1,2,3,4,5};

这样创建数组会带来非常大的限制,就是数组的大小无法灵活的变化,必须在开始的时候就写死数组的大小。

所有在C99中给定了一个变长数组(variable-length array,简称VLA) 的新特性,允许我们可以使用变量来创建数组大小。

//这样一来就可以根据输入的值来创建对应的大小的数组了
int n;
scanf("%d",&n)
int arr[n];

上述例子中arr为边长数组,它的数组大小取决于输入值n的大小,编译器无法提前确定数组大小,只有程序运行时,才能知道n是多少。(即变长数组的大小只有在运行时才能确定,所以变长数组也就不能初始化
好处:在开发程序时,不需要特地的去考虑定义数组的大小范围等,程序在运行时可以精确的根据对变量的赋值来分配数组的大小。
注意:程序运行时,根据变量的大小来分配数组的大小,数组的大小一旦被分配,就确定不再变化。(可变是指创建数组时的变量可变,不需要唯一固定值;而不是说能随意的改变数组的大小)


可惜的是在VS2022上支持大部分C99语法,但是VS中不支持C99中的变长数组

#include <stdio.h>
int main(){int n = 0;scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩int arr[n];int i = 0;for (i = 0; i < n; i++){scanf("%d", &arr[i]);}for (i = 0; i < n; i++){printf("%d ", arr[i]);}
return 0;
}

输入:
5
1 2 3 4 5

输出:
1 2 3 4 5

4.二分查找法(也称折半查找法)

拿传统的查找方法来作比较

就是从数组下标0的元素开始,逐次递增,来和要查找的数进行比较
缺点:如果要查找的数很大,上万上千,那么也要查找上万上千次;查找的数越大查找起来越费劲

//传统查找方式(麻烦,什么年代了还在用传统香。。。方法)
int main() {int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int k = 0;//要查找的数int count = 1;//查找次数scanf("%d", &k);int sz = sizeof(arr) / sizeof(arr[0]);//数组内元素个数int find = 0;//假设找不到int i = 0;//循环递增数组下标作比较for (i = 0; i < sz; i++){if (k == arr[i]) {printf("成功找到arr[%d]=%d,共查找了%d次", i,arr[i],count);find = 1;break;}count++;}if (find == 0){printf("查找了%d次,找不到",count);}return 0;
}

在这里插入图片描述


二分查找法

开始:
将列表的起始索引 low 设置为 0
将列表的结束索引 high 设置为数组长度减1循环条件为(low 小于等于 high):将中间索引 mid 设置为 (low + high) 的一半如果列表的mid下标对应的元素小于目标值:将 low 设置为 mid 加 1如果列表的mid下标对应的元素大于目标值:将 high 设置为 mid 减 1否则(也就是low 等于 high 时):mid 下标对应的元素 等于 目标值退出循环
//二分查找
int main() {int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int k = 0;//要查找的数scanf("%d", &k);int count = 1;//查找次数int find = 0;//假设找不到int sz = sizeof(arr) / sizeof(arr[0]);//数组内元素个数(组数长度)//low和high都是指下标位置int low = 0;int high = sz - 1;while (low <= high){int mid = (low + high) / 2;//以下方法为 int mid = low + high 的优化方法://之所以这么写是为了防止数据类型超出上限//int mid = low + (high - low)/2;if (arr[mid] < k){low = mid + 1;count++;}else if (arr[mid] > k) {high = mid - 1;count++;}else{printf("成功找到arr[%d]=%d,共查找了%d次", mid, arr[mid], count);find = 1;break;}}if (find == 0){printf("找不到");}return 0;
}

在这里插入图片描述

以int arr[] = { 1,2,3,4,5,6,7,8,9,10 };为例
虽然说传统查找方法6次 二分查找法3次差别不是特别大
但是随着数组的大小变大,二分查找的效率优势会越来越明显

相关文章:

7.数组(一维数组、二维数组、C99中的变长数组、二分查找法)

数组 1.数组的概念2.一维数组2.1 一维数组的创建2.2 一维数组的类型2.3 一维数组的初始化2.4 一维数组的下标2.5 一维数组的输入与输出2.6 一维数组在内存中的存储2.7 利用sizeof()计算数组元素的个数 3.二维数组3.1 二维数组的概念3.2 二维数组的创建3.3 二维数组的初始化3.4 …...

ubuntu服务器配置ftp服务

需求&#xff1a;配置ftp服务用于在windows电脑上直接浏览、下载、上传ubuntu服务器上的文件&#xff0c;用于文件共享&#xff0c;方便实用 效果&#xff1a;用户打开windows资源管理器后输入ftp://xxx.xxx.xxx.xxx &#xff08;公网IP地址&#xff09;后&#xff0c;即可浏览…...

IDA+Frida分析CTF样本和Frid源码和objection模块

文章目录 一些资料IDA调试命令IDA调试安卓的10个技巧objection基本使用 Wallbreaker1frida源码阅读之frida-java 第一个实例EasyJNI第二个实例objection资料 art_trace2.pyart_trace2.js IDAFrida分析CTF样本和Frid源码和objection模块 一些资料 IDA调试命令 adb devices adb…...

ConCurrentHashMap常见面试题

1. JDK1.7和JDK1.8中ConCurrentHashMap的实现有什么不同&#xff1f; JDK1.7中的实现可以认为是大数组套小数组&#xff0c;大数组是Segment数组&#xff0c;小数组是HashEntry数组&#xff0c;锁是锁在大数组的元素上&#xff08;Segment&#xff09;&#xff0c;力度比较大&…...

mysql数据备份并重置

mysql数据备份并重置 1.备份mysql数据 mysqldump -uroot --single-transaction -R -E --databases lc2 cpm a10_goods self_warehouse > /mnt/vdc1/var/lib/mysql/datadir/lc2_cpm_a10_goods_self_warehouse.sql -p Y6B2wb 2.初始化mysql mysqld --initialize; 3.修改配…...

I- yh的线段(2023河南萌新联赛第(四)场:河南大学)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 yh喜欢好线段&#xff0c;好线段即两条线段相交且不与其他线段重合的线段。 两条线段[l1,r1]和[l2,r2]相交(如果存在至少一个x&#xff0c;使得l1≤x≤r1和l2≤x≤r2&#xff0c;则认为两个线段…...

python与深度学习(十四):CNN和IKUN模型二

目录 1. 说明2. IKUN模型的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…...

chrome扩展在popup、background、content之间通信解决传输文件问题

文章目录 背景介绍案例介绍代码示例popup页面&#xff0c;上传文件页面popup页面&#xff0c;js上传代码&#xff0c;file文件转base64background监听消息&#xff0c;base64转file文件&#xff0c;axios上传 附-转base64后直接下载 背景介绍 示例扩展API版本MV2。 以弹…...

Oracle获取创建对象的DDL脚本

Oracle获取创建对象的DDL脚本 Oracle获取创建对象的DDL脚本查看 dbms_metadata.get_ddl()函数的定义 Oracle获取创建对象的DDL脚本 例如&#xff0c;对tzq schema下的表 test2&#xff0c;查看DDL脚本的SQL如下&#xff1a; SELECT SELECT dbms_metadata.get_ddl(upper(table…...

《算法竞赛·快冲300题》每日一题:“01树”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 0…...

Mac提示文件:已损坏,无法打开。你应该把它移到废纸篓

文章目录 一、电脑信息二、打开任何来源设置三、更改应用程序拓展属性 一、电脑信息 我的是新版的Venture 13的系统。UI改的比较多。与之前的配置还是有很大的区别的。 打开下载的软件&#xff0c;显示已经损坏&#xff0c;打不开。抛开软件本身的问题外&#xff0c;一般是Ma…...

探索嵌入式系统:从入门到实践

随着科技的飞速发展&#xff0c;嵌入式系统已经成为了我们生活中不可或缺的一部分。从智能手机、智能家居到工业自动化设备&#xff0c;嵌入式系统的应用已经渗透到了各个领域。那么&#xff0c;如何学习嵌入式系统呢&#xff1f;本文将从入门到实践&#xff0c;为你详细解答。…...

网络安全知识点整理(作业2)

目录 一、js函数声明->function 第一种 第二种 第三种 二、this关键字 this使用场合 1.全局环境 2.构造函数 3.对象的方法 避免多层this 三、js的同步与异步 定时器 setTimeout和setInterval 同步与异步的例子 四、宏任务与微任务 分辨宏任务与微任务 一、js…...

idea数据库快速上手-库操作与表结构和数据操作

引言 对数据库的操作无非就是执行SQL语句&#xff0c;要想熟练操作数据库&#xff0c;就要熟练运用SQL语句。 一&#xff0c;数据库操作 展示当前服务器内的数据库 -- 展示服务器内的数据库 show databases; show schemas; 执行结果&#xff1a; 创建数据库&#xff1a; --…...

当“国潮”遇见“双语” 以传承之心种下一颗文化的种子

看&#xff0c;活灵活现的纸片人在“跳舞”。光影的辉映下&#xff0c;两个形神兼备的“齐天大圣”究竟孰真孰假&#xff1f;舞台上&#xff0c;京西皮影非遗传承人王熙和5岁的Mona小朋友正在用双语为大家带来一段“真假美猴王”的好戏。生动的皮影造型和精彩的故事演绎看得台下…...

计划管理与项目管理:有何区别?

简而言之&#xff0c;是的。尽管它们经常互换使用并对全局产生影响&#xff0c;但它们是完全不同的。 在本文中&#xff0c;我们将了解计划和项目管理之间的差异&#xff0c;提供每个示例&#xff0c;并向您展示如何使计划和项目管理工作更有效地实现您的业务目标。 计划管理与…...

个人信息保护合规审计如何做?

8月3日&#xff0c;为指导、规范个人信息保护合规审计活动&#xff0c;根据《中华人民共和国个人信息保护法》等法律法规&#xff0c;国家互联网信息办公室就《个人信息保护合规审计管理办法&#xff08;征求意见稿&#xff09;》&#xff08;简称《办法》&#xff09;及配套的…...

HTTP杂谈之Referer和Origin请求头再探

一 关于Referer和Origin的汇总 1) 知识是凌乱的,各位看官看个热闹即可2) 内容不断更新1、理解有盲区,需要及时纠正2、内容交叉有重复,需要适当删减3、扩展视野3) 以下内容都与Referer和Origin请求头有关联 nginx防盗链 HTTP杂谈之Referrer-Policy响应头 iframe标签referre…...

数学建模-爬虫入门

Python快速入门 简单易懂Python入门 爬虫流程 获取网页内容&#xff1a;HTTP请求解析网页内容&#xff1a;Requst库、HTML结果、Beautiful Soup库储存和分析数据 什么是HTTP请求和响应 如何用Python Requests发送请求 下载pip macos系统下载&#xff1a;pip3 install req…...

HSRM各表

文章目录 表规则接口种类服务与网关路由菜单一、采购申请1、采购申请—查询2、采购申请-操作记录二、采购申请跟踪报表1、采购申请跟踪报表—列表查询三、寻源1、寻源大厅—列表查询2、寻源大厅—询价单明细3、寻源大厅—物料明细4、寻源大厅—供应商列表5、寻源模板—列表查询…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...