当前位置:网站首页>【C语言】明解数组(1)
【C语言】明解数组(1)
2022-08-02 13:04:00 【凡人编程传】
作者:凡人编程传
系列:C语言初阶(适合小白入门)
说明:以凡人之笔墨,书写未来之大梦
*前言
哈喽!几日不见,甚是想念啊,因为前两天身体有点问题去医院拖更了,现在好了回来继续卷!好了,咱们这一节进入全新的一个章节——数组。这一章节的内容也挺重要的,这个数组和后面数据结构的顺序表很类似所以值得认真学,把基础打好,才能应对后面的数据结构与算法这个大boss。好了,咱们直接进入正题!
*一维数组
这个东西在前面的文章代码里大家也肯定见过多次面了。他的全名叫做一维数组。为啥叫一维数组呢?大家肯定听说过维度吧。比如现在我们生活的空间就是一个三维空间,一维指只有长,这里长在C语言中指的就是数组的长度(行),那有一维数组,有没有二维数组呢?答案是有的。二维数组就增加了一个列的概念。但是也不要想象力太过了,是没有三维数组的,如果有,那你那个三维的不跳出编译器打你?
一维数组的创建和初始化
- 一维数组的创建如下:
int arr[3];
这句代码的意思就是创建了一个数组名为arr,并且有3个类型为int的元素。
- 一维数组的初始化
(1)完全初始化(初始化也就是指创建的时候顺便赋值)
int arr[3]={1,2,3};
(2)不完全初始化
int arr[5]={1,2,3};
这两个有啥区别啊?咱们不妨调试代码看一下
可以看到,第一个中的元素只有三个,且全部都按初始化指定数字了。第二种有5个元素,只有前3个元素初始化了指定数字,后面的两个元素默认为0.
由上可知:
1.一维数组会按下标(数组的下标是从0开始),用来标识元素。如arr[1]对应的就是数字2)从前往后存储数据的。
2.一维数组不完全初始化时,后面没被初始化的元素会被默认为0,(当数组类型是char的时候默认的是\0)
一维数组的使用
1.用来连续录入一组数据
有的人就说了,为啥不用scanf?那么让你录入1-10000数字,你一个一个输入吗?累不累啊?用数组配合循环分分钟的事情。
#include<stdio.h>
int main()
{
int arr[1000];
int i=0;
for(i=0;i<1000;i++) //因为数组下标是从0开始,所以i从0开始初始化
{
arr[i]=i;
}
return 0;
}
这里还要提醒大家一点,在创建数组的时候不能写成int arr[n];的形式,[]里面必须是整形常量,当然在C99标准中添加了一个柔性数组的概念,如果你的编译器支持C99标准完全可以大胆这样写。
2.配合sizeof操作符计算数组个数
sizeof操作符用于计算一个数据的大小,单位是字节(byte).那么我们知道Int的长度是4个字节,那么int arr[3];数组里面有3个int类型的元素,那么1个int类型的元素戳4个字节,所以3个Int类型的长度就是3 * 4=12个字节,也就是整个数组的长度是12个字节。那么一个int类型是4个字节。就可以得到一个公式 ——元素总长度/元素长度==元素个数
也就是sizeof(arr)/sizeof(arr[0])==3
code;
#include<stdio.h>
int main()
{
int arr[3] = {
1,2,3 };
printf("%d", sizeof(arr) / sizeof(arr[0]));
return 0;
}
运行结果:
一维数组在内存中的存储
咱们要想了解内存,不妨来打印看看数组的地址、
code:
#include<stdio.h>
int main()
{
int arr[3] = {
1,2,3 };
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%p\n", &arr[i]);
}
return 0;
}
运行结果:
由上图可知:
1.一维数组在内存中是连续存放的,可以看到内存是以十六进制显示,第一个元素个位8与C(12),之间相差4个字节,也就是说每个元素(地址)各占4个字节,也就相差4个字节
2内存地址.随着数组下标的增长,从低地址增长到高地址。
如下图所示:
*二维数组
二维数组的创建和初始化
二维数组就是在一维 数组的基础上多了一个维度——列,也就是多了个下标。
code:
#include<stdio.h>
int main()
{
int arr[3][4];
return 0;
}
像以上这种有两个下标的数组就是二维数组。那他多出来的一个下标有啥意思呢?
看下图:
可以看出,与一维数组的区别就是多了几行,其他的没什么区别。那么从图看出这个数组的第一个元素就是下标为[0][0]的元素(第0行0列),也就是左上角那个元素,第二个元素则是[0][1]以此类推。其实这跟矩阵有点像,学过的同学更容易理解。
那么知道了怎么创建就该初始化了。初始化和一维数组还是有点区别的。请看如下代码:
- 非指定完全初始化
#include<stdio.h>
int main()
{
int arr[3][4]={
1,2,3,4,5,6,7,8,9,10,11,12};
return 0;
}
不妨来调试一下里面的存储情况如何:
由上图可知:
二维数组的元素存放方式与一维数组一样,从第一个元素下标开始存放
- 非指定不完全初始化
这次咱们举一个字符数组的例子来看看和一维数组是否有所不同。
code
#include<stdio.h>
int main()
{
char arr[3][4] = {
'a','b','c','d','e','f','g','h' };
return 0;
}
1.二维数组和一维数组的不完全初始化方式一样,若没有初始化完全部元素则补0,字符数组则补\0.
2.字符串数组不能写成二维数组的形式,char[3][4]=“abcdefg”;这种写法是不存在的。
- 指定完全初始化
这中初始化的形式和一维数组的初始化就不一样了.咱们调式一下就明白了。
code:
#include<stdio.h>
int main()
{
int arr[3][4] = {
{
1,2,3,4},{
5,6,7,8},{
9,10,11,12} };
return 0;
}
很明显,这种初始化方式就可以指定初始化哪一个下标,{1,2,3,4}这个集合刚好对应第0行0,1,2,3列,从而初始化。
- 指定不完全初始化
这种初始化方式和完全初始化略有不同。
code:
#include<stdio.h>
int main()
{
int arr[3][4] = {
{
1,2},{
5,6},{
9,10} };
return 0;
}
在指定的区域内没有初始化到的元素自动补0,字符数组则补\0.
二维数组的基本使用
输出二维数组的数据:
#include<stdio.h>
int main()
{
int arr[3][4] = {
{
1,2},{
5,6},{
9,10} };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("arr[%d][%d]=%d ", i, j, arr[i][j]);
}
printf("\n"); //每次打印完一行后,换行
}
return 0;
}
运行结果:
当然,二维数组真正的使用肯定不是这么简单啦。这个后面会讲到,今天只是了解。
二维数组在内存中的存储
code:
#include<stdio.h>
int main()
{
int arr[3][4] = {
{
1,2},{
5,6},{
9,10} };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("arr[%d][%d]=%p ", i, j, &arr[i][j]);
}
printf("\n"); //每次打印完一行后,换行
}
return 0;
}
一可以看出维数组在内存中是连续存储的,同理二维数组也是在内存中连续存储的。每一列之间相差4个字节,每一行之间相差16个字节(因为1行4列,4 * 4=16.)那么这个连续存储有什么作用呢?
1.这里还有一个知识点就是二维数组的行下标是可以省略的,当然不是行下标符合本身不写,是行下标里面的数字可以不写。但是列下标是不可以省略的如:int arr[][4]; 那么这里行下标可以省略就和二维数组是连续存放有关系了,因为一行的列数确定是可以找到下一行的,因为这一行的最后一列的下一个元素一定就是下一行的第一列元素嘛,所以可以省略行下标.
如图:
*结言
好了,今天的内容就是这些,学习编程一定要去多调试观察,总结。希望你有收获,我们下节见!
边栏推荐
猜你喜欢
随机推荐
.Net 5.0快速上手 Redis
Data Lake (2): What is Hudi
String concatenation in SQL
移动端适配,华为浏览器底色无法正常显示
Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单。
SQL Server 数据库之生成与执行 SQL 脚本
企业用直播平台能实现什么
智能手表前景如何?
水平垂直居中方式
汉源高科千兆12光12电管理型工业以太网交换机 12千兆光12千兆电口宽温环网交换机
Object.entries()
新特性解读 | MySQL 8.0 GIPK 不可见主键
3 ways for OpenFeign to set headers
机器人碰撞检测方法形式化
wx-wow(微信小程序动效库)
The uniapp/applet onload method executes the interpretation every time the page is opened
路由-嵌套路由
FreeRTOS experiment--one function creates multiple tasks
LeetCode_139_单词拆分
How to implement waterfall flow layout (what is waterfall flow layout)