C语言基础入门----(5)数组详解

这篇具有很好参考价值的文章主要介绍了C语言基础入门----(5)数组详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Tips:本文主要面向C语言初学者及新手,属于系列文章,笔者借此巩固自身同时也希望帮助更多新人更快的入门,如有不当或错误,欢迎指正。

目录

前言

一、数组的定义

1.1数组的概念        

1.2数组的定义格式

1.3注意事项 

1.4数组元素的访问

1.5数组的特点 

1.6常见错误:数组越界

二、一维数组

1.数组初始化

2.数组的大小及元素个数   

3.清零函数

4.字符数组 

4.1字符数组的初始化

4.2字符数组的输入输出

4.3strlen()函数 

三、二维数组

3.1二维数组的定义

3.2二维数组元素的访问

3.3二维数组的初始化

3.4二维数组的大小

3.5二维数组遍历

 四、数组名的另外含义

总结


前言

        前面几篇文章我们有讲解过C中的常见数据类型,而本篇我们将讲解一种我们人为构造的数据类型——数组。同时,数组也是C中第一个开始我们重点掌握的内容,熟悉了数组,我们才能做出更多 的操作。


一、数组的定义

1.1数组的概念        

        在C语言中, 数组属于构造数据类型。一个数组内包含单个或者多个数组元素,这些数组元素可以是基本数据类型,也可以是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。

1.2数组的定义格式

        通常情况下,我们的数组格式为以下形式:

        存储类型            数据类型               数组名[元素个数]      = {         内容         }

例:     auto                    int                        num[5]                 = { 1,2,3,4,5 }

这就是创建了一个存储类型为auto(自动型)的整型(int)数组,这个数组名为num,包含有1~5五个元素。

对数组进行初始化可以直接整体赋值,也可以单独的一个一个赋值:

int num[5]={1,2,3,4,5}    <==等同于==> a[0] = 1;a[1] = 2;a[2] = 3;a[3] = 4;a[4] = 5;

1.3注意事项 

        1.我们在定义一个数组时,非特殊需求下不会对其存储类型进行声明,选择省略,此时并非是未对其定义,而是编译时默认将其视作为auto型。

        2.C语言中定义数组时的数据类型就是数组内元素的数据类型,二者必须保持统一

        3.数组名需要符合标识符命名规则

        4.同一函数中,数组名不要和变量名重复,避免引起冲突,编译崩溃

        5.数组必须先定义,后使用。只能逐个引用数组元素,不能一次引用整个数组。
 

1.4数组元素的访问

        数组一般情况下包含了诸多元素,那我们只需要获取其中一个元素是怎么获取的呢?在C语言中,我们利用的是数组的下标来“访问”的数组内各个元素。

即:数组名[下标号],下标可以是常量,也可以是表达式,若数组未初始化,则访问的元素值将会是随机数。

数组写法格式,基础编程,c语言,开发语言,单片机,面试

如上图所示,这里需要注意的是,数组访问时,下标是从0开始,如果如上图这样使用,下标为1时候获得的元素反而是第二个元素。

同样的,我们也可以通过输入函数scanf等修改元素:

数组写法格式,基础编程,c语言,开发语言,单片机,面试

1.5数组的特点 

         数组有两个特点,一点是前文我们提及到的同一数组内数据类型相同;另外一点就是数组内的元素内存是连续的

        我们的数据只要是成功创建,他就会占据我们的空间,这部分空间是虚拟存在的,并不是我们电脑上存储东西的实际物理内存(FLASH或者说ROM)。只有当运行我们的这个程序时,它才会从虚拟空间将其拷贝到我们的内核空间,然后执行程序内容。当运行程序时,系统会自动生成一个进程,这个进程便是我们运行的程序。系统会为每一个进程创建一个0-4G(32位系统)的虚拟内存,而我们的数据如果没有其他说明,便是存放在其中的栈区,程序运行结束时,便会从栈区自动的释放掉,减少对于系统内存的占用。

数组写法格式,基础编程,c语言,开发语言,单片机,面试
内存图

 如果读者还是不太清晰这方面,可以暂做了解,后面我会在C进阶内容中将这里再展开详细讲解。

数组便是通过在存放时,各个元素的存储是连续的,例如上文讲解到用到的a[5],在32位系统中若假设第一个元素a[0]存放的地址是0x0000(一般情况下,我们习惯用16进制表示地址),由于是int数据类型,每一个元素都占4字节,则其在系统内存中的存放实际是如下图所示:

数组写法格式,基础编程,c语言,开发语言,单片机,面试

 当然,我们也可以通过代码查看各个数据的地址情况,从而判断:

#include <stdio.h>

int main(void)
{
    int a[5]={1,2,3,4,5};

    int i = 0;
    for(;i<5;i++)
    {
        printf("a[%d] = %d     ",i,a[i]);
        printf("a[%d]的地址是: %p\n",i,&a[i]);
    }
    return 0;
}

其运行结果如下:

数组写法格式,基础编程,c语言,开发语言,单片机,面试
数组的输出一般采取for循环遍历输出

 1.6常见错误:数组越界

        数组越界是常见的一种错误,由于C是较为重视运行效率,在一些情况下数组越界有可能不会报错,增加很大的后期维护工作。

所谓的数组越界,实际上产生的原因便是访问的元素超出了数组本身的长度,如下图所示:

数组写法格式,基础编程,c语言,开发语言,单片机,面试

         我们定义的数组a本身是不存在a[5]的,当我们尝试输出一下a[5]时候,他居然是可以访问取出的。这是因为我们已经访问的不再是我们数组定义的数据了,此时访问到的数据是不属于系统给数组a开辟的内存的,属于是“界外内存”。这时候我们是对其进行的输出显示操作,但是如果我们采取的是输入等操作,对a[5]所在空间输入一个数据,就会将原本这个空间存放的数据覆盖掉。如果很不凑巧你这个内存空间原本存放的数据非常重要,这个错误就会导致你重要数据的丢失

        如果读者是在循环时不小心数组越界,就会导致死循环:

数组写法格式,基础编程,c语言,开发语言,单片机,面试
将a数组中的所有元素遍历修改为0但是数组越界

 由于数组越界的存在,所以建议读者使用时多加注意。

二、一维数组

1.数组初始化

//全部初始化
int a[5] = {1,2,3,4,5};

//部分初始化
int a[5] = {1,2};
/* 此时a数组实际是 1,2,0,0,0 在初始化数组时未初始化的元素则为0 */

//未初始化
int a[5];
/* 未初始化的数组的各个元素值为随机值,只能另外单独对元素赋值,未赋值的元素依旧为随机值 */

一维数组初始化时,可以省略元素个数。 

2.数组的大小及元素个数   

        数组的大小通过sizeof关键字实现,也可以人为计算,计算方式为:

元素数据类型所占字节数  *  元素个数  =  数组的大小      

int main(void)
{
    int a[5]={1,2,3,4,5};

    printf("%d ",sizeof(a));      //sizeof(数组名)

    return 0;
}

输出结果为20,即  4  *  5。

元素个数的获取,也可以通过sizeof(数组名)/sizeof(数据类型)方式获得。

需要明确的一点是,对于一维数组而言,数组的大小即是数组的长度。 这一点在讲解下文的二维数组时会加深理解。

3.清零函数

数组写法格式,基础编程,c语言,开发语言,单片机,面试

4.字符数组 

        C语言不像C++,python等编程语言,有专门的字符串数据类型(string),故而想要表示一串字符,需要通过字符数组的方式来存放,该类数组就是元素数据类型为字符型的数据。

4.1字符数组的初始化

1.字符串赋值初始化

char a[] = {"hello"};

//等价于

char a[] = "hello";

该类赋值方式较为简单,但是需要注意的一点是这种的初始化系统会在最后补充一个  '\0'  来作为字符串结束标志,此时若是使用sizeof函数可以查看到其是占据内存空间的。

数组写法格式,基础编程,c语言,开发语言,单片机,面试

2.逐个字符赋值初始化

char b[] = {'h','e','l','l','o'};

这种方式的初始化较为麻烦,但是这种方式的初始化,不会添加字符串的结束标志  '\0',数组的大小不会受到影响,使用sizeof可知其大小为5。

若是此时我们将数组a的内容赋值给数组b,则此时会报错,因为b在前面初始化时给其开辟的空间只有5,而“hello”内容却是6个字节,超出了其容量。

4.2字符数组的输入输出

数组写法格式,基础编程,c语言,开发语言,单片机,面试

4.3strlen()函数 

        strlen函数是string库中的函数之一,主要作用是用来计算字符数组的长度,它的计算长度是实际长度,不包含  ‘\0’  。

size_t   strlen(const  char  *s)

其参数是我们要计算的字符串的首地址(即字符数组名),返回值的size_t是类int型的一个宏定义,输出使用时依旧使用%d格式控制即可。

数组写法格式,基础编程,c语言,开发语言,单片机,面试

strlen与sizeof的区别 :

        1.sizeof明确来说实际上是关键字,而strlen是string库的函数

        2.sizeof计算的是数据所占空间的大小,strlen计算的是字符串的实际长度

        3.当计算的字符数组元素个数省略时候,sizeof计算的数组大小会包含 '\0' ,而strlen计算的数组长度不包括  '\0' 。

三、二维数组

        上述讲的只有一个下标的数组统称为是一维数组,而多个下标的数组我们就称作是多维数组

读者可以理解为一维数组类似于一根有端点的直线,端点之间也有众多点,每个点都代表一个元素;而二维数组类似于一个平面直角坐标系下的平面,我们需要确定(x,y)两者才可以确定该点的值;而三维数组就类似于三维直角坐标系下的(x,y,z),需要三者才可以确定值......

此时想要去访问元素就不能像之前一样单个下标即可定位具体的元素,下面将会以二维数组为例讲解多维数组的基础知识。

3.1二维数组的定义

通常情况下,我们的二维数组格式为以下形式:

        存储类型            数据类型               数组名[行数][列数]    

例:     auto                    int                        num[3][4]                 

这就是创建了一个存储类型为auto(自动型)的整型(int)数组,这个数组名为num,行数为3,列数为4;

同样的,二维数组乃至多维数组都需要注意数组越界问题,上述创建的三行四列的二维数组实际是a[0][0]到a[2][3]共12个数据。

3.2二维数组元素的访问

二维数组依旧是通过下标来访问的元素,但是此时相当于(x,y)坐标,多了一个需要确定的下标,通过控制行下标列下标来决定访问的元素。

数组写法格式,基础编程,c语言,开发语言,单片机,面试

3.3二维数组的初始化

二维数组与一维数组的初始化类似,分为全部初始化、部分初始化、以及未初始化三种形式。

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};          //按三行四列顺序赋值全部初始化
    
int b[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};    //按行赋值全部初始化

int c[3][4] = {1,2,3,4,5,6,7,8};                     //三行四列顺序赋值部分初始化
    
int d[3][4] = {{1,2,3},{5,6,7}};                     //三行四列顺序赋值部分初始化  

int e[3][4];                                         //未初始化

数组写法格式,基础编程,c语言,开发语言,单片机,面试

由此可看出, 初始化时未赋值则其为0,若是未初始化,则元素值为随机值,需对其单独赋值。

需要注意的是,在数组定义初始化时我们可以省略行坐标,上文中的a[3][4]也可以以a[][4]来定义,但是不可以省略列坐标

3.4二维数组的大小

二维数组的大小与一维数组就有区别了,一维数组中我们讲到过,一般情况下一维数组的大小与长度一致。而二维数组的大小,就是实际占据的空间大小,与长度无关

我们一般使用关键字sizeof(二维数组名)来确定二维数组的大小,同样的也可以采取人为计算的方式计算。

3.5二维数组遍历

一维数组遍历,在上述中以图片形式展现,为使用for循环遍历,而二维数组的遍历,我们在C语言中一般采取的是for嵌套来遍历。

数组写法格式,基础编程,c语言,开发语言,单片机,面试

 四、数组名的另外含义

对于一维数组而言,数组名除了代表一个数组之外,也表示是一个数组的首地址。我们可以直接使用数组名来提高我们的日常编程使用。

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

   printf("a[0] :%d\n",a[0]);
   printf("a的首地址是:%p\n",a);
   printf("a的第一个元素的地址是:%p\n",&a[0]);
数组写法格式,基础编程,c语言,开发语言,单片机,面试
一维数组a

对于二维数组a[3][4]而言,a[0]实际上是二维数组a的首行行地址,即a[0]这第一行的行地址,也可以用数组名a表示。而a[1]表示的是a+1的地址,是第二行的首地址。而a[0]此时本身已经是行地址的级别,a[0]+1的话则是在行地址的基础上精准到了列地址,表明是a[0][1]的地址。

数组写法格式,基础编程,c语言,开发语言,单片机,面试
a[0]+1获得的是地址,取地址内的内容使用取内容符号 *

总结

        本篇讲解了第一个构造数据类型数组的定义,使用,注意事项等。下一篇将会讲解C语言中大名鼎鼎的“指针”,学习了本篇数组的初学者,建议网络上查找一些练习题巩固,加深对数组的理解。文章来源地址https://www.toymoban.com/news/detail-767525.html

到了这里,关于C语言基础入门----(5)数组详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言基础入门之C语言列表的增删改查与指针链表详解

    在C语言中,列表通常使用数组来实现。数组是一种连续的内存空间,可以存储相同类型的数据。通过下标访问数组元素,可以快速查找和修改数据。 要向列表中添加新元素,可以通过将元素插入到指定位置来实现。首先,需要确保列表有足够的空间来存储新元素。然后,将

    2024年02月07日
    浏览(36)
  • 【go语言基础】指针数组和数组指针

    (1)指针数组: 存储指针的数组,也叫存储地址的数组,简单说就是存储地址的。 首先它是一个数组,数组中的元素都是指针(地址)。 (2)数组指针: 首先它是一个指针,存储的是指向数组的指针。 (1)指针数组 定义: 注意:首先是一个数组,将数组中的元素定义为

    2024年02月13日
    浏览(52)
  • C语言基础之——数组

    前言:本篇文章,我们将对一维数组,和二维数组进行展开式的讲解,并进行实际应用。 目录 一.一维数组 1.一维数组的创建和初始化 (1)数组的创建 (2)数组的初始化  2.一维数组的使用 3.一维数组在内存中的存储 二.二维数组 1.二维数组的创建与初始化 (1)数组的创建

    2024年02月11日
    浏览(37)
  • C语言基础——数组与字符串

    数组 – 类型 – 构造类型 数组是相同类型数据的集合。 类型 [数组长度];//类型 [] char [] int [] float [] double [] 类型:4大基本类型 – char int float double 数组 指针 结构体 [] – 一定不可以省略 数组长度 – 定义变量时,告诉编译器,该数组要开辟多大空间。 类型 标识符=初始化

    2023年04月12日
    浏览(42)
  • perl脚本语言学习1——基础篇:变量、数组、哈希数组、循环、文件、函数

    2023.3.18 今天下载虚拟机把电脑磁盘内容弄到乱七八糟,难受 发现每次学习遇到一个坎,感觉面前是一座大山,越过去之后又对前途充满了希望 perl:practical extraction report language 实用提取和报表语言 从字面上看主要与文本处理相关 变量定义: my 存储 数字、字符、字符

    2024年02月12日
    浏览(72)
  • 考研C语言刷题基础篇之数组(一)

    目录 第一题:用数组作为参数实现冒泡排序 不用函数的冒泡排序 冒泡排序原理: 错误的数值传参冒泡排序 错误的原因  就是什么是数组名 正确的数组传参的冒泡排序  数组的地址和数组首元素的地址的区别  冒泡排序原理: 一共经过n-1次排序:相邻之间两两作比较。交换

    2024年01月25日
    浏览(44)
  • 【Go 基础篇】深入探索:Go语言中的二维数组

    在计算机编程中,数组是一种基本的数据结构,用于存储相同类型的元素。而二维数组作为数组的一种扩展,允许我们以类似表格的方式存储和处理数据。在Go语言中,二维数组是一个重要的概念,本文将深入探讨Go语言中的二维数组,包括定义、初始化、遍历以及应用场景等

    2024年02月10日
    浏览(41)
  • web基础入门和php语言基础入门 二

    WHERE 子句,条件限制语句: SELECT *或其他 FROM 数据表(可以是多个) WHERE 需要满足的条件 SELECT NAME FROM VULN WHERE NAME=\\\"ecoloy\\\"; SELECT * FROM VULN WHERE NAME=\\\"ecoloy\\\"; 首先,我先插入了几条数据。 然后我进行了限制查询,从 vuln 数据表中的 name 字段下筛选出来 NAME=\\\"ecoloy\\\" 数据。 第二句话是

    2024年02月13日
    浏览(56)
  • JAVA数组元素反转的三种写法------JAVA入门基础教程

    int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67}; for(int i = 0;i arr.length/2;i++) {     int temp = arr[i];     arr[i] = arr[arr.length - 1 - i];     arr[arr.length - 1 - i] = temp; } for(int i = 0;i arr.length;i++) {     System.out.print(arr[i] + \\\"t\\\"); } System.out.println(); //互换方法2 int[] newArr = new int[arr.length]; for(int i = arr.l

    2023年04月17日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包