0


C语言数组这些知识,你真的会了吗?(万字详细总结,让你快速掌握)

在这里插入图片描述

大家好呀!我是小杨。小杨把C语言中的数组做了一个总结,希望在方便自己复习的同时也能够帮助到大家。 文章很长建议先收藏再看,防止下次想看看就找不到啦,哈哈哈😃😃😃


✨数组

🚀1.1,数组的定义

数组是由基本数据类型按照一定规则组成的,称其为构造数据类型。

构造数据类型包括数组,结构体,共用体等,使用构造数据类型可以求解更为复杂的问题。

数组是最基本的构造类型,是相同类型数据的有序集合。

数组中的元素在内存中连续存放,用数组名和下标可以唯一地确定数组元素。

🚀1.2,数组的分类

有序数组指的是数组中的每一个元素在集合中都是按序排列的,排列的位置用其下标来表示。

带有一个下标的数组称为一维数组,带有两个下标的数组称为二维数组,带有多个下标的数组称为多维数组。



✨一维数组

🚀2.1,一维数组的定义
🔭2.1.1,一维数组的一般形式

一维数组定义的一般形式

类型名 数组名 [常量表达式]
🔭2.1.2,一维数组的示例说明
int a[6];

说明:

(1)定义了一个整型一维数组,数组名为a,含有6个元素。

(2)数组名后是用方括号[]括起来的“常量表达式”。

注意:不能使用圆括号()和花括号{}。

intk(10);//不合法int l{10};//不合法

(3)方括号中的“常量表达式”,用于表示数组元素的个数,即数组的长度。

C语言规定,数组元素下标是从0开始,不能为负数:而下标的最大值由”常量表达式“的值减1确定。

注意:C语言在编译过程中不检查数组元素的下标是否越界,若数组下标越界,则会造成不可预知的后果。

(4)常量表达式可以是整型常量或者符号常量,不包含变量。也就是不允许用变量来对数组大小进行定义。

int i=10;int a[i];//这种定义不合法
#define N 15int a[N];//这种定义合法

(5)和普通变量一样,定义数组时系统会为每个数组元分配存储单元。同一数组的数组元素在内存中占用的存储单元是连续的。

int a[10];//定义一个有10个整型元素的数组achar ch[15];//定义一个有15个字符型元素的数组chfloat f[20];//定义一个有20个浮点型元素的数组f

(6)在一个定义语句中,可以有多个数组说明符,它们之间用用逗号隔开。

int a[10],b[10];

分别定义了名为a和b的数组,数组元素个数均为10。


🚀2.2,一维数组的引用

与简单变量不同的是,不能整体引用一个数组,只能引用数组中的某一个元素。

换而言之,在参与表达式运算时,数组只能以数组元素的形式出现。

🔭2.2.1,一维数组的引用一般形式
数组名 [下标]

注:下标必须是整型表达式。

a[3]=5;//将5赋值给数组元素a[3]
a[2]=a[3]-a[a[3]-4];//将a[3]与a[1]之差赋值给数组元素a[2]
🔭2.2.2,一维数组的引用注意说明
  • 因数组的定义和数组元素的引用都是用“数组名[常量表达式]”,故注意区分数组的定义和数组元素的引用。
  • 定义数组时,方括号内的常量表达式代表数组长度,可以整型常量和符号常量,但不能是变量。
  • 数组的长度在定义时必须指定,在程序中运行的过程中不能改变。
  • 引用数组元素时,方括号内是表达式,代表下标,可以是变量,下标取值范围是[0,数组长度-1]。

🚀2.3,一维数组的初始化

和普通变量一样,在定义时可以对数组元素进行赋值,称为数组的初始化。

🔭2.3.1,一维数组的初始化一般形式

一维数组的初始化一般形式:

类型名 数组名[数组长度]={初值表};
🔭2.3.2,一维数组的初始化示例说明
int a[6]={1,2,3,4,5,6};//定义a数组的同时初始化

数组初始化后各元素分别为a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5,a[5]=6。

说明:

1,数组元素的初值依次写在一对花括号内,数组之间用逗号分隔。当初值的个数与数组长度相同时,初始化可以省略数组长度。

int a[6]={1,2,3,4,5,6};//可以等价为:int a[]={1,2,3,4,5,6};

注意:若定义数组时。没有对其初始化,则数组长度不能省略。

2,静态存储的数组在定义时如果没有初始化,系统会自动给数组的所有元素赋值为0。

staticint a[6];//相当于:staticint a[6]={0,0,0,0,0,0};

3,动态存储的数组在定义时如果没有初始化,则与“未初始化的变量,其值是不确定的”一样,其元素的值不确定。

int a[6];//此时a[0]~a[5]的值未知,不确定

4,可以只给数组的前几个元素赋初值,其余元素的初值系统自动赋值为0。

int a[6]={1,2,3};//只对前3个元素赋初值,其余元素赋值为0

注意:若只对数组部分元素赋初值,因初值的个数与数组长度不相同,数组的数组长度不能省略。

int a[]={1,2,3};
//系统会认为a数组只有3个数组元素,而不是6个数组元素

5,若一个数组中的每个元素的值均为0,可以简写成:

//正确写法int a[6]={0};//错误写法int a[6]=0;

6,若初值个数大于数组的长度,则系统会产生编译错误。

int a[6]={1,2,3,4,5,6,7};//系统会编译错误

7,初值表中只能是常量,不能为变量,即使是赋值的变量也不可以。

int n=10;
a[3]={n};//错误写法

🚀2.4,一维数组的使用

代码:

#include<stdio.h>intmain(){int arr1[10]={1,2,3,4,5,6,7,8,9,10};for(int i =0; i <10; i++){printf("%d ", arr1[i]);}return0;}

代码调试:

在这里插入图片描述

输出结果:

在这里插入图片描述


🚀2.5,一维数组在内存中的储存

代码:

#include<stdio.h>intmain(){int arr1[10]={1,2,3,4,5,6,7,8,9,10};for(int i =0; i <10; i++){printf("arr1[%d]=%p\n",i,&arr1[i]);}return0;}

输出结果:

在这里插入图片描述

仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。

由此可以得出结论:数组在内存中是连续存放的。

在这里插入图片描述



✨二维数组

🚀3.1,二维数组的定义
🔭3.1.1,二维数组的一般形式
类型名 数组名 [常量表达式1][常量表达式2]
  • 与一维数组相比,二维数组定义添加一个常量表达式,其他的都一样。
  • 常量表达式1表示数组第一维的长度(行数),常量表达式2表示数组第二维的长度(列数)。
  • 二维数组的数据结构是个二维表,相当于数学中的一个矩阵,可以将其看成若干行,若干列组成。
🔭3.1.2,二维数组的注意说明
int a[4][3];

定义数组a为4*3(4行,3列)的二维数组,其元素及逻辑结构如下:

         第0列      第1列        第2列
第0行    a[0][0]     a[0][1]    a[0][2]
第1行   a[1][0]     a[1][1]    a[1][2]
第2行   a[2][0]     a[2][1]    a[2][2]
第3行   a[3][0]     a[3][1]    a[3][2]

1,二维数组a的数组元素行下标为0~ 3,列下标为0~2,共12个元素。

2,与一维数组一样,在使用二维数组时要特别注意数组元素下标是否越界。

说明:

(1)表示行数和列数的常量表达式必须在两个中括号内,不能合并写在一个中括号内。

(2)二维数组(包括多维数组)在内存中是按行存放,即在内存中先存放第一行的元素,再存放第二行的元素,…,以此方式存放。

(3)对多维数组可以看成是其元素也是数组的数组。

int a[4][3];//该二维数组可以被看成是a[0],a[1],a[2],a[3]四个一维数组构成的数组。//a[0]的数组元素有:a[0][0],a[0][1],a[0][2]//a[1]的数组元素有:a[1][0],a[1][1],a[1][2]//a[2]的数组元素有:a[2][0],a[2][1],a[2][2]//a[3]的数组元素有:a[3][0],a[3][1],a[3][2]

这种逐步分解,降低维数的方法对于理解多维数组的存储方式,初始化以及指针有很大的帮助。


🚀3.2,二维数组的引用

和一维数组一样,二维数组被引用的也是它的元素,而不是它的名称(名称表示二维数组第一个元素的首地址)。

🔭3.2.1,二维数组的引用一般形式

二维数组的应用一般形式:

数组名[行下标][列下标]
🔭3.1.2,二维数组的示例说明

二维数组的元素与一维数组元素一样可以参加表达式运算。

b[1][0]=a[1][0]*10+5;

🚀3.3,二维数组的初始化

二维数组与一维数组一样,可以在说明时进行初始化。二维数组的初始化要特别注意各个变量数据的排列顺序,这个排列顺序与数组各元素在内存中的存储顺序完全一致。

🔭3.3.1,二维数组的初始化一般形式

二维数组初始化的一般形式:

类型名 数组名[行数][列数]={初值表};
🔭3.3.2,二维数组的初始化示例说明

(1)按行给二维数组赋初值。

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

这种初始化比较直观,二维数组的行数等于初值表中大括号的对数。即第一对大括号内的数据赋值给第一行的元素,第二对括号内的数据赋值给第二行的元素,…,逐行赋值。

(2)可以将所有数据放置在一个大括号内,按数组元素排列的顺序赋初值。

int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

效果同上,但按行的赋值方法较好,一个大括号对应一个一行,清晰明了。而这种方法,若数据过多,容易遗漏,不易检查。、

(3)对二维数组部分元素赋初值。

  • 对各行首列元素赋初值
int a[4][3]={{4},{3},{2},{1}};

作用是只对各行第一列的元素赋初值,其余元素值自动为0.赋初值后数组各元素为:

         第0列     第1列     第2列
第0行       400
第1行       300
第2行       200
第3行       100
  • 对各行中某一元素赋初值
int a[4][3]={{1},{2,3},{3,4,5},{6}};

赋初值后数组各元素为:

         第0列     第1列     第2列
第0行       1       0       0
第1行       2       3       0
第2行       3       4       5
第3行       6       0       0
  • 对某几行元素赋初值
int a[4][3]={{1,2},{3}};

赋初值后数组各元素为:

          第0列     第1列  第2列
第0行       120
第1行       300
第2行       000
第3行       000

🚀3.4,二维数组的使用

代码:

#include<stdio.h>intmain(){int arr[3][4]={1,2,3,4,2,3,4,5,3,4,5,6};int i =0;for(i =0; i <3; i++){int j =0;for(j =0; j <4; j++){printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);}}return0;}

代码调试:

在这里插入图片描述

输出结果:

在这里插入图片描述


🚀3.5,二维数组在内存中的存储

代码

#include<stdio.h>intmain(){int arr[3][4]={1,2,3,4,2,3,4,5,3,4,5,6};int i =0;for(i =0; i <3; i++){int j =0;for(j =0; j <4; j++){printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]);}}return0;}

输出结果:

在这里插入图片描述

内存中的储存:

随着数组下标的增长,元素的地址,也在有规律的递增。

二维数组在内存中也是连续存储的。

在这里插入图片描述



✨字符数组

🚀4.1,字符数组的定义

与整型数组的数组元素是一个整数,实数数组的元素是一个实数一样,字符数组的元素是一个字符。

🔭4.1.1,字符数组的一般形式

字符数组也分为一维字符数组和二维字符数组。

(1)一维字符数组的一般形式:

char 数组名[常量表达式];

(2)二维字符数组的一般形式:

char 数组名[常量表达式1][常量表达式2];
🔭4.1.2,字符数组的示例说明

(1)一维字符数组的示例:

char str[5];

(2)二维字符数组的示例:

char str[5][5];

🚀4.2,字符数组的引用
🔭4.2.1,字符数组的引用一般形式

(1)一维字符数组的引用一般形式:

 数组名[下标]

(1)二维字符数组的引用一般形式:

数组名[行数][列数]
🔭3.1.2,字符数组的示例说明

(1)一维字符数组的引用示例:

str[1]

(1)二维字符数组的引用示例:

str[2][2]

🚀4.3,字符数组的初始化
🔭4.3.1,字符数组的初始化一般形式

(1)一维字符数组初始化一般形式:

char 数组名[常量表达式]={初值表};

(2)二维字符数组初始化一般形式:

char 数组名[常量表达式1][常量表达式2]={初值表};
🔭4.3.2,字符数组的初始化示例说明

(1)一维字符数组初始化示例:

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

(2)二维字符数组初始化示例:

char str[4][4]={{'b','i','g','l'},{'a','s','d','f'},{'g','j','k','e'},{'r','t','u','k'}};

说明:

(1)若初值表中的初值个数大于字符数组的长度,则会出现编译错误。

(2)若初值表中的初值个数小于字符数组的长度,则多余的字符元素的初值默认为0。

(3)若初值表中的初值个数等于字符数组的长度,可以在定义时省略数组的长度,系统编译会根据初值的个数确定数组的长度。

(4)允许用字符串常量对字符数组进行初始化。

char str[5]={'C','H','I','N','A'};char str[]={'C','H','I','N','A'};char str[]={"CHINA"};char str[]="CHINA";//这四种初始化语句等价

(5)不能在定义数组后,对数组名进行赋初值。

char str[5];
str[5]="hello";//不合法char str[5];
str ="hello";//不合法

(6)若字符数组在定义时未进行初始化,则数组各元素的初值是不确定的,与整型数组同理。

(7)二维字符数组的初始化与一维字符数组的初始化方法相类似。

(8)字符’\0’代表整数0,也就是ASCII码为0的字符,但’\0’不是字符’0’,'0’的ASCII码为48。


🚀4.4,字符数组的使用

代码:

#include<stdio.h>intmain(){char str[10]={"CHINRESE"};for(int i =0; i <10; i++){printf("%c ", str[i]);}return0;}

代码调试:

在这里插入图片描述

输出结果:

在这里插入图片描述


🚀4.5,字符数组在内存中的存储

代码:

#include<stdio.h>intmain(){char str[8]={"CHINRESE"};int sz =sizeof(str)/sizeof(str[0]);for(int i =0; i < sz; i++){printf("%c = %p\n", str[i],&str[i]);}return0;}

输出结果:

在这里插入图片描述

内存中的储存:

随着数组下标的增长,元素的地址,也在有规律的递增。

字符数组在内存中是连续存储的。

在这里插入图片描述



✨扩展:数组名

数组名表示首元素的地址。
但是数组名不表示首元素的地址有2个例外:

  • sizeof(数组名)
  • &数组名

🚀5.1,一维数组的数组名
🔭5.1.1,sizeof(数组名)

代码:

#include<Stdio.h>intmain(){int arr[10]={0};int n =sizeof(arr);//40printf("%d\n", n);return0;}

输出结果:

在这里插入图片描述

结论:

sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节。

🔭5.1.2,&数组名

代码:

#include<Stdio.h>intmain(){int arr[10]={0};printf("%p\n", arr);//arr就是首元素的地址printf("%p\n", arr+1);printf("----------------------\n");printf("%p\n",&arr[0]);//&arr[0]是首元素的地址printf("%p\n",&arr[0]+1);printf("----------------------\n");printf("%p\n",&arr);//&arr数组的地址printf("%p\n",&arr+1);return0;}

输出结果:

在这里插入图片描述

结论:&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。


🚀5.2,二维数组的数组名
🔭5.2.1,sizeof(数组名)

代码:

#include<Stdio.h>intmain(){int arr[3][4]={0};int n =sizeof(arr);//48printf("%d\n", n);return0;}

输出结果:

在这里插入图片描述

🔭5.2.2,&数组名

代码:

#include<Stdio.h>intmain(){int arr[3][4]={0};printf("%p\n", arr);//arr就是首元素的地址printf("%p\n", arr +1);printf("----------------------\n");printf("%p\n",&arr[0]);//&arr[0]是首元素的地址printf("%p\n",&arr[0]+1);printf("----------------------\n");printf("%p\n",&arr);//&arr数组的地址printf("%p\n",&arr +1);return0;}

输出结果:

在这里插入图片描述

分析:

在上述代码里,二维数组的首元素是一维数组arr[0],arr[0]+1为arr[1],因arr1[0]与arr[1]之间有4个数组元素,故arr[0]与arr[1]的地址相差16个字节。

在程序编译过程中,数组元素地址是以16进制的形式编译。

🔭5.2.3,二维数组行列数

代码:

#include<stdio.h>intmain(){int arr[3][4]={0};printf("%d\n",sizeof(arr)/sizeof(arr[0]));//求二维数组的行数printf("%d\n",sizeof(arr[0])/sizeof(arr[0][0]));//求二维数组的列数return0;}

输出结果:

在这里插入图片描述

结论:

  • 二维数组的行数等于sizeof(数组名)/sizeof(二维数组首元素)
  • 二维数组的列数等于sizeof(二维数组首元素)/sizeof(一维数组首元素)


结语

小伙伴们,当你学到这里的时候,你们应该对数组部分的内容已经有了全新的认识吧!🥳🥳🥳后续小杨会给大家总结指针的内容,不断更新优质的内容来帮助大家,一起进步。加油,追梦人!让我们一起拥抱美好明天!🎆🎆🎆

在这里插入图片描述

标签: c语言 学习

本文转载自: https://blog.csdn.net/m0_64338546/article/details/124676590
版权归原作者 小杨爱编程☆ 所有, 如有侵权,请联系我们删除。

“C语言数组这些知识,你真的会了吗?(万字详细总结,让你快速掌握)”的评论:

还没有评论