数组
摘要:
数组是数据的组合,并不是所有的数据都能组成一个数组,构成数组的数据需要满足俩个条件:数据的类型相同,在内存中连续储存。
目录:
-
一维数组的创建和初始化 -
一维数组的使用 -
一维数组在内存中的储存 -
二维数组的创建和初始化 -
二维数组的使用 -
二维数组在内存中的存储 -
数组作为函数参数
一维数组的创建和初始化 数组是一组相同元素的集合。数组的创建方式: ? ?type name [number]; 类型 数组名 [数组元素个数]; 例如 : ? ?int arr1[10];
? ?char arr2[10];
? ?float arr3[10]; 需要注意的是:[]内必须是常量,不能是变量。 ? ?int a=10;
? ?int arr[a]; 这样的数组创建是错误的。 数组创建的同时,可以进行初始化,就是给数组赋上合理的初始化值。 例如: ? ?int arr1[10]={1,2,3,4,5,6,7,8,9,10};
? ?//这是数组有十个元素,全部初始化
? ?int arr2[10]={1,2,3};
? ?//部分初始化,其余默认为0
? ?int arr2[]={1,2,3};
? ?//[]中没有常量,系统会根据{}内元素个数,来决定数组的长度 一维数组的使用 想要访问数组中的元素就要知道一个操作符 [] ,下标引用操作符。格式为:数组名[下标],数组元素的下标从0开始,定义一个整型数组 int arr[5],那么数组元素的下标依次为0,1,2,3,4。arr[5],这样的访问是错误的,数组越界,因为下标最大就是4。 例如:一个打印数组元素的程序 ? ? #include<stdio.h>
? ? int main()
? ? {
? ? ?//定义并初始化数组arr ?
? ? ?int arr[5]={1,2,3,4,5};
? ? ?for(int i=0;i<5;i++)
? ? {
? ? ? ?//依次访问数组元素arr[i]
? ? ? ?printf("%d ",arr[i]) ?
? ? }
? ? ? ?return 0;
? ? } 一维数组在内存中的储存 一维数组在定义的时候,会向内存申请一块空间,空间的大小由数组类型和数组长度决定,数组长度就是[]中的常量,这也解释了为什么不可以是变量。向内存申请的空间是定的,要是长度是变量,会导致空间不定。 拿数组arr[5]举例,以上就是它的内存排布,可以看到是紧挨着排放的,每个元素所占内存大小是由类型决定,整型就是4字节,字符就是1字节等等 我们也可以打印出数组的地址 ? ? #include<stdio.h>
? ? int main()
? ? {
? int i = 0;
? int arr[10] = { 1, 2, 3, 4, ? ? 5, 6, 7, 8, 9, 10 };
? for (i = 0; i <10; i++)
? {
? ? ? printf("&arr[%d]=%p\n", ? ? ? ? ? ? ? ? ? ?i, &arr[i]);
? }
? return 0;}
? ? -
仔细观察结果,随着数组下标的增长,元素的地址也在有规律的递增。由此可以得出结论:数组在内存中是连续存放的。 二维数组的创建和初始化 二维数组常称为矩阵,将二维数组看成行列式,可以帮助我们更好的理解二维数组的逻辑。 在创建二维数组时,和一维数组类似。也是在定义同时进行初始化。但也有区别,如代码: (1)分行给数组初始化 ? ? int arr1[行][列];
? ? int arr2[2][3]={{5,6,7}, ? ? {8,9,10}};//每个{}代表一行, ? {}内的是这一行的列的数据 (2)按数组元素在内存中的排列顺序初始化 ? ?int arr3[2][3]={5,6,7,8,9,10} 这样初始化,会先按列取够数成为一行,再依次这样操作。简单说就是,这个数组就是个2行3列的行列式嘛,先取5,6,7三个数够了一行了,再取8,9,10给第二行。 (3)省略行的初始化 ? ?int arr4[][3]={5,6,7,8,9} 由于行不确定,系统会根据{}内的数据和列来绝对由几行。 就是先取够一行5,6,7还剩下8,9那就是两行,第一行是5,6,7,第二行是8,9,0。这个0是默认补来的。 (4)对部分元素进行初始化 ? ?int arr5[2][3]={{5,6},{8,0,9}} 这样初始化的效果如表:
二维数组的使用 二维数组的引用和一维数组类似,都是通过[]操作符来引用,区别在于格式。 二维数组引用格式为 数组名[下标] [下标]。 如: ? ?#include<stdio.h>
? ?int main()
? {
? ? ? ?int arr[2][3]={0};
? ? ? ?int i=0;int j=0;
? ? ? ?for(i=0;i<2;i++)//行
? ? ? {
? ? ? ? ?for(j=0;j<3;j++)
? ? ? ? {
? ? ? ? ? ? ?arr[i][j]=i;
? ? ? ? }
? ? ? }
? ? ? ?for(i=0;i<2;i++)//行
? ? ? {
? ? ? ? ?for(j=0;j<3;j++)
? ? ? ? {
? ? ? ? ? printf("%d ",arr[i][j]);
? ? ? ? ? if(j==2)
? ? ? ? ? ? ? printf("\n");
? ? ? ? }
? ? ? }
? ? ?
? ? }
二维数组在内存中的储存
我们在理解二维数组时将其想成矩阵,但是在内存中是如此存储吗?是一个矩阵形式的储存空间吗?
为此我们可以编写一个程序来看看:
? ? #include<stdio.h>
? ? int main()
? ? {
? ? ? ?int arr[2][3]={0};
? ? ? ?int i=0;int j=0;
? ? ? ?for(i=0;i<2;i++)
? ? ? {
? ? ? ? ? ?for(j=0;j<3;j++)
? ? ? ? ? {
? ? ? ? ? ? ? ?printf("&arr[%d][%d]=%p\n",i,j,&arr[i][j]);
? ? ? ? ? }
? ? ? }
? ? ? ?return 0;
? ? ? }
从中,可以看出,这是连续存放的。
是以行为单位,连续存放。
这其实也有助于我们学习二维数组,二维数组我们不仅可以将其想象成二维的空间(矩阵),也可以想象成一个线性的排列(以行为单位)。
数组作为函数参数
之所以,将其单独提出来讲,是因为其中容易出错。
一般情况数组名是首元素的地址。但又两种特殊情况:
-
sizeof(数组名),这个数组名代表整个数组 -
&数组名,这个数组名表示整个数组
我编写程序,看看效果:
? ?#include<stdio.h>
? ?int main()
? {
? ? ? ?int arr[10]={1,0};
? ? ? ?printf("%p\n",arr);
? ? ? ?printf("%p\n",&arr[0]);
? ? ? ?printf("%d\n",*arr);//验证是否为首元素的地址
? ? ? ?return 0;
? }
我编写一个冒泡排序函数,方便大家理解数组传参:
? ? #include<stdio.h>
? ? void mao_pao(int arr[])
? ? {
? ? ? ? int i=0;int j=0;
?int z=sizeof(arr)/sizeof(arr[0]); ? ?
? ? ? ? for(i=0;i<z-1;i++)
? ? ? ? {
? ? ? ? ? ? for(j=0;j<z-1-i;j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(arr[j]>arr[j+1])
? ? ? ? ? ? ? ? ? ? int t=arr[j];
? ? ? ? ? ? ? ? ? ? arr[j]=arr[j+1];
? ? ? ? ? ? ? ? ? ? arr[j+1]=t;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? int main()
? ? {
? ? ? ? int arr[]={3,1,7,5,9,11,2};
? ? ? ? mao_pao(arr);
?int sz=sizeof(arr)/sizeof(arr[0]);
? ? ? ? for(int i=0;i<sz;i++)
? ? ? ? {
? ? ? ? ? ? printf("%d ",arr[i]);
? ? ? ? }
? ? ? ? return 0;
? ? }
发现根本就没有排序,这是啥错误呢?
我先稍作改动:
?#include<stdio.h>
? ? void mao_pao(int arr[],int z)
? ? {
? ? ? ? int i=0;int j=0;
? ? ?
? ? ? ? for(i=0;i<z-1;i++)
? ? ? ? {
? ? ? ? ? ? for(j=0;j<z-1-i;j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(arr[j]>arr[j+1])
? ? ? ? ? ? ? ? ? ? int t=arr[j];
? ? ? ? ? ? ? ? ? ? arr[j]=arr[j+1];
? ? ? ? ? ? ? ? ? ? arr[j+1]=t;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? int main()
? ? {
? ? ? ? int arr[]={3,1,7,5,9,11,2};
?int sz=sizeof(arr)/sizeof(arr[0]);
? ? ? ? mao_pao(arr,sz);
? ? ? ? for(int i=0;i<sz;i++)
? ? ? ? {
? ? ? ? ? ? printf("%d ",arr[i]);
? ? ? ? }
? ? ? ? return 0;}
发现代码运行正确,那么上次的错误在哪呢?
上一次的代码我在函数里也用了sizeof(arr)由于数组传参,导致在函数里这个arr就是代表了首元素的地址,它不能代表整个数组,尽管是sizeof这种特殊情况也不行。经过这个程序我希望大家可以更深入的了解数组传参。
结语:
希望大家可以有所收获,完结撒花,啦啦啦。
|