数组的学习与运用

 /*************************************************************************************************************

                     刚开始学习C语言,仅代表自己的学习理解,不代表观点一定正确

                                                              只做学习记录

                                                     有错误的麻烦指出,谢谢!

**************************************************************************************************************/
 

数组的概念

数组就是数据的集合,简单的说数组就是由n个数据组合在一起,数组的英文是Array。数组其实就是用户向内核申请的一块空间,只不过内核提供的这块空间的内存地址是连续的,目的就是方便用户存储数据和访问数据。

数组的规定

内核为了方便管理这块内存,所以规定这块内存只能存储相同类型的数据

想要向内核申请空间,需要提前说明存储数据的类型以及存储数据的数量

定义格式:数据类型 数组名称[数据个数];   例  int buffer[10];  char buffer[5];

数组的定义

由C语言标准可以知道,想要访问数组中的某个数据,C语言标准中把数组中的数据称为元素(element),用户需要通过数组元素的编号来访问数据,C语言标准把数组元素的编号称为下标,而数组元素的下标是从0开始的。  

比如:E1假设是数组对象,E2假设是数组元素的个数,假设存储整型,定义数组的时候 int E1[E2],如果想要访问E1数组中的第E2个元素, E1[E2] = 10;  数组元素的下标:0 ~ E2 - 1

int buf[5];  // 一共有5个元素  

buf[5] = 10; //错误的 数组下标无法达到5,下标从0开始!!

 

语义

可以知道,C语言标准中提到数组名其实是一个指向数组第一个元素的地址,同时也指的是一个数组

数组下标和转换

可以看到,C语言标准中提到 E1[E2]就表示可以访问名字叫做E1的数组对象的第E2个元素,并且可以用另一种方式进行替换 就是 ( * ( (E1) + (E2) ) ),如果E2是一个常量,则括号可以省略,如果E1只是一个数组名,括号也可以省略。

( * ( (E1) + (E2) ) )  --->  ( * ( E1 + E2 ) )  ---> 如果只打算访问数组元素 --->  *( E1 + E2 ) !!!!!

 

为什么C语言中规定*( E1 + E2 )可以访问数组内存地址,是什么原理?*有什么作用?

回答:通过C语言标准可以知道E1是数组对象,并且E1也可以表示数组对象第一个元素的地址,所以E1就是E1[0]的地址,E2表示要访问的数组元素的下标,可以知道数组只能相同类型的数据,所以数组中的每个元素的数据的宽度是相同的,所以从内存的角度理解(E1+E2),就是从E1地址开始向后偏移E2个元素单位,所以就是向后偏移了E2*type个字节。

 (E1+E2)形式只是计算出数组元素所对应的地址,但是数据是存储在存储单元中的,用户此时只知道存储单元对应的地址,但是如果想要把该地址中的数据读取出来,C语言标准是利用 * 实现的。

*运算符

C语言标准中把 * 也作为单目运算符,所以只有一个操作数,这个操作数的类型应该是指针类型,也就是说操作数应该是一个地址, * 地址就表示得到该地址对应的结果,简单的说,*地址就可以得到该地址下的值。  *也被称为间接运算符,一般和指针一起使用

如果用户定义了一个整型数组int buf[5];那么(buf+1)指的是数组地址向后偏移一个元素对应的单元大小,也就是地址向后偏移了4字节,请问(&buf+1)表示什么意思,应该如何解释?

 

可以发现,C语言标准中提到数组名可以用于表示数组的第一个元素的地址,但是有两种例外情况。

第一种:当&地址运算符和数组名一起使用时,数组名就不能表示数组首元素地址,而是表示数组本身,所以(&buf+1)向后偏移一个单位其实是向后偏移整个数组大小的字节,上图向后偏移了20字节

第二种:当sizeof运算符和数组名一起单独使用时,数组名就不能表示数组首元素地址而是表示数组本身,int buf[6];  sizeof(buf) = 24byte。 

对数组进行初始化

int but[10]={0}; //表示定义数组的时候就对数组进行初始化,每个数组元素存储的值都是0

int buf[10]; buf[10]={0};//是错误的 只有在定义数组的时候对数组赋值的动作才叫做初始化

计算数组元素个数

如果用户定义数组时并未在[]中说明数组元素个数,但是在定义数组时已经对数组进行初始化,所以系统会自动计算数组所需要占用的内存大小,请问系统如何判定数组的长度?用户又如何来验证数组元素个数是否正确?

回答:可以通过sizeof运算符来计算数组的空间大小,如果用户想要计算数组元素的个数,应该设计为   sizeof(数组名称)/sizeof(数组类型)

清除数组之前的元素

用户定义了一个数组,并且也对数据正确进行了初始化,但是用户后面准备存储新的元素到数组中,想要把之前存储的元素清空,由于定义数组已经做过初始化,是否意味着只能把数组中的元素一个一个单独清空?

方法:调用库函数bzero()和memset()可以轻松实现数组的清除动作,两个函数的区别:bzero函数只可以把数组的元素清0,但是memset可以让数组中的每个元素为指定的值,所以memset函数使用更加灵活

字符数组

使用字符数组的目的是存储字符序列,字符数组的格式是a[]={‘a’,’b’},字符需要带’’单引号,C语言规定用户也可以使用字符串来存储字符序列,字符串需要使用双引号””进行约束,字符串也表示字符序列的首地址

字符数组和字符串的区别

 可以知道,C语言中的字符串会由系统自动在末尾添加转义字符“\0”,目的是作为字符串的结束标志,而定义的字符数组是由用户进行初始化,所以系统不会自动在字符数组中添加“\0”

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值