第五章 数组

news2024/9/20 14:57:34

定义

数组是一组相同类型元素的集合,但我们需要创建多个相同类型的变量时,只需要创建一个类型的数组,就相当于同时创建很多相同类型的变量。


一维数组

数组如何创建

从定义来入手看一下数组的创建:

type_t arr_name[const_n];
  • type_t是指元素的类型;
  • arr_name是数组名;
  • const_n是一个常量表达式,用来指定数组的大小;

可以简易为:
元素类型 数组名[元素个数]
eg:

int arr[10] 

意思是:创建一个名为arr数组,数组中存储着10个元素,每个元素类型为int类型

变长数组

在创建数组时候,我们可能会想过使用以下方法创建数组

int n=10;
int arr[n];

当然这种方法是不可行的
原因:在c99标准之前,数组的大小只能是常量表达式,在c99标准中引入了变长数组的概念,使得数组的大小可以是变量,但这样的数组不能初始化,vs2019或vs2022这样的编译器(IDE)不支持c99中变长数组,但gcc编译器可以。

数组初始化

一维数组在创建时 ,未给出确定的数组大小值,则该数组必须得初始化,数组的大小根据初始的内容来确定。故数组的初始化是指,在创建数组的同时给数组的内容一些合理的初始值。

用法示例

   int arr1[10] = { 1 };
   int arr2[] = { 1,2,3,4 };
   int arr3[5] = { 1,2,3,4,5 };
   char arr4[3] = { 'a',98,'c' };
   char arr5[] = { 'a','b','c' };
   char arr6[] = "abcdef";

一维数组的使用

  • 我们一般使用操作符:[ ] (下标引用操作符)来对数组中的某个位置的元素进行访问;
  • 数组元素的下标是从0开始

用法示例

从键盘输入十个数,并将他们打印在屏幕上

#include<stdio.h>
int main()
{
   int arr[10] = { 0 };
   int sz = sizeof(arr) / sizeof(arr[0]);
   int i = 0;
   for (i = 0; i < sz; i++)
   	scanf("%d", &arr[i]);
   for (i = 0; i < sz; i++)
   	printf("%d ", arr[i]);
   return 0;
}

我们一般用关键字sizeof来求数组的长度

  • sizeof(arr)表示整个数组的大小
  • sizeof(arr[0])表示计算数组中首元素的大小,即每个元素的大小
  • 数组元素个数=数组总大小/数组每个元素大小

一维数组的存储

数组在内存中是怎样存储的呢?我们先来看一段代码:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
		printf("&arr[%d]=%p\n", i, &arr[i]);
	return 0;
}

注意:%p是打印地址的格式输出符号
这段代码是将数组每个元素的地址打印出来,结果如下:
在这里插入图片描述
由结果而知,随着数组下标的增长,元素的地址是在由规律的递增,并且相邻元素地址相差4,正好是一个int类型的大小,所以我们得知,数组在内存中是连续存放的。


二维数组

二维数组的创建

二维数组的创建与一维数组非常相似

type_t arr_name[row][col];
  • type_t是指元素的类型;
  • arr_name是数组名;
  • row是一个常量表达式,用来指定数组的行数;
  • col是一个常量表达式,用来指定数组的列数;

用法示例

int arr[3][4];//创建一个3行4列的整形二维数组
char arr1[3][5];//创建一个3行5列的字符二维数组
double arr3[2][4];//创建一个2行4列的浮点型二维数组

二维数组的初始化

//数组初始化
int arr[3][4] = {1,2,3,4};//将第一行赋值1,2,3,4,其余行的数默认为0;
//表示第1行{1,2},第2行{4,5}
//最终效果:
//1 2 0 0
//4 5 0 0
//0 0 0 0
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略
  • 数组的不完全初始化,其他内容默认为0
  • 二维数组初始化时,行可以省略,列不能省略

二维数组的使用

二维数组的访问用 数组名[行][列] 的形式

用法示例

#include<stdio.h>
int main()
{
	int arr[3][5];
	int i = 0, j = 0;
	for (i =0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			arr[i][j] = 3 * i + 5 * j;
		}
	}
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

二维数组的存储

像之前一样,通过打印各个元素的地址来观察一下:

#include<stdio.h>
int main()
{
	int arr[3][4];
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("&arr[%d][%d]=%p\n", i, j, &arr[i][j]);
		}
	}
	return 0;
}

在这里插入图片描述
通过观察发现:

  • 二维数组每行元素里相邻元素地址相差4,刚好为一个int类型大小
  • 每行最后一个元素与下一行第一个元素地址也相差4
    由此可见,二维数组和一维数组一样,在内存中也是连续存储的。

数组的越界访问

我们在创建数组时候,都知道下标是由范围限制的。

  • 数组的下标规定是从0开始,如果数组由n个数组组成,那么元素的下标范围就是0到-1
  • 所以当数组的下标小于0或者大于n-1,就是数组越界访问,超出了数组合法空间的访问

注意:C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的。

数组越界的例子

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i <= 10; i++)
		printf("%d\n", arr[i]);//当i等于10的时候,越界访问
	return 0;
}

数组越界访问,我们无法知道越界访问的空间是否存在危险,也无法预料产生的其他后果。

数组作为函数参数

  • 通常情况下,数组名是首元素地址
  • sizeof(数组名):计算的是整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组
  • &数组名:取出的是数组的地址,&数组名,数组名表示整个数组
#include<stdio.h>
int main()
{
	int arr[5] = { 0,1,2,3,4 };
	printf("  arr=%p\n", arr);
	printf("arr+1=%p\n", arr + 1);
	printf("\n");
	printf("  &arr[0]=%p\n", &arr[0]);
	printf("&arr[0]+1=%p\n", &arr[0] + 1);
	printf("\n");
	printf("  &arr=%p\n", &arr);
	printf("&arr+1=%p\n", &arr + 1);
	return 0;
}

在这里插入图片描述

冒泡排序

适用条件:整型数组进行升序排序

用法示例

错误示例

#include <stdio.h>
void bubble_sort(int arr[])
{
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 5,3,7,6,1,8,9,2,4,0 };
	bubble_sort(arr);
    int i = 0;
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

这段代码星相信很多小伙伴看不出什么问题,但是运行结果时却是错误的,原因就在于sizeof(arr)计算的是数组的大小,而将arr传递进函数内部时,arr就不再时一个数组,而是一个地址,也就是数组首地址,所以我们用sizeof计算一个地址大小时,会产生很大的误差。

正确示例

#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 5,3,7,6,1,8,9,2,4,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	bubble_sort(arr, sz);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

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

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

相关文章

《向量数据库指南》——FAISS和Chroma:两种流行的向量数据库的比较

目录 FAISS Chroma 比较 向量数据库是一种可以存储和检索高维向量数据的数据库,高维向量数据是一种可以表示任何类型数据的A.I原生方式,比如文本、图像、音频等。向量数据库可以用于实现各种基于相似度搜索和聚类的A.I应用,比如语义搜索、推荐系统、图像识别等。在本文中…

Spring Boot——Spring Boot自动配置原理

系列文章目录 Spring Boot启动原理 Spring Boot自动配置原理 系列文章目录前言一、Spring Boot自动配置原理剖析二、自动配置生效三、总结&#xff1a; 前言 一直在使用Spring Boot特别好奇的是为什么Spring Boot比Spring在项目构建和开发过程中要方便很多&#xff0c;无需编…

二叉树的层序遍历(两种方法:迭代+递归)

题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]] 解题思路&#xff1a;迭代法…

【设计模式——学习笔记】23种设计模式——组合模式Composite(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 学校院系展示 编写程序展示一个学校院系结构: 需求是这样&#xff0c;要在一个页面中展示出学校的院系组成&#xff0c;一个学校有多个学院&#xff0c;一个学院有多个系 【传统方式】 将学院看做是学校的子类&#xff0c;系是学院的子类&#xff0c;小的组织继承大…

位1的个数,编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1‘ 的个数(也被称为汉明重量)。

题记&#xff1a; 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为汉明重量&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff…

MySQL使用xtrabackup备份和恢复教程

1、xtrabackup说明 xtrabackup是percona开源的mysql物理备份工具。 xtrabackup 8.0支持mysql 8.0版本的备份和恢复。 xtrabackup 2.4支持mysql 5.7及以下版本的备份和恢复。 这里我以xtrabackup 8.0为例讲解备份和恢复的具体操作方法。 xtrabackup 2.4版本的使用上和8.0版本相…

PX4从放弃到精通(二十九):传感器冗余机制

文章目录 前言一、parametersUpdate二、imuPoll三、 put四、 confidence五、 get_best 前言 PX4 1.13.2 一个人可以走的更快&#xff0c;一群人才能走的更远&#xff0c;可加文章底部微信名片 代码的位置如下 PX4冗余机制主要通过传感读数错误计数和传感器的优先级进行选优 …

解决[Vue Router warn]: No match found for location with path “/day“问题

首先是升级vue-router4.0后会警告[Vue Router warn]: No match found for location with path "/day" 找了许久解决方案如下&#xff1a; 一、404页面不需要再异步路由后边添加&#xff0c;直接放到静态路由里即可 二、要注意不能写name&#xff0c;否则会刷新默认…

Parameter ‘roleList‘ not found.

Parameter roleList not found. Available parameters are [arg1, arg0, param1, param2] 多半是Mapper层传入多个参数的时候&#xff0c;没有加Param注解&#xff0c;导致BindException错误

ORA-01187 ORA-01110

ORA-01187: cannot read from file because it failed verification tests ORA-01110: data file 201: ‘/u01/app/oracle/oradata/CNDB/temp01.dbf’ 查询临时文件是存在的 重建临时数据文件 删除临时文件&#xff1a; alter database tempfile /u01/app/oracle/oradata…

56. 合并区间 排序

Problem: 56. 合并区间 文章目录 思路Code 思路 对数组排序&#xff0c;按照左端点从小到大排序。初始化Merged&#xff0c;将第一个区间放入。遍历intervals ,如果当前区间的左端点比merged最后一个区间的右端点大&#xff0c;不重合&#xff0c;直接将该区间加入最后&#xf…

《零基础入门学习Python》第070讲:GUI的终极选择:Tkinter7

上节课我们介绍了Text组件的Indexs 索引和 Marks 标记&#xff0c;它们主要是用于定位&#xff0c;Marks 可以看做是特殊的 Indexs&#xff0c;但是它们又不是完全相同的&#xff0c;比如在默认情况下&#xff0c;你在Marks指定的位置中插入数据&#xff0c;Marks 的位置会自动…

指针的基础应用(数组的颠倒和排序,二维数组的表示)

1.数组的颠倒&#xff1a;若有10个数字&#xff0c;那么数组的颠倒即 a[0]与a[9]交换,a[1]与a[8]交换&#xff0c;a[2]与a[7]交换&#xff0c;......a[4]与a[5]交换&#xff0c;所以到a[4]就颠倒完毕&#xff0c;即 (n-1)/2 若不用指针代码如下 #include<stdio.h>voi…

交互式AI技术与模型部署:使用Gradio完成一项简单的交互式界面

下面的这段代码使用Gradio库创建了一个简单的交互式界面。用户可以输入名称、选择是早上还是晚上、拖动滑动条来选择温度&#xff0c;然后点击"Launch"按钮&#xff0c;界面会显示相应的问候语和摄氏度温度。例如&#xff0c;如果用户输入"John"&#xff0…

iperf3 编译安装及网讯WX1860千兆网口测试

iperf3 编译安装及网讯1860千兆网口测试 编译安装 安装包下载地址:https://github.com/esnet/iperf/archive/refs/tags/3.8.tar.gz 将安装包iperf-3.8.tar.gz拷贝测试系统盘桌面,使用如下命令进行编译安装: tar zxvf iperf-3.8.tar.gz cd iperf-3.8 ./configure make s…

LeetCode-222-完全二叉树的节点个数

一&#xff1a;题目描述&#xff1a; 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#xff0c;并且最下面一层的节…

点餐系统测试报告

文章目录 一、项目介绍项目简介功能介绍 二、测试计划1 功能测试功能测试用例发现的 BUG 和 解决方法注册功能上传图片功能 2 自动化测试3 性能测试 一、项目介绍 项目简介 该项目是一个门店点餐系统&#xff0c;采用前后端分离的方式实现&#xff0c;后端框架是SSM&#xff…

R-并行计算

本文介绍在计算机多核上通过parallel包进行并行计算。 并行计算运算步骤&#xff1a; 加载并行计算包&#xff0c;如library(parallel)。创建几个“workers”,通常一个workers一个核&#xff08;core&#xff09;&#xff1b;这些workers什么都不知道&#xff0c;它们的全局环…

第一次后端复习整理(JVM、Redis、反射)

1. JVM 文章仅为自身笔记 详情查看一篇文章掌握整个JVM&#xff0c;JVM超详细解析&#xff01;&#xff01;&#xff01; 1.1 什么是JVM jvm是Java虚拟机 1.2 Java文件的编译过程 程序员编写代码形成.java文件经过javac编译成.class文件再通过JVM的类加载器进入运行时数据…

Java云电子病历源码:电子病历在线编辑

SaaS模式Java版云HIS系统的子系统云电子病历系统源码&#xff0c;本系统采用前后端分离模式开发和部署&#xff0c;支持电子病历四级。 电子病历系统主要为医院住院部提供医疗记录依据&#xff0c;协助医务人员在医疗活动过程中通过信息化手段生成的文字、图表、图形、数据、影…