【逐步剖C】第三章-数组

news2024/11/14 18:33:28

一、一维数组

1. 一维数组的定义与使用

  • (1)数组的简单概念:一组具有相同类型的元素的集合

  • (2)数组的创建:
    格式:类型名+数组名+[数组大小]
    需要注意的是:对多数情况而言,在指定的数组大小时,需要用常量表达式。
    (PS:若编译器支持C99,则可使用变量来指定数组的大小(即变长数组);但变长数组有一些限制:变长数组必须是自动存储类的,意味着它们必须在函数内部或作为函数参数声明,而且声明时不可以进行初始化。)
    数组的大小可以省略,但若想省略则必须在创建时就对其进行初始化。

  • (3)数组的初始化:
    和变量的初始化类似,在创建它的时候赋予它一些合理的值
    一般的初始化形式:数组名[数组大小]={…}
    数组的下标是从0开始的,故需根据实际需求正确指定数组的大小
    若数组的大小省略,则数组会根据初始化的内容来确定数组的大小
    如:int arr[]={1,2,3};
    数组arr的大小就为3个整型变量的大小
    若数组的初始化部分即{ }中的元素达不到数组的大小时,相应没有指定初始化的地方自动初始化为零,称为数组的不完全初始化
    如:int arr[3] = {1};
    此时数组中对应的元素为 arr[0] = 1; arr[1] = 0; arr[2] = 0

故常通过如下面这段代码来实现对数组每个元素赋0的初始化:

int arr[10] = {0};

对于作为全局变量的数组 ,其元素默认初始化为0

  • (4)一维数组的使用:通过下标引用操作符[ ]来实现对每个元素的访问
arr[2] = 2;
//将数组的第三个元素赋值为2
  • (5) 可通过sizeof来计算数组的长度
int len = sizeof(arr)/sizeof(arr[0]);
  • (6)易踩坑点:用数组存储字符串的初始化

时刻要在脑海中的一个知识点字符串的最后一个字符是‘\0’,这也是函数对字符串进行操作的标志,如strlen strcmp等。故在用数组进行字符串的存储时,一定要考虑到 \0 而正确指定数组的大小

如下代码:

char arr[3] = { "abc"};

将其打印出来的结果是:
​​​​在这里插入图片描述
解释:此时数组的情况是arr[0] = ‘a’; arr[1] = ‘b’; arr[2] = ‘c’; 而‘\0’ 并没有被随着字符串存储到数组当中,故在对其进行打印操作时,找不到结束的标志, 在打印完abc后又打印了乱码

结论:对字符串来说,其长度就为组成它的字符个数,如上字符串“abc”的长度就是3,而对数组来说,还要另将字符串的结束标志 \0考虑进去。通过如下代码加深印象:

int main()
{
	char arr1[3] = { "abc"};
	char arr2[3] = { 'a','b','c' };
	char arr3[4] = { 'a','b','c','\0' };
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);
	return 0;
}

打印结果:
在这里插入图片描述

2. 一维数组在内存中的存储

先说结论数组在内存中是连续存放的,且是从低地址到高地址,即随着下标的增长,其每个元素的地址也在有规律地递增。
如下代码展示:

#include<stdio.h>
int main()
{
	int arr[5] = { 0 };
	int len = sizeof(arr) / sizeof(arr[0]);
//上面说的计算数组长度的方法
	int i = 0;
	for (i = 0; i < len; i++)
		printf("%p\n", &arr[i]);
	return 0;
}

运行结果:
在这里插入图片描述

二、二维数组

1. 二维数组的创建和使用

  • (1)格式:
int arr [rows] [cols];

同一维数组, [ ] 中为常量表达式

  • (2)初始化:
int arr[2][2] = {1,2};
//数组的第一行的一二列的初始化
int arr[2][2] = {{1},{2}};
//数组的第一列的一二行的初始化
int arr[][2] = {1,2};
//数组的省略初始化,但要注意行可以省略,但列不能省略
  • (3)使用:同一维数组,使用 [ ] 操作符进行访问。

2. 二维数组在内存中的存储

也和一维数组一样,按地址由高到低连续存放
(PS:其实所谓行和列只是我们的一种理解,其实二维数组的存放和一维数组一样是一整行的),如下图:

在这里插入图片描述
所以这里可以有一种理解方法:把对应行(如arr[0])看作是对应一维数组的数组名,而再通过操作符 [ ] 中的数字来访问这个一维数组的每一个元素。即把二维数组当一维数组来使用。如arr[0][1]就可以理解为访问的是一维数组arr[0]的第二个元素
这里我们同样可以通过sizeof来对二维数组进行一些运算:

//计算二维数组的行数:
sizeof(arr) / sizeof(arr[0])

//计算二维数组每行元素个数:
sizeof(arr[0]) / sizeof(arr[0][0])

三、补充知识

1.数组越界问题

所谓越界就是指访问的下标超过了数组的长度。需要注意的是C语言本身不做数组下标的越界检查,编译器也不一定报错,编译器不报错并不代表程序就本身是正确的。所以我们在写代码的时候一定要细心,写完后最好做一遍越界的检查。

2.数组作为函数参数

先说知识点:数组传参,本质上传的是数组首元素的地址。这里就不得不谈到数组名的问题。
数组名其实就代表着该数组首元素的地址,如下代码:

int arr[5] = { 1,2,3 };
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%d", *arr);

运行结果:
在这里插入图片描述
当然也有两个例外情况:

(1)用sizeof计算数组大小时,()中的数组名,代表的时整个数组。

(2)&数组名,其中的数组名也表示整个数组,这个操作指的是取出整个数组的地址(到指针总结时会更详细说明)

3. 对数组类型的理解:

int num = 10;

对于变量num而言, int 就是它的类型(即去掉变量名)
可以得到 sizeof(int) == sizeof(num)
对于数组而言其实是同样的道理:

int arr[10];

对于上面这个数组arr而言呢,int[10] 就是它的类型(即去掉数组名)
同理也有:sizeof(int[10]) == sizeof(arr)

4. 数组作为函数参数的重要实例:冒泡排序

补充:冒泡排序的主要思想是:相邻两数进行对比,若不符合想要实现的序列(升序或降序),则两数进行交换
先来个错误的函数例子,好涨记性:

void bubble_sort(int arr[])
{
 int len = sizeof(arr)/sizeof(arr[0]);
//这里想求数组长度,但调试发现结果不符合预期
    int i = 0;
 for(i=0; i<len-1; i++)
   {
        int j = 0;
        for(j=0; j<len-i-1; j++)
       {
            if(arr[j] > arr[j+1])
           {
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
           }
       }
   }
}

结果为1的原因:上面说过,用sizeof计算数组长度时()中的数组名表示整个数组,或着说应当为整个数组的地址,而数组传参本质上传的是数组首元素的地址,而地址的大小,在32位机上位4个字节,在64位机上为8个字节,又因为该数组为整型数组,其元素的类型大小为4个字节,故最终的len的值只可能是2或1。

解决办法:数组长度在外面算好后,再传进去

改正并通过flag优化后的完成冒泡排序程序如下:

void bubble_sort(int arr[], int n)
{
	int i, j;
	int tmp = 0;
	for (i = 0; i < n - 1; i++)		//趟数,即有多少个数需要被处理
	{
		int flag = 1;		
		for (j = 0; j < n - 1 - i; j++)		//对换次数,即一趟需对换多少次
		{
			if (arr[j] > arr[j + 1])		//本质上是想让不满足既定有序条件的两个数对换
			{
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;				//当i=1时,5和4就已发生对换,整个数组已经有序									
			}
		}
		if (flag == 1)
			break;
	}
}

对flag优化的解释:利用flag可以减少趟数,优化代码(用来解决可能提前排序完成的情况)(即已经有序了)。因为n-1趟的规律是在完全倒序情况下总结的,即数组为9,8,7…,但实际上数组可能只需一趟就完成了排序
如1,2,3,5,4。
如果没有flag的话,代码依然会按照n-1趟来判断,一些过程就重复了。
flag可以理解为是一个检测有序的标志
结合代码理解:如上例{1,2,3,5,4},第一趟4和5发生对换,对换后数组已经有序,此时进行下一趟排序时,内循环中的交换将一次都不进行,也就是flag的值不会被置为0,内循环结束时,flag的值仍为1,这就代表着数组已经有序,就可以跳出循环了。

以上就是我对数组这一部分知识的总结啦。

看完觉得有觉得帮助的话不妨点赞收藏鼓励一下,有疑问或有误地方的地方还恳请过路的朋友们留个评论,多多指点,谢谢朋友们🌹🌹🌹!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/196288.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

# Vue中的Mixin混入

Vue中的Mixin混入 将组件的公共逻辑或者配置提取出来&#xff0c;哪个组件需要用到时&#xff0c;直接将提取的这部分混入到组件内部即可。这样既可以减少代码冗余度&#xff0c;也可以让后期维护起来更加容易。 1. 什么是Mixin&#xff1f; 混入 (mixin) 混入 (mixin) 将组…

数据库分类

关系型与非关系型 关系数据库 MySQL、MariaDB&#xff08;MySQL的代替品&#xff09;、 Percona Server&#xff08;MySQL的代替品&#xff09;、PostgreSQL、 Microsoft Access、Google Fusion Tables、SQLite、DB2、FileMaker、Oracle、SQL Server、INFORMIX、Sybase、dBASE…

阿里云中间件2024届校园招聘

【团队介绍】 阿里云云原生中间件团队负责分布式软件基础设施&#xff0c;为阿里云上万家企业提供如微服务引擎、服务网格、消息服务、分布式事务等分布式基础服务&#xff0c;加速企业上云的进程和创新速度。同时&#xff0c;云原生中间件团队也服务着阿里集团众多核心业务和…

智能指针(三)—— shared_ptr 循环引用问题

shared_ptr 作为智能指针&#xff0c;可以满足大多数场景&#xff0c;对于一些特殊情况&#xff0c;可能会引发循环引用问题。 目录 1、循环引用案例分析 (1) 案例介绍 (2) 原因分析 2、weak_ptr 解决循环引用 1、循环引用案例分析 (1) 案例介绍 我们通过实际案例来了解…

网络编程 1 相关基础概念 及 请求、响应类 定义

目录 一、HTTP基本概念 1、HTTP是什么 2、HTTP客户端是什么 3、HTTP消息结构 4、服务器响应信息 二、相关概念 1、网址 URL 2、IP地址 3、域名 4、域名与IP关系 5、域名解析 6、DNS 三、设计请求、响应类基本数据结构 1、请求类定义 2、响应类定义 一、HTTP基本概…

AD引脚交换

19年写过一篇AD交换引脚的文章&#xff0c;原文请查阅AD18调PIN方法及注意事项&#xff0c;该方法是手动更改焊盘的网络&#xff0c;如果是对于少量的或者零散的引脚交换还好&#xff0c;但遇到像FPGA、CPLD或者端子这种大量引脚需要调PIN的情况还是一个一个手动更改就很费时了…

java 微服务 RabbitMQ高级 消息可靠性问题 死信交换机 延迟队列 惰性队列

消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; 1.消息可靠性问题&#xff08;面试很会问&#xff09; 针对这些问题&#xff0c;RabbitMQ分别给出了解决方案&#xff1a; 生产者确认机制 mq持久化 消费者确认机制 失败重试机制 下面我们就通过案…

基于Android的办公用品管理平台的设计与实现

需求信息&#xff1a; 教师端&#xff1a; &#xff08;1&#xff09;注册登录&#xff1a;教师通过输入自己的工号和密码登录系统&#xff1b; &#xff08;2&#xff09;信息修改&#xff1a;教师可以完善个人信息&#xff08;院系、职务等&#xff09;&#xff1b; &#xf…

DMS感知方案前装赛道「排位」,2025年750万辆市场争夺

对舱内驾驶员、乘客的关怀&#xff0c;正在成为车企新一轮体验升级的关键突破口。在2023年CES展上&#xff0c;类似的产品方案也成为汽车行业的焦点。 比如&#xff0c;一家名为Myant的创新材料技术公司&#xff0c;在今年CES期间推出了一款将传感器和执行器&#xff08;与编织…

深度解刨性能测试工具Locust

An open source load testing tool. 一个开源性能测试工具。 define user behaviour with python code, and swarm your system with millions of simultaneous users. 使用Python代码来定义用户行为。用它可以模拟百万计的并发用户访问你的系统。 如果你常关注我的博客&…

2022尚硅谷SSM框架跟学(十)SSM整合

2022尚硅谷SSM框架跟学 十 SSM整合四、SSM整合4.1ContextLoaderListener(1).创建Maven Module(2).导入依赖(3).配置web.xml(4).创建SpringMVC的配置文件并配置(5).创建Spring的配置文件并配置(6).创建组件(7).创建页面(8).访问测试功能4.2准备工作(1).创建Maven Module(2).导入…

【2023亲测可用】JS 获取电脑本地IP 和 电脑网络IP(外网IP|公网IP)

1、了解&#xff1a;电脑本地的IP地址&#xff08;内网IP&#xff09;和电脑本机在网络上的IP地址&#xff08;外网IP|公网IP&#xff09; 在运行窗口输入“cmd”&#xff0c;在弹出的界面里输入“ipconfig/all”。弹出的数据中&#xff0c;IPv4地址&#xff0c;就是电脑本地的…

使用Hadoop分析气象数据(附代码)

刚学了Hadoop&#xff0c;在网上找完整的分析使用过程进行练手观看。本文数据和方法均来自于大佬的使用Hadoop分析气象数据完整版&#xff08;附带完整代码&#xff09;&#xff08;侵删&#xff09; 文章目录1.获取数据1.1下载数据1.2 数据格式1.3 合并数据2.MapReduce处理数据…

01sklearn-机器学习的几种算法(附代码)

说明: 本篇文章主要写了机器学习的流程及一些常用的算法如: 贝叶斯,朴素贝叶斯,线性回归,决策树,随机森林,逻辑斯蒂回归,模型调优和特征工程等(都是使用python的sklearn库实现) 一、概述 二、 一、特征工程 在看下面的算法之前,我们要先对机器学习流程进行一下熟悉! 主要有…

代码随想录算法训练营第五十九天_第九章_动态规划 | 583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇

LeetCode 583. 两个字符串的删除操作 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 视频讲解https://www.bilibili.com/video/BV1we4y157wB/?spm_id_from333.788&vd_sourcef…

瑞斯拜词汇课第一讲

英语词汇 第一段 1、under the weather 身体不舒服 2、billion 十亿 3、suffer from 遭受 4、high blood pressure 高血压 high blood pressure 高血压 hypertension 高血压 hyper 紧张的5、take steps to do sth 采取措施做某事 take measures to 采取措施 take steps to …

NVME_PCIE_SATA_AHCI_M.2_2.5“

SATA和PCIe两个都是总线标准。它们是并列发展的关系&#xff0c;并不是谁取代谁的关系。 SATA&#xff1a;由IDE/PATA标准发展而来&#xff0c;主要用途是把存贮设备&#xff08;硬盘&#xff09;连接到主机&#xff08;主板&#xff09;。 SATA经历了如下版本&#xff1a; SA…

数影周报:小米汽车供应商被罚100万,1688延迟下线“1688买家旺旺”

本周看点&#xff1a;小米汽车供应商被罚100万&#xff1b;特斯拉将在硅谷招聘AI 人才&#xff1b;阳光出行等25款 App涉违规收集使用个人信息等&#xff1b;1688延迟于2月8日下线“1688买家旺旺”&#xff1b;微蚁科技完成数千万元B轮融资......数据安全那些事小米汽车供应商被…

机器学习实战教程(四):从特征分解到协方差矩阵:详细剖析和实现PCA算法

1. 协方差 概念 方差和标准差的原理和实例演示&#xff0c;请参考 方差 方差&#xff08;Variance&#xff09;是度量一组数据的分散程度。方差是各个样本与样本均值的差的平方和的均值&#xff1a; 标准差 标准差是数值分散的测量。 标准差的符号是 σ &#xff08;希腊…

【redis6】第十五章(应用问题解决)

缓存穿透 问题描述 key对应的数据在数据源并不存在&#xff0c;每次针对此key的请求从缓存获取不到&#xff0c;请求都会压到数据源&#xff0c;从而可能压垮数据源。比如用一个不存在的用户id获取用户信息&#xff0c;不论缓存还是数据库都没有&#xff0c;若黑客利用此漏洞…