IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言】如何正确的理解数组 (一维) -> 正文阅读

[C++知识库]【C语言】如何正确的理解数组 (一维)

??

哈喽大家好,我是保护小周?,C语言,接下来给大家带来的是数组和指针系列的文章,这篇主要讲的是一维数组的相关知识,是博主的所见所闻,细节上的知识后面会这里面没有提,会放在后期的文章中与指针相结合讲,多多包含。

目录

一、 一维数组的创建和初始化

1.1 数组的创建

1.2 数组的初始化

二、?一维数组在内存中的存储

2.1 关于数组越界问题

2.2 关于字符数组计算元素个数的问题


一、 一维数组的创建和初始化

1.1 数组的创建

我们在程序开发中,常常需要描述一块由多个相同元素的数据项组成的数据,这就是数组。

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

数组的定义,举个例子:

int arr[5];

int 是指数组的元素类型,arr 是数组名, [? ] 可以先理解为告诉编译器这是个数组,里面的常量5 代表需要创建多少个 数组元素类型的元素。

这句话怎么站在编程的角度理解呢? 就是在内存的栈区上开辟一块连续的 5个 int 类型的空间(20个字节)?,然后这块空间名字叫 arr。

那我们是不是可以说 arr 的类型为 int [5] , 其实这才是正确的理解。

数组创建,在C99标准之前, [? ] 中 要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化。VS 编译器中不支持变长数组,定义的时候只能是给常量。


1.2 数组的初始化

数组在定义创建的时候,我们可以对里面的值进行初始化。

C语言中数组不进行初始化的时候里面都是随机值。我们应该养成好习惯在定义的时候初始化将这些空间值置为0,int arr[5]={0};? 也可以根据自己的需要初始化值。

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

?对数组的部分空间初始化:

int arr1[10] = {1,2,3};

那么这一块10?个连续的整型空间前 3块空间的值分别初始化为 1,2,3;后面的7块空间都是随机值。


数组在创建的时候如果想不指定数组的确定的大小就得初始化。

int? arr[ ]={1,2,3,4,5};

这个时候编译器就会 根据初始化的内容来确定数组的元素个数,然后根据元素个数开辟空间。上例,初始化了5个元素,所以编译器会给 arr数组开辟5个 整型空间。


对字符数组的初始化:

首先字符数组也对根据初始的内容(元素个数)开辟相应的空间,只要是数组,在初始化的时候,如果你指定了数组的元素个数,但是你初始化的元素多于指定数组的空间个数,初始化的元素依次赋值给数组空间,多余的部分无效。

C语言里面没有字符串类型!通常用一个字符数组来存放一个字符串。字符数组每一块空间都只占1个字节。而且存储的内容是根据ASCLL码存储。

字符数组初始化的方式有两种:

依次的初始化(也可以指定字符数组的元素个数):

char str1[]={'a','b','c','d','e','f'};

?存储结构如图:

这里给大家介绍一个概念,数组开辟的一块连续的存储空间,数组元素也是一种变量,通常称之为下标变量,我们可以通过数组的下标来表示,数组中的某一个元素。数组的下标规定从 0开始依次往后(详细内容后面讲)。

另外,在初始化的时候 char str1[ ]={? '97' , 97 }; 这两个的含义是不一样的'? ?'?引用表示用 ASCLL 码的形式存储,里面的数字会对应 ASCLL 表里字符存储。如果不打引号,这个数字就是单纯的数字,因为一个字节 是八个二进制位,如果是有符号位(signed)char 那么他的取值范围就是 [-128,127] , 无符号位(unsianed)char 取值范围就是 [0~255]? ,ASCLL码 规定由一个字节描述,最高位为 0 ,所以ASCLL 码的取值范围是 [0~127] ,128个字符。 我们所说的 ‘\0’,其实就是 字符 0 ,但是千万不可以理解为 ‘0’,这个是数字0。


?按照“字符串”元素个数开辟空间,和初始化:

char str2[]="abcdef";

这种情况,表面上编译器为 str2 字符数组开辟6 个字节的空间,实际上是7个,因为编译器会把字符串的后一个空间放字符串的结束标志 ‘\0’ 表示字符串已经结束。有了‘\0’标志后,编译器就可依此判断字符串的元素个数,所以使用字符串初始化的时候无须指定数组的长度。在输入,输出的时候还可以一次性处理字符串,可以不使用循环语句逐个输入和输出。(%s)字符串的形式。


二、?一维数组在内存中的存储

先来介绍一点知识,数组的使用,数组的 [ ] 是操作符,下标引用操作符,作用是就是可以访问数组元素,?数组名 [下标值] 即可访问对应下标的元素。

通过以上代码我们得出几点知识:

1. arr 就是数组名,数组名代表就是 数组首元素(下标为0 的元素)的地址,但是有两个例外

  • sizeof(数组名);计算的是整个数组的地址。
  • &数组名,数组名是表示整个数组,是取整个数组的地址。

sizeof 这个标识符的作用就是计算 它包含的在内存中所占的字节数。

所以我们计算一个整型数组的元素个数,可以用:sizeof (数组名) / sizeof(数组的任意一个元素);我们一般是 / 首元素。

2.??栈区内存的使用习惯:先使用高地址处的空间,再使用低地址处的空间。

3. 假设 arr 数组在内存的栈区上开辟了一块连续的存储空间(40个字节),数组每个元素的地址根据数组的下标的增长,由低地址向高地址变化。

?4.?数组在内存中是连续存放的

?5.? 如果我们对定义的数组造成越界访问( 越界就是通过操作符等手段访问了不属于数组的空间),这种是很容易造成的错误,一定要注意,数组下标从 0? 开始。没有初始化的空间往往就是随机值,也有可能是“烫烫烫”。


2.1 关于数组越界问题

  • 数组的下标是有范围限制的。
  • 数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
  • 所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
  • C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的。

咱们写代码时,最好自己做越界的检查,一定要注意, 越界访问有可能就造成了对别的空间的非法使用,如果那块空间给到了某个变量维护,这就是很严重的错误。


2.2 关于字符数组计算元素个数的问题

上文说到字符数组的初始化有两种方式:

char? str1[ ]={ 'a','b','c','d','e','f' };

char? str2[ ]="abcdef";

我们先用sizeof 标识符来试试计算长度:

#include<stdio.h>
int main()
{
	char str1[] = {'a','b','c','d','e','f'};

	char str2[] = "abcdef";

	int len1 = sizeof(str1) / sizeof(str1[0]);
	int len2 = sizeof(str2) / sizeof(str2[0]);

	printf("str1数组的元素个数为:%d\n", len1);
	printf("str2数组的元素个数为:%d\n", len2);
	
	return 0;
}

这也证明了我们上文说的 如果直接初始化一个字符串,那么在字符串的最后还会使用一个空间存字符串的结束标志 '\0' ,在C语言当中 '\0'可是字符串里很重要的一点。我们在使用%s 以字符串的形式输入,其实最后编译器会默认在最后添加一个 '\0'; 使用 %s 以字符串的形式输出的时候,会根据 '\0' 来打印,'\0'之后的字符不会被打印。

举个例子:

scanf() 输入字符串:

我们可以看到我给 字符数组指定了10个字节的存储空间,理论上我们可以存10个字符,没有问题,但是我们是以字符串的形式输入,自己我输入了 10 个字符a 也打印出来了10个a? 但是编译器报了个错,这是为什么呢?因为以字符串的形式存储,需要留一个空间存储 ‘\0’? 所以造成了越界使用空间,使用了 11个字节的空间,这样是不行的,所以我们给字符数组指定了空间大小(定义的时候),我们一定记得预留一个空间存储 ‘\0’ 。

错误得示范,越界访问时绝对不可以的, 越界使用更是大大得错误,一定要注意!

字符数组才可以整体得输入输出,整型数组,或者是浮点型数组,都得老老实实的循环输入输出!


?我们使用 strlen ( ) 库函数来试试计算字符数组长度:

这里我们就很奇怪,str2 这个数组里,确实是 6个有效字符,没有问题,那么 str1 数组明明是只输入了 6个字符,为什么会有这个结果 19呢,好奇怪啊,接下来博主来给你们解答疑惑。

strlen( ) 这个库函数 专门计算字符数组的元素个数,那么他是根据 '\0'(字符串结束标志)来计算,遍历字符串,直到在内存中找到 '\0' 为止。返回类型是 无符号整型。

str1 字符数组,我们没有存放 '\0' 结束标志,所以在使用 strlen() 函数的时候就会越界访问,直到找到'\0' 。

不断地进行,越界访问,直到在内存中找到了 '\0' ,然后统计了 '\0' 之前的个数,这就是 strlen(str1)打印 19 原因,所以结束标志很关键得嘞。

当然解决方案就是:

char str[]={'a','b','c','d','e','f','\0'};

?主动添加字符串结束标志,这就是争对循环输入字符的方式,手动末尾添加。


?printf() 打印字符串

你们看咱们初始化的时候将 '\0' 其实就是字符0,放入str [ ]数组,没有问题,但是在打印的时候却忽略了? '\0' 后的字符 efg ,所以打印也是根据 '\0' 来决定打印的字符。


至此C语言一维数组博主已经分享完了,相信大家对一维数组有了不同的理解,尽请期待数组 &&指针。

本期收录于博主的专栏——C语言,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“C语言基础知识”。C语言_保护小周?的博客-CSDN博客

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周???*★,°*:.☆( ̄▽ ̄)/$:*.°★*??

文章多处存在借鉴,如有侵权请联系修改删除!?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:08:17  更:2022-09-21 00:10:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:03:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码