理解透C语言一维数组,二维数组这一篇就够啦!

news2024/11/25 12:39:13

前言
💖作者龟龟不断向前
简介宁愿做一只不停跑的慢乌龟,也不想当一只三分钟热度的兔子。
👻专栏:C++初阶知识点

👻工具分享

  1. 刷题: 牛客网 leetcode
  2. 笔记软件:有道云笔记
  3. 画图软件:Xmind(思维导图) diagrams(流程图)

在这里插入图片描述

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主🙊,如有不足还请指点,博主及时改正

文章目录

    • 数组
      • 1.一维数组的创建和初始化
        • 1.1一维数组的创建
        • 1.2初始化举例
        • 1.3C99变长数组
      • 2.一维数组的使用
      • 3.一维数组在内存中的存储方式
      • 4.数组名是什么?
        • 4.1数组名的意义
        • 4.2数组名的两个例外意义
      • 5.二维数组的创建和初始化
      • 6.二维数组的使用
      • 7.二维数组在内存中的存储方式
      • 8.浅浅理解二维数组的数组名
      • 9.数组的类型

数组

1.一维数组的创建和初始化

1.1一维数组的创建

  数组:一组相同类型元素的集合。跟数学中的集合是类似的。

创建方式:

type_t   arr_name   [const_n];

//type_t 是指数组的元素类型

//const_n 是一个常量表达式,用来指定数组的大小

 

1.2初始化举例

举例

int main()
{
	int arr1[10];//10个元素的数组,元素未初始化,元素值是随机值
    
	int arr2[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//10个元素的数组,元素完全初始化
    
	int arr3[10] = { 1, 2, 3 };//10个元素的数组,数组部分初始化,未指定的部分元素默认是0
    
	int arr4[] = { 1, 2, 3 };//编译器帮你计算出元素个数为3

	//定义数组时,vs下--元素个数只能是常量表达式
	int count = 10;
	//int arr5[count];//error

	double darr[10];//double类型的数组,有10个元素
    
	float farr[10];//float类型的数组,有10个元素

	return 0;
}

 

int arr1[10];的效果,元素为随机值与函数栈帧有关:

在这里插入图片描述

 

int arr3[10] = { 1, 2, 3 };的效果

在这里插入图片描述

 

int arr4[] = { 1, 2, 3 };的效果,编译器帮你计算出元素个数

在这里插入图片描述

 

  所以大家创建数组根据自己的需求来,如果想让编译器帮你计算出元素个数,初始化要明确,如果想全部初始化为0,就要把元素个数指明清楚,这样的代码int arr[] = {0}可是达不到想要的效果哒

 

1.3C99变长数组

    变长数组:可以使用变量来定义数组的大小,即数组大小可以自己输入,但是变长数组不允许初始化。

  其中vs编译器不支持C99变长数组,下面的代码我们放在linuxgcc编译器下面跑,给大家展示以下效果。

 

#include<stdio.h>

int main()
{
  int n = 0;
  
  printf("你想定义的数组的元素个数:\n");
  scanf("%d",&n);

  int arr[n];//变长数组不允许初始化

  for(int i = 0;i<n;++i)
  {
    arr[i] = i+1;
    printf("%d ",arr[i]);
  }
  printf("\n");
  return 0;
}

 

在这里插入图片描述

 

 

2.一维数组的使用

咱们使用数组的初衷就是存储一类类型相同,元素个数较多的数,那么这些元素该如何区使用呢?如何访问这些数组元素呢?

操作符[]会:下标引用操作符 --> 数组访问的操作符

举例

#include<stdio.h>

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

解释

  1. 计算数组元素个数

    其中数组大小 = 元素大小 * 元素个数

    –>元素个数 = 数组大小/元素个数 使用操作符sizeof()即可求出数组大小和元素大小

  2. 下标访问

    下标是从0开始的,例如第1个元素的下标是0,第n个元素的下标是n-1

    方式: 数组名 [下标] : 下标所对应的元素

    这也非常完美地和我么之前建议的左闭右开结合在了一起,访问元素会比较方便

    arr数组中的几号元素NO.1NO.2NO.3NO.4NO.5NO.6NO.7NO.8NO.9NO.10
    元素值12345678910
    下标0123456789

在这里插入图片描述

 

ps:大家不要把定义数组时的[]和下标访问的[]给弄混了

其中:

定义数组时的[] – [元素个数] – 只能是常量表达式(VS)

访问元素时[] – [下标] – 可以是变量

访问元素一次只能访问一个

 

3.一维数组在内存中的存储方式

  咱们就拿下述代码举例

#include<stdio.h>

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

  F10调式程序,打开内存窗口

在这里插入图片描述

  可以发现,下标越小的元素,地址越小,小标越大的元素地址越大。即数组在内存上是一个顺序存储的结构。也就是说如果我们得到了第一个元素的地址,以及数组的元素个数,是否就能得到所有的元素了呢?— 正确的

 

#include<stdio.h>

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

  上述代码同样也可以达到访问元素的效果。

在这里插入图片描述

 

4.数组名是什么?

4.1数组名的意义

在这里插入图片描述

  一个队伍总有它的的队头队尾,在数组中当中,数组名也是起着队头的作用,数组名–首元素的地址

int arr[10];,arr与&arr[0]在数值上是一样的。如下

#include<stdio.h>

int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	printf("arr:%p\n", arr);

	for (int i = 0; i < sz; ++i)
	{
		printf("&arr[%d]:%p\n", i, &arr[i]);
	}

	return 0;
}

ps:数组名是常量地址,是不允许被修改的,允许被修改的是,数组里面的元素
 
在这里插入图片描述

 

4.2数组名的两个例外意义

  数组名有两个特殊情况,在这两种特殊情况下,数组名不表示首元素地址的意思

  • sizeof(arr)

    这个计算的是整个数组的大小 = 元素大小 * 元素个数

    而不是一个 指针大小 – 4

  • &arr

    这个表示整个数组的地址

 

解释整个数组的地址的概念:

#include<stdio.h>

int main()
{
	int arr[10] = { 0 };
	printf("arr:%p\n", arr);
	printf("&arr[0]:%p\n", &arr[0]);
	printf("&arr:%p\n", &arr);

	printf("\n");

	printf("arr+1:%p\n", arr+1);
	printf("&arr[0]+1:%p\n", &arr[0]+1);
	printf("&arr+1:%p\n", &arr+1);
	return 0;
}

 

在这里插入图片描述

  我们观察到,首元素地址和整个数组的地址在数值上是相同的,但是在+1上的效果是不同的,首元素地址+1跨过了4个字节(一个元素的大小),整个数组地址+1跨过了40个字节(整个数组的大小)

 

5.二维数组的创建和初始化

  但从理解上去看二维数组,顾名思义:二维数组,二维–面,二维数组是一个有行有列的数组。

那么我们在创建时就要指明:要创建一个几行几列的数组呢?

#include<stdio.h>

int main()
{
	int arr1[3][3];//3行3列的数组,元素未初始化
    
	int arr2[4][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 ,6};//4行4列的数组,全部初始化
    
	int arr3[4][4] = { 1, 2, 3 };//4行4列的数组 -- 部分初始化,其他部分未0
    
	int arr4[3][3] = { { 1, 2 }, { 2 }, { 3 } }; //3行3列数组 -- 指明行数初始化,第一行初始化未1 2 0,第二行初始化为2 0 0,第三行初始化为3 0 0
    
	int arr5[][4] = { { 1 }, { 2 }, { 3 }, { 4 } };//省略行数初始化,编译器会帮你计算出有几行

	return 0;
}

 

int arr1[3][3];的效果。

  大家可以从数学集合的角度去理解,二维数组 – 集合里面放了集合

在这里插入图片描述

 

int arr2[4][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 ,6};的效果

 第一行放满放第二行,第二行放满放第三行…。

在这里插入图片描述

 

int arr3[4][4] = { 1, 2, 3 };

在这里插入图片描述

 

int arr4[3][3] = { { 1, 2 }, { 2 }, { 3 } };的效果:-- 指定行初始化

在这里插入图片描述

 

int arr5[][4] = { { 1 }, { 2 }, { 3 }, { 4 } };的效果

行可以省略,编译器会帮你计算,但是列是不可以省略的

在这里插入图片描述

 

6.二维数组的使用

如何取出二维数组当中的元素呢,很明显要想在二维数组当中确定一个元素的位置,

需要两个下标,1 – 行标 2 – 列表

即访问方式: 数组名 [行下标] [列下标]

#include<stdio.h>

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("%d ", arr[i][j]);
		}
		printf("\n");
	}

	return 0;
}

 

7.二维数组在内存中的存储方式

  我们将每个元素的值拿出来打印一下,看看他们之间是什么样的关系。

#include<stdio.h>

int main()
{
	int arr[3][3] = { 0 };
	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;
}

 

在这里插入图片描述

  大家注意不仅仅是圈起来的元素之间相差4,行与行之间的间隔也是4

图解

在这里插入图片描述

 

  也就可以理解成,C语言的这个二维数组,其中就是一个一维数组的乔装打扮,在一维数组里面放了几个一维数组,从而伪装成二维数组的样子。事实上还是一维的。物理上:还是顺序存储的。

  既然如此,我们也可以通过首元素地址和元素个数,来推出所有元素的位置了

#include<stdio.h>

int main()
{
	int arr[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

	int *pa = &arr[0][0];
	for (int i = 0; i < 9; ++i)
	{
		printf("%d ", *(pa + i));
	}
	printf("\n");
	return 0;
}

在这里插入图片描述

 

8.浅浅理解二维数组的数组名

  即使二维数组物理上是顺序存储的,但是我们使用逻辑结构去理解也没有影响,int arr[4] [4]的二维数组,其中arr[0]–第一行的数组名,结构:二维数组中arr[i]–第i行的数组名–第i行的首元素地址

 

9.数组的类型

我们介绍过C语言的数据类型,有int,double,char……等等,但是数组的类型不是这些

int a;–a的类型是int

double d;–d的类型是double

…………去掉数组名剩下的东西就是类型名(一般情况)

类似的:

int arr[10]– 去掉数组名arr,类型:int [10]

int arr[10] [10]–去掉数组名,类型:int [10][]10

 

 并且我们可以使用sizeof来计算一下这个类型大小

#include<stdio.h>

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

在这里插入图片描述
本篇文章就讲到这里啦,咱们下期见,拜!

在这里插入图片描述

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

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

相关文章

网站部署:使用Nginx部署vue项目到阿里云服务器

最近租了个阿里云的服务器&#xff0c;想使用Nginx把刚做好的网站部署上去 下载Nginx 目前yum已经有了Nginx的源&#xff0c;因此可以直接用yum下载和安装 yum -y install nginx默认的安装位置为/etc/nginx 默认的项目位置为/usr/share/nginx 如果安装失败检查是否安装了zli…

渗透测试-CTF文件类型操作

识别文件类型 文件分离 文件合并 识别文件类型 当文件没有后缀名或者有后缀名无法正常打开时&#xff0c;根据识别的文件类型来修改后缀名即可正常打开文件。 使用场景&#xff1a;不知道后缀名&#xff0c;无法打开文件。 第一种方式&#xff1a;kali中使用 file 文件名 f…

173:vue+openlayers:解决国内openstreetmap地图加载不出来的问题(代码示例)

第173个 点击查看专栏目录 近来写程序,发现openlayers用OSM方式来加载OpenStreetMap地图,一片爆红,瓦片加载不出来。 本示例的目的是介绍演示如何在vue+openlayers中解决OpenStreetMap地图在国内被DNS污染,加载不出来瓦片的问题,通常我们是直接引用OSM,这里采用的是XYZ方…

2022年11月第十四届蓝桥杯校模拟赛详解+代码(一)

“须知少时凌云志&#xff0c;自许人间第一流” 鄙人11月八号有幸参加学校蓝桥杯校选拔赛&#xff0c;题型为5道填空题&#xff0c;5道编程题&#xff0c;总时间为小时。奈何能力有限&#xff0c;只完成了5道填空和3道编程大题&#xff0c;现进行自省自纠&#xff0c;分享学习&…

国产ETL工具 BeeDI 产品“实时同步“之 高阶 功能组件

BeeDI 提供“ 实时”企业数据集成。实时组件通过实时处理和传输业务数据的能力&#xff0c;增强了BeeDI的批处理功能。为满足当下复杂的业务需求&#xff0c;IT部门需要实时集成以加快核心业务流程和信息流。使用实时功能&#xff0c;IT部门可以使用统一界面&#xff0c;从BeeD…

【Mybatis】mybatis使用与理解

1. mybatis基础环境搭建 若想使用mybatis&#xff0c;需要有如下两个jar包&#xff1a;①mybatis的核心jar包。②数据库驱动包。 &#xff08;想使用别人提供的服务就必须要有别人的jar包&#xff1b;mybatis是和数据库打交道的&#xff0c;那么你的程序中&#xff0c;数据库的…

【MySQL高级】MySQL的锁机制

目录 概述 MyISAM 表锁 InnoDB行锁 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制&#xff08;避免争抢&#xff09;。 在数据库中&#xff0c;除传统的 计算资源&#xff08;如 CPU、RAM、I/O 等&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共…

重装系统后要安装哪些驱动

​重装win10后需要安装驱动吗?win10系统比win7系统高级的地方在于系统内置了很多驱动&#xff0c;这可以省去用户很多安装时间&#xff0c;下面小编来告诉大家重装系统后要安装的驱动有哪些。 工具/原料&#xff1a; 系统版本&#xff1a;windows10系统 品牌型号&#xff1…

mysql8其它新特性

文章目录MySQL8.0新特性新特性1&#xff1a;窗口函数序号函数ROW_NUMBER()函数RANK()函数DENSE_RANK()函数分布函数PERCENT_RANK()CUME_DIST()函数前后函数LAG(expr,n)函数LEAD(expr,n)函数首尾函数FIRST_VALUE(expr)函数LAST_VALUE(expr)函数其它函数NTH_VALUE(expr,n)函数NTI…

Docker 常用命令大全

个人理解 docker中的镜像 就像是咱们java 中的Class &#xff0c;而容器呢 是基于这个镜像构建出的实例 类似于咱java 中 根据Class构造出的一个个实例对象 &#xff0c;本人是初学者 理解有误还请见谅&#xff0c;并麻烦您说说您的看法让彼此相互学习… 按我理解 简言之 doc…

Java-日期类,正则实验

1. 随机产生两个日期时间&#xff0c;输入按时间先后顺序输出 public class RandomDate {SuppressWarnings("deprecation")public static void main(String[] args) throws ParseException {SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss&…

二分查找 【模板+中间值问题】

全文目录&#x1f603;前言&#x1f615;二分查找动图演示&#x1f634;代码模板❗️ 使用哪个模板问题 ❗️&#x1f4a2; mid为何1问题 &#x1f4a2;&#x1f603;前言 二分查找也称折半查找&#xff08;Binary Search&#xff09;&#xff0c;它是一种效率较高的查找方法。…

[解决]github上传大文件卡住

0x00 需求 github目前的策略是超过50M的文件不允许上传&#xff0c;推荐使用lfs。 0x01 操作 再把之前提交的commit 回滚&#xff1a; git reset --hard commitId 在配置lfs&#xff1a; git lfs install git lfs track "*.zip" git lfs track "*.jar" git…

【K8S】亲和、反亲和、污点、容忍

文章目录【K8S】亲和、反亲和、污点、容忍K8s调度亲和与反亲和Pod和Node硬亲和和软亲和requiredDuringSchedulingIgnoredDuringExecution&#xff1a;硬策略preferredDuringSchedulingIgnoredDuringExecution&#xff1a;软策略污点与容忍污点&#xff08;Taint&#xff09;污点…

Python学习----基础语法2

布尔类型 布尔本质上是 1 和 0 if 基本语法格式 语法还是比较简单的 , 需要注意的是 , Python是通过空格缩进来判断代码块归属的 ( 不像java这么通过 花括号进行区分 ) , 默认是四个空格 , 你也可以使用两个或者三个等 , 只要全部统一即可 , 但是编辑器会有提示 , 规范是四…

一文带你快速了解ptrdiff_t

简介 ptrdiff_t是C/C标准库中定义的一个与机器相关的数据类型。ptrdiff_t类型变量通常用来保存两个指针减法操作的结果。 ptrdiff_t定义在stddef.h&#xff08;cstddef&#xff09;这个文件内。 ptrdiff_t通常被定义为long int类型。 ptrdiff_t定义在C99标准中。 标准库类…

【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出

文章目录目标代码0.页面结构1.新增按钮和弹出表单&#xff1a;结构2.新增按钮和弹出表单&#xff1a;点击新增弹出表单3.表单样式4.表单验证5.表单的提交和取消功能&#xff1a;接口、mock相关准备6.表单的提交和取消功能提供的数据和接口1-operateFormLabel.js5-user.js效果总…

小程序转App最便捷的方法,附实操

Flutter是谷歌的移动UI框架&#xff0c;可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界&#xff0c;Flutter正在被越来越多的开发者和组织使用&#xff0c;并且Flutter是完全免费、开源的。 它也是构建未来的Google Fuchsia应…

计算机网络(一)网络体系结构

layout: post title: 计算机网络&#xff08;一&#xff09;网络体系结构 description: 计算机网络&#xff08;一&#xff09;网络体系结构 tag: 计算机网络 计算机网络计算机网络体系基本概念网络性能指标数据量与数据速率&#xff08;比特率&#xff09;带宽吞吐量时延时延带…

Python入门自学进阶-Web框架——25、DjangoAdmin项目应用-分页与过滤

对于数据很多&#xff0c;就需要将数据进行分页显示&#xff0c;同时还要提供过滤功能。 当配置文件中配置了过滤条件&#xff0c;那就要在显示表信息的时候&#xff0c;显示过滤条件选择项&#xff0c;选择后进行过滤&#xff0c;然后下面显示过滤后的数据&#xff0c;如果数…