【C语言数据结构】:数组

数组本质上只是编译器在内存空间上开辟的【一连串的内存】

而代表数组的【变量】其实只是这一连串内存空间的【第一个元素的内存地址】。

所以当你给编译器看一个数组时,他并不是像人一样能看到这个数组的全貌,他只能看到这个数组的第一个元素,并且知道这个元素的内存地址。

【看了这段话很蒙圈?问题不大!接着看下去就行了】

一、定义数组

数组的普通定义非常简单,你只需要这样

int numList[10];

就可以定义一个【含有10个空间大小的整型数组】,里面可以存放十个整型元素。

在刚定义并未初始化的时候,你可以理解为里面什么都没有,是空的,就像你拿了一个袋子,里面没有装东西一样。

1. 【延伸知识】数组的理解

毕竟数组你们在学C语言的时候也都学了,那么我们再学数据结构的时候,肯定还需要再深入一点点的

当然上面这个例子不是十分恰当,或许这个例子更好一点:

在你们学校开会的时候,【第一排的座位】规定只能由【领导】坐

这个【第一排座位】就可以理解为这个【数组】,有【10个座位】就是数组的【长度为10】,【领导】就是这个【int类型】。

如果这个你还不理解,那就…那就…去看视频理解吧 [手动狗头]

2. 【延伸知识】数组的初始元素

当然了,虽然可以理解为空的

但是其实不是空的,他是由数组长度个(上面的数组就是10个)自由内存地址组成,诶,你别不信,我们可以打印一下试试,看看我说的到底是真的还是假的。

#include <stdio.h>int main()
{int a[10];for (int i=0;i<10;i++){printf("%d\n", a[i]);}
}

看到这,可能有些Java选手受不了了,明明没有定义,你就打印,肯定会报错的!

pass:Java中需要定义,声明

但是会吗?很明显是不会的,它是有元素的

打印结果:

1997818734
0
1
44
7673468
6422376
4200059
4199952
0
44

二、数组的类型强制

——带着问题学知识——

  1. 下标取值是怎么做到的?
  2. 下标为什么从0开始?
  3. 为什么数组会强制类型?

————————————

【p1】下标取值是怎么做到的?

我们知道,数组其实是在内存空间中开辟的一串连续的内存地址,而在编译器中只有数组第一个元素的内存地址。

【下标】,其实是在操作数组第一个元素的内存地址,令其【加下标】,就能得到第【几个】元素。

我们假设第一个数组元素的内存地址为:00000001(不要当真),而这个数组变量为【a】(数组为整型),那么【a[0]】,其实就是令这个内存地址【+0】,得到第一个元素的内存地址,再得到这个内存地址所存储的值。

而因为这个数组是整型数组,而整型在内存中占用4个字节,所以,第二个元素应该这么表示:【a[1] =》(00000001+(1*4))】 得到第二个元素的内存地址,再得到第二个元素。


展示数组的地址与数组第一个元素的地址相同

#include <stdio.h>int main(int argc, char const *argv[])
{int a[] = {1, 2, 3, 4};     // 一个数组printf("a的内存地址%p\na[0]的内存地址%p", &a, &a[0]);return 0;
}

运行结果:

a的内存地址0061FEC0
a[0]的内存地址0061FEC0

【p2】下标为什么从0开始?

想必看完上面的问题,你也对这个问题有了认知。

因为数组的内存实际上是第一个元素的内存,而通过下标进行计算是需要对内存地址进行相加操作的,所以就必须从0开始。

【p3】为什么数组需要强制类型?

看看刚刚的式子:【a[1] =》(00000001+(1*4))】 转成通用的式子就是:

数组第一个元素的内存地址+(下标*类型在内存中所占用的字节数)

所以数组要强制类型。

这个内存地址在C语言中,是可以通过【&】直接取到的,有兴趣的,可以通过这个符号去对数组进行一些操作。

比如:

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

自己打印一下看看数组的内存地址看看是不是相邻的,看看相邻是不是4

运行结果:

0061FEA4
0061FEA8
0061FEAC
0061FEB0
0061FEB4
0061FEB8
0061FEBC
0061FEC0
0061FEC4
0061FEC8

三、数组使用

增改查的操作。

增其实也是在未初始化的时候,,,而不是长度增加。

数组在使用的时候,切忌要记得数组的长度,不要超出数组长度,会报错的。

1. 增

遍历赋值的操作

#include <stdio.h>int main()
{int a[10];for (int i=0;i<10;i++){a[i] = i;printf("元素的内存地址:%p\n\n元素的值:%d\n", &(a[i]), a[i]);}
}

运行结果:将0-9的值放进数组中

元素的内存地址:0061FEA4
元素的值:0元素的内存地址:0061FEA8
元素的值:1元素的内存地址:0061FEAC
元素的值:2元素的内存地址:0061FEB0
元素的值:3元素的内存地址:0061FEB4
元素的值:4元素的内存地址:0061FEB8
元素的值:5元素的内存地址:0061FEBC
元素的值:6元素的内存地址:0061FEC0
元素的值:7元素的内存地址:0061FEC4
元素的值:8元素的内存地址:0061FEC8
元素的值:9

2. 改

因为定义的时候,数组不是空的,也是有元素的,我们在进行我们的操作的时候,就将原来的值替换掉了,这个改也是同样的道理,其原理还是通过下标。

3. 查

通过下标查找某个元素

#include <stdio.h>int main()
{int a[10];for (int i=0;i<10;i++){a[i] = i;printf("元素的内存地址:%p\n元素的值:%d\n\n", &(a[i]), a[i]);}
}

再说别的就是数组的相关算法了,什么二分枚举,双指针,三分枚举…

四、练习题

学编程,最忌讳的就是光看不练,动起来,做点题

p1 数组串联

给你一个长度为 n 的整数数组 nums 。请你构建一个长度为 2n 的答案数组 ans ,数组下标 从 0 开始计数 ,对于所有 0 <= i < n 的 i ,满足下述所有要求:

ans[i] == nums[i]
ans[i + n] == nums[i]
具体而言,ans 由两个 nums 数组 串联 形成。

返回数组 ans 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/concatenation-of-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

p2 基于排列构建数组

给你一个 从 0 开始的排列 nums(下标也从 0 开始)。请你构建一个 同样长度 的数组 ans ,其中,对于每个 i(0 <= i < nums.length),都满足 ans[i] = nums[nums[i]] 。返回构建好的数组 ans 。

从 0 开始的排列 nums 是一个由 0 到 nums.length - 1(0 和 nums.length - 1 也包含在内)的不同整数组成的数组。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/build-array-from-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

p3 执行操作后的变量值

存在一种仅支持 4 种操作和 1 个变量 X 的编程语言:

++X 和 X++ 使变量 X 的值 加 1
–X 和 X-- 使变量 X 的值 减 1
最初,X 的值是 0

给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有操作后, X 的 最终值 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/final-value-of-variable-after-performing-operations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

关注下方公众号,领取更多福利- python基础教程- python知识脑图- python入门100例- C语言数据结构教程- C语言算法100题

【C语言数据结构】数组相关推荐

  1. C语言数据结构-数组广义表-十字链表-实现十字链表的初始化操作-实现十字链表的删除操作

    十字链表 十字链表相关定义如下: typedef int ElemType;// 非零元素结点结构 typedef struct OLNode {int row,col;ElemType value; ...

  2. c语言数组左下角便*,数据结构 - 数组

    数组与线性表的差异 我们以前应该学习过数组,数组与线性表的区别与联系呢? 它们的相同之处: (1)它们的相同之处,它们都是若干个相同数据类型的数据元素a0,a1,a2,-,an-1构成的有限序列 它们 ...

  3. C语言数据结构-动态数组

    C语言动态数组就是建立一个动态数组结构体,其中包括一个指针,一个当前元素个数,一个容量. //动态数组的结构体定义 typedef struct DYNAMICARRAY {int *pAddr;// ...

  4. c语言一维数组逆序输出_剑指信奥 | C 语言之兵人来袭!

    趣乐博思剑指信奥系列 ❝ 趣乐博思剑指信奥系列,专门针对全国青少年信息学奥林匹克联赛 NOIP 而开展的专业教育方案.开设的课程有 C 语言基础,C++ 语言基础,算法设计入门与进阶,经典试题分析与详 ...

  5. 数据结构c语言版第一章答案,《c语言数据结构》第一章概论自测题答案

    <<c语言数据结构>第一章概论自测题答案>由会员分享,可在线阅读,更多相关<<c语言数据结构>第一章概论自测题答案(4页珍藏版)>请在人人文库网上搜索. ...

  6. 算法与数据结构--数组和链表的区别

    最近由于在找工作,经历了一些校招面试后,感觉在数据结构和操作系统上面,还有很多的欠缺.所以今天要学习一下数据结构.还是从面试的那到题开始. 数组和链表的区别? C和C++语言中用数组处理一组数据类型相 ...

  7. 一些可运行的C语言数据结构代码

    网上有很多C语言数据结构代码:有的不能运行:下面是一些能运行的,和运行截图:备用一下: 1 队列 #include<stdio.h> #include<stdlib.h>#de ...

  8. 数据结构数组计算机中的应用,2018考研计算机:数据结构数组和广义表复习重点...

    2018考研计算机:数据结构数组和广义表复习重点 2017-08-17 16:00 | 考研集训营 <数据结构(C语言版)>复习重点在二.三.六.七.九.十章,考试内容两大类:概念,算法, ...

  9. 用数据结构c语言写成绩排序,C语言数据结构 快速排序实例详解

    C语言数据结构 快速排序实例详解 一.快速排序简介 快速排序采用分治的思想,第一趟先将一串数字分为两部分,第一部分的数值都比第二部分要小,然后按照这种方法,依次对两边的数据进行排序. 二.代码实现 # ...

  10. 【c语言数据结构】二叉树

    c语言数据结构完全二叉树 快速开始 直接参考示例代码即可 介绍 概念 二叉树(Binary tree)是树形结构的一个重要类型. 许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单 ...

最新文章

  1. 一、flask的基本使用-flask
  2. Jackson 注解 -- 指定输出顺序
  3. ASP.NET MVC 重点教程一周年版 第九回 HtmlHelper
  4. redis 流 stream的使用总结 - 如何遍历
  5. mysql存储过程返回多个值_数据库mysql存储过程之返回多个值的方法示例
  6. 微pe工具箱是微软的吗_微PE工具箱V2.0更新10内核
  7. WordPress无其他语言解决方法
  8. 2012年软件评测师真题精选
  9. 解决du df结果不一样的问题
  10. Sprint周期开发总结
  11. Android客户端如何使用cookie
  12. Java动态代理机制原理详解(JDK 和CGLIB,Javassist,ASM)
  13. 【MDCC专访】郑晔:用JavaScript征服物联网应用开发
  14. IOS开发之——AFN-网络状态监控(04)
  15. 信号处理琐碎知识点 — OFDM 正交频分复用
  16. 【c++面向过程实验6】函数
  17. 三个等号和二个等号的区别是
  18. 蛋白粉可以提高免疫力吗?
  19. 一秒获取朋友位置(火绒抓取ip)
  20. scanner.nextLine()和scanner.next();的区别

热门文章

  1. Web开发必须知道的知识点
  2. Strusts2笔记6--拦截器
  3. mysql死锁——mysql之四
  4. 设置Response中的ContentType
  5. MS Sql Server查询磁盘的可用空间,数据库数据文件及日志文件的大小及利用率
  6. php如何获取当前几号,PHP如何获取当前时间
  7. docker rabbitmq_RabbitMQ消息中间件快速入门
  8. MySQL ( Ubuntu16.04 )
  9. Mac 升级 catalina 后无法创建文件,Read-only file system
  10. 自定义NodeJS-C++ Addons使用说明