【C生万物】 数组篇

news2024/11/19 20:17:49

欢迎来到 Claffic 的博客 💞💞💞

 

前言: 

这个专栏好久没更新了,今日诗兴大发,打算尽快完成这个专栏,这期讲数组。


目录

Part1:一维数组

1.创建

2.初始化

3.使用

4.在内存中的存储

Part2:二维数组

1.创建

2.初始化

3.使用

4.在内存中的存储

Part3:数组越界

Part4:数组作为函数参数

1.冒泡排序的错误设计

2.数组名?

3.冒泡排序错误更正

Part5:实战


Part1:一维数组

1.创建

数组是一组 相同类型元素的集合

数组的创建方式:

type_t arr_name [const_n]
//类型  数组名    元素个数

实例:

// 实例1
int arr1[10];

// 实例2  VS2022环境下不可正常创建
int count = 10;
int arr2[count]

// 实例3 
char arr3[10];
float arr4[1];
double arr5[15];
注: 数组创建,在 C99 标准之前, [ ] 中要给一个 常量 才可以,不能使用变量。在 C99 标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化。

2.初始化

数组的初始化就是在创建数组的同时附一些合理的初始值。

如:

int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
char arr4[3] = {'a',8, 'c'};// 8是int类型,不是char类型,不符合规则
char arr5[] = {'a','b','c'};
char arr6[] = "abcdef";

指定大小:初始化内容数量不可超过指定大小;

不指定大小:元素个数根据初始化内容来确定。

3.使用

之前使用到的 [ ] 符号你可能不知道是什么意思,它叫做 下标引用操作符 ,用来访问数组中的元素。

说到下标,数组的下标是 从 0 开始 的,依次向后延续;

看下这段代码:

#include <stdio.h>
int main()
{
     int arr[10] = {0};//数组的初始化
     //计算数组的元素个数
     int sz = sizeof(arr)/sizeof(arr[0]);
     //对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
     int i = 0;//做下标
     // 循环操作,进行赋值
     for(i=0; i<10; i++)
     {
         arr[i] = i;
     } 
     //输出数组的内容
     for(i=0; i<10; ++i)
     {
         printf("%d ", arr[i]);
     }
     return 0;
}

总结:

• 数组可以使用下标来访问元素,下标从 0 开始;

• 数组的大小可以通过计算得到(使用sizeof函数)。

4.在内存中的存储

要观察数组在内存中的存储,不妨让计算机告诉我们:

#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;
}

输出结果:

地址一般是以十六进制展示的,可以观察到一个规律:相邻元素之间的地址相差4字节,且呈递增趋势;

而64进制下,一个指针的大小正好是4字节;

说明 数组中的元素是连续存储 的。

Part2:二维数组

1.创建

如果说一维数组是数轴,那么二维数组就是平面直角坐标系,有行有列。

实例:

//数组创建
int arr[3][5];
char arr[4][6];
double arr[2][4];

2.初始化

我们以常见的三种实例做解释:

int arr[3][4] = {1,2,3,4};
// 3行4列的二维数组,第一行初始化为 1,2,3,4 其余默认为0
// 1 2 3 4
// 0 0 0 0
// 0 0 0 0
int arr[3][4] = {{1,2},{4,5}};
// {}中的内容是一行的数字,数量不够为0
// 1 2 0 0
// 4 5 0 0
// 0 0 0 0
int arr[][4] = {{1,2},{3,4}};
// 二维数组初始化,行可以省略,列不能省略
// 1 2 0 0
// 3 4 0 0

3.使用

与一维数组相比,二维数组多了列,那么在赋值和打印的过程中,再嵌套一层循环即可:

int main()
{
	int arr[3][4] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			arr[i][j] = i * 4 + j;
		}
	}
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

输出结果:

0 1 2 3
4 5 6 7
8 9 10 11

4.在内存中的存储

同样的,让计算机告诉我们是如何存储的: 

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;
}

输出结果: 

与一维数组相同, 二维数组在内存中的存储也是连续 的。

Part3:数组越界

前面讲到,数组是可以由下标来访问的,但下标可不是随意的;

如果一个一维数组的长度为n,那么它的下标范围就是 0 ~ n-1

如果超出了这个范围,就会造成非法访问;

编译器默认是不做下标检查的,不报错不能保证不错,所以还是要做好下标的检查;

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 ", arr[i]);//当i等于10的时候,越界访问了
	}
	return 0;
}

结果:

下标为10,访问越界,表现为随机数。

Part4:数组作为函数参数

在实现一些函数时,我们会把数组作为参数进行传参,比如冒泡排序的设计,那么应该如何正确传参呢?

1.冒泡排序的错误设计

void bubble_sort(int arr[])
{
	int sz = sizeof(arr) / sizeof(arr[0]);//这样对吗? sz == 1
	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;
			}
		}
	}
}

这个排序是错误的,通过调试,我们发现 sz 的值为1

我们来分析一下 sz 为什么是1:

sz 是由 arr 的大小 除以 arr 第一个元素的大小得到的,由于该数组中的元素是整型,arr 第一个元素的大小为4字节,因为结果为 1 ,所以 arr 的值为 1 ,那么问题就在 arr 的大小上;

得出结论: 数组传参,传递的不是整个数组的大小

2.数组名?

看下面这段代码:

int main()
{
	int arr[10] = { 1,2,3,4,5 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%d\n", *arr); // 解引用操作符,是由地址找到所指量的操作

	return 0;
}

输出结果:

这里解释一下:

arr 本身是地址,与第一个元素的地址相同,所以arr相当于首元素的地址;

数组名解引用后是第一个元素,再次验证了上面的结论。

int arr[10] = {0};
printf("%d\n", sizeof(arr));

上面这段代码的输出结果是40;

当直接使用 sizeof 时,计算的就是数组的大小了。

结论:

• sizeof(数组名),计算整个数组的大小,内部单独放一个数组名,表示整个数组;

• &数组名,取出的是数组的地址,数组名表示整个数组。

除以上两种情况之外,所有的数组名都表示数组首元素的地址。 

3.冒泡排序错误更正

int main()
{
	int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

直接先计算数组大小,再将它作为参数传给排序函数即可。

Part5:实战

你已经学会数组了,写一些简单的小项目吧:

C语言三子棋游戏实现

另外还有扫雷,随后补🤣🤣🤣


总结: 

C语言小知识之数组,重点在数组的创建和初始化,注意数组名通常情况下表示什么,建议通过两个小游戏的实现来巩固数组知识。

码文不易 

如果你觉得这篇文章还不错并且对你有帮助,不妨支持一波哦  💗💗💗

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

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

相关文章

安卓开发学习记录(续)

文章目录十一、综合训练&#xff08;购物车功能&#xff09;十二、内容提供者Provider十一、综合训练&#xff08;购物车功能&#xff09; 实现功能&#xff1a; 手机商品页面展示&#xff0c;加入购物车功能&#xff0c;商品详情页面&#xff0c;清空购物车&#xff0c;删除购…

C++算法初级9——递归

C算法初级9——递归 文章目录C算法初级9——递归递归求阶乘递归求斐波那契数列递归&#xff0c;简单地来说&#xff0c;就是一个函数自己调用自己。函数f()就好像是工厂中生产零件的模板&#xff0c;每次我们调用函数f()的时候&#xff0c;都会依照模板生产一个新的零件&#x…

项目4:后台管理的开发和使用(前端)

项目4&#xff1a;后台管理的开发和使用&#xff08;前端&#xff09; 1.npm包管理器的基本学习 2.利用现成后台管理系统开发 3.后台管理系统的路由配置 4.后台管理系统的地址访问配置 5.前后端联调 6.完善积分等级的前端系统 7.对前端系统的全面分析&#xff08;Vue组件…

跳槽进阿里了,其实也没那么难...

对于很多没有学历优势的人来说&#xff0c;面试大厂是非常困难的&#xff0c;这对我而言&#xff0c;也是一样&#xff0c;出身于二本&#xff0c;原本以为就三点一线的生活度过一生&#xff0c;直到生活上的变故&#xff0c;才让我有了新的想法和目标&#xff0c;因此我这个二…

【C++ -模块一 常量变量、关键字、数据类型】

C 模块一C框架代码&#xff1a;第一个C程序&#xff0c;打印hello C &#xff01;代码注释&#xff1a;一 变量和常量&#xff1a;1.1变量变量创建语法&#xff1a;1.2 常量&#xff1a;不能被修改的数据&#xff08;1&#xff09; #define定义的宏常量&#xff1a;一般写在文件…

排序(3)之交换排序

目录 前言 交换排序 1.冒泡排序 1.1冒泡排序的实现 1.2 特性总结 2.快速排序 2.1hoare版本 2.2 挖坑法 2.3 前后指针版本 3.快速排序的优化 3.1 三数取中法 3.2 小区间优化 4.快速排序的非递归实现 前言 今天小编给大家带来交换排序的内容&#xff0c;对于交换排序…

C-关键字(下)

文章目录循环控制switch-case-break-defaultdo-while-forgetchar()break-continuegotovoidvoid*returnconstconst修饰变量const修饰数组const修饰指针指针补充const 修饰返回值volatilestruct柔型数组union联合体联合体空间开辟问题利用联合体的性质,判断机器是大端还是小端enu…

力扣javascript刷题343——动态规划之整数拆分

这几天有在开始投暑期实习的简历&#xff0c;可能确实是投的太晚了&#xff0c;好多厂都没有hc了&#xff0c;阿里简历面都没过&#xff08;感觉是kpi面试&#xff09;&#xff0c;被深深打击到了呜呜呜&#xff0c;花了两天整理情绪&#xff0c;重新出发&#xff0c;下篇文章针…

mysql 索引详解

mysql 索引索引分类1. 普通索引和唯一索引2. 单列索引和组合索引3. 全文索引4&#xff0e;空间索引操作使用索引1. 在已有表中添加索引2. 删除索引索引是一个单独存储在磁盘上的数据库结构&#xff0c;使用索引可以快速找出在某个或多个列中有一特定值的行&#xff0c;提高查询…

【C语言 -结构体 结构体声明、定义、初始化、结构体成员访问、结构体传参】

C语言 - 结构体声明、定义、初始化、结构体成员访问、结构体传参一 结构体类型的声明&#xff1a;声明格式&#xff1a;二 结构体的定义并初始化2.1用结构体创建&#xff08;定义&#xff09;结构体变量&#xff08;对象&#xff09;的两种方式&#xff1a;&#xff08;1&#…

WebRTC 系列(三、点对点通话,H5、Android、iOS)

WebRTC 系列&#xff08;二、本地 demo&#xff0c;H5、Android、iOS&#xff09; 上一篇博客中&#xff0c;我已经展示了各端的本地 demo&#xff0c;大家应该知道 WebRTC 怎么用了。在本地 demo 中是用了一个 RemotePeerConnection 来模拟远端&#xff0c;可能理解起来还有点…

HTTP协议:当下最主流的应用层协议之一,你确定不了解一下吗?

一.HTTP协议的含义http是什么&#xff1f;超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。‘超’可以理解为除了文本之外的图片&#xff0c;音频和视频&#xff0c;和一些其他…

硬盘、文件系统相关常识

1.硬盘 以机械硬盘为例&#xff0c;下面是机械硬盘的外形结构。 结构图&#xff1a; 每个磁盘分为两个盘面&#xff0c;每个盘面中有很多磁道(Disk Track)&#xff0c;每个磁道上有很多扇区(Sector)&#xff0c;磁道上的一段一段的就是扇区。 扇区是最小的单位&#xff0c;…

Flutter开发日常练习-黑白主题

1.添加了白天黑夜模式 2.country_picker: ^2.0.20 城市信息框架 3.image_picker: ^0.8.53 photo_manager: ^2.3.0 相机和相册的调用 4.shared_preferences: ^2.0.8 sqflite: ^1.3.1 path: 数据异步持久化到磁盘 注:登录的时候记录一下登录状态isLogin,通过isLogin来标记是否…

OCR之论文笔记TrOCR

文章目录TrOCR: Transformer-based Optical Character Recognition with Pre-trained Models一. 简介二. TrOCR2.1. Encoder2.2 Decoder2.3 Model Initialiaztion2.4 Task Pipeline2.5 Pre-training2.6 Fine-tuning2.7 Data Augmentation三. 实验3.1 Data3.2 Settings3.2 Resul…

如何战胜AI?唯努力尔-- DSP算法的FPGA实现指南

如何战胜AI?唯努力尔! DSP算法的FPGA实现指南! 来一集番外。 而这 也是开坑的第一个算法&#xff01;我们先讲案例再谈实现指南 文章目录如何战胜AI?唯努力尔! DSP算法的FPGA实现指南!观前提醒实用算法原理数学原理代码模块划分与实现FIR滤波器误差计算与系数更新模块最终代…

算法 贪心2 || 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II

122.买卖股票的最佳时机II 如果想到其实最终利润是可以分解的&#xff0c;那么本题就很容易了&#xff01; 如何分解呢&#xff1f; 假如第0天买入&#xff0c;第3天卖出&#xff0c;那么利润为&#xff1a;prices[3] - prices[0]。 相当于(prices[3] - prices[2]) (prices[2…

HBuilderX 开发工具

介绍 uni-app 官方推荐使用 HBuilderX 来开发 uni-app 类型的项目。 主要好处&#xff1a; 模板丰富完善的智能提示一键运行 下载 HBuilderX 1、官网下载地址&#xff1a;https://www.dcloud.io/hbuilderx.html 2、下载正式版&#xff08;根据自己电脑选&#xff09; 安装…

( “树” 之 DFS) 112. 路径总和 ——【Leetcode每日一题】

112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点…

虚假评论检测可视化系统的实现

菜鸟一枚&#xff0c;大佬勿喷&#xff0c;主要是想分享&#xff0c;希望能帮到像我一样的人。 主要代码是参考&#xff1a;https://github.com/SoulDGXu/NLPVisualizationSystem/tree/master/frontend 他这个代码实现了词云、摘要生成等功能吧。因为我做的是虚假评论检测系统&…