数组基础讲解-C语言

1、数组的概念

假设我们要创建10个变量,那就写10个变量,那问题来了,如果是100个变量呢?你是不是要创建100个变量,很麻烦;我们想这个10个,100个变量都是int类型,那我们能不能把它们放在一起呢?

我们把多个相同类型的变量集合放在一起,我们可以称之为数组;

数组是一组相同类型元素的集合;那我们能得到两条信息:

1、数组是有1个或者多个数据,数组的元素个数不能为0;

2、数组的元素类型是相同的

数组可以分为一维数组、二维数组、多维数组;

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

2.1 数组创建

type   arr_name [常量值];

type;表示数组存放数据的类型;比如int、char、float

arr_name;表示数组名,数组名可以自己来写,尽量写有意义的数组名;

[ ] ;里面的常量值表示这个数组的大小,数组的元素个数;

存放在数组里面的值我们称为数组的元素,我们可以通过改变type和常量值的大小,指定数组元素的类型和数组的大小;

/*
	比如存放20个数学成绩
	int math[20];
	10个浮点数
	float ch[10];
	10个字符
	char a[10];
*/

2.2一维数组初始化

比如我们创建变量的同时,给它赋值,叫做初始化;

数组创建的同时,我们也给数组赋值,叫数组初始化;

数组我们要用{  }括号把元素装起来,元素之间要用英文逗号隔开;

不完全初始化
int arr[10]={1,2,3,4,5};

错误初始化
本来是存放5个元素,现在存放了7个元素
int arr[5]={1,2,3,4,5,6,7};

完全初始化
int arr[10]={1,2,3,4,5,6,7,8,9,10};

省略数组元素个数的初始化

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

初始化可以省略数组大小,由编译器根据后面的内容帮你计算数组的元素个数

2.3一维数组的数组类型

比如一个变量
int a = 0;
变量a的类型就是int

如果是一个数组
int a[10];
那数组a的类型是int [10];

去掉变量名就是变量的类型
去掉数组名就是数组的类型

比如
int a[5];     数组类型int [5]
float b[6];   数组类型float [6]
char c[9];    数组类型char [9]

3、数组的使用

既然创建了数组,那我们就要运用数组,那么搜首先我们来了解一下数组的小标。

3.1数组小标

数组的每个元素都对应这一个下标,下标从0开始,如果数组有n个元素,那么数组就有n-1个元素下标;

每个元素都有对应下标;比如你去找一个人,你需要找到对应的房间编号;才能找到那个人;对应的你找的下标,那么你就找到了那个元素;

我们可以运用[  ]--下标引用操作符,来找到对应下标的元素;

#include<stdio.h>
int main()
{
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    //打印  7
    printf("%d\n",a[6]);
    return 0;
}

 3.2数组元素打印                

既然我们知道通过下标找到元素,那我们就可以把整个数组的元素打印出来;

小标都是从0开始的,0 1 2 3 4 5 6 7 8 9;比如产生10个下标,那我们可以用循环,产生10个下标,打印每个元素;

#include<stdio.h>
int main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    for(i=0; i<10; i++)  //产生0~9的下标
    {
        printf("%d ",arr[i]);
    }
    return 0;
}

   3.3输入数组元素

  我们知道找到下标可以打印元素,我们可以输入一个值,改变这个元素;你找到了下标,就等于你知道这个元素的房间编号;你知道的这块空间,那我们就可以往里面放东西;

int main()
{
	int i = 0;
	int arr[5] = { 1,2,3,4,5 };
	arr[3] = 9; //改变数组arr[3]
	for (i = 0; i < 5; i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}

  我们想打印一样,循环,只是这次我们不打印,我们输入进去                                                        

int main()
{
    int arr[10] = { 0 };
    int i = 0;
    for (i = 0; i < 10; i++)  //产生0~9的下标
    {
        scanf("%d",&arr[i]);  //输入数据
    }
    return 0;
}

   4、一维数组在内存中的存储;

首先我们要了解内存;内存会划分为一个一个内存单元,单位是字节;每一个内存单元都有一个编号,编号就是地址;

那我们把每个数组元素的编号打印出来,要用到&---取地址符;%p打印

int main()
{
	int arr1[8] = { 1,2,3,4,5,6,7,8 };
	int i = 0;
	for (i = 0; i < 8; i++)
	{
		printf("&arr1[%d]的地址是%p\n",i,&arr1[i]);
	}
	return 0;
}

打印出来的结果,我们改一下环境用X86,地址没那么长;

           

这是16进制的地址;可以看出来每个地址都是差4,D0~D4差4;D4~D8也差4,以此类推;接下去每个地址间都差4;

我们的数组每个元素都是int类型;占4个字节;假设每个字节都有一个编号;那么从第一个字节开始,第一个字节为0,剩下的 1 2 3 4 5 6 7 8 9 10 11;我们可以看图知道第一个元素跟第二个元素差4个字节,第二个元素跟第三个元素也差4个字节;那么看上面的地址,它们也差4个字节,那我们把地址和下面的图定义起来,假设第一个元素是0;第二个元素是1;放到下图;那么第一个元素的起始地址在字节0跟第二个元素的起始地址在字节4,那它们是不是也差4;

注意;我们就可以得出一个结论;一维数组的元素是连续存放的;

 

    5、sizeof函数计算数组元素个数

       比如这个例子;我们定义数组的元素个数是10;那么循环里面也是10;可以这样写,但是这样就写死了;你没换一次元素个数,下面循环也要跟着换;

int main()
{
    int arr[10] = { 0 };
    int i = 0;
    for (i = 0; i < 10; i++)  //产生0~9的下标
    {
        scanf("%d",&arr[i]);  //输入数据
    }
    return 0;
}

这时候我们可以用sizeof函数;  我们用sizeof函数就出来arr数组的大小是40字节,因为arr数组有10元素,每个元素是int,4个字节,那就是40个字节,下一个我们求的是数组的一个元素arr[0],字节是4;那我们换算一下如果我们,用数组的总大小除以一个元素的大小就等于数组的元素个数;因为每个元素的类型都是一样的4个字节;

int main()
{
	int arr[10] = {0};
	printf("%d\n", sizeof(arr));     //40
	printf("%d\n", sizeof(arr[0]));  //4
	return 0;
}

      sizeof(arr)/sizeof(arr[0]),这样的话,你只需要该上面的数组元素大小,就不用该下面循环的代码了;

int main()
{
	int i = 0;
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int sz = sizeof(arr) / sizeof(arr[0]);  //数组元素的个数
	for (i = 0; i < sz; i++)
	{
		printf("%d ",arr[i]);
	}
}

5、二维数组的创建

5.1二维数组

一维数组是由一组相同数据类型元素的集合;由1个元素或者多个元素;二维数组则是由多个一维数组组成,由二维数组组成的数组叫三维数组,二维数组以上组成的数组叫多维数组;

5.2二维数组创建

type  arr_name  [常量值1][常量值2]

type表示二维数组每一个元素的数据类型

arr_name表示二维数组的数组名

[常量值1]表示二维数组的行有几个元素

[常量值2]表示二维数组的列有几个元素

int arr[3][5];  //表示有3行,每一行5个元素

5.3二维数组初始化

//完全初始化
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

//不完全初始化
int arr[3][5] = {1,2};

完全初始化

不完全初始化

按行初始化,二维数组是由多个一维数组成元素组成的;一行是一个一维数组,那么一维数组我们用{ }括号括起来,二维数组也用{ }括号括起来;那就是第一个初始化第一行,第二个初始化第二行,第三个初始化第三行;

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

省略行初始化;不能省略列

省略了列,就不知道每一行多少个元素,比如有5列,每一行存5个元素,那么第六个元素就自动到下一行了;自动计算行;

int arr[][5] = {1,2,3,4,5,6};  //每列5个元素

 

剩下的元素默认为0;

6、二维数组的使用

6.1二维数组下标

二维数组跟一维数组是一样有下标的,有行下标,有列下标,要找到二维数组的元素就要包含行下标,列下标;行下标跟列下标都是从0开始的;

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

打印元素7,行2,列4

int main()
{
	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
	printf("%d\n",arr[2][4]);
	return 0;
}

6.2数组的打印和输入

跟一维数组一样,遍历每个下标,打印对应的元素;

第一行0,列 1,2,3,4,5

第二行1,列 2,3,4,5,6

第三行2,列 3,4,5,6,7

int main()
{
	int i = 0;
	int j = 0;
	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
	for (i = 0; i < 3; i++)      //行
	{
		for (j = 0; j < 5; j++)  //列
		{
			printf("%d ",arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

输入也是一样的,遍历元素下标,输入值;

int main()
{
	int i = 0;
	int j = 0;
	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
	for (i = 0; i < 3; i++)      //行
	{
		for (j = 0; j < 5; j++)  //列
		{
			scanf("%d",&arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

7、二维数组在内存中的存储

首先我们看一下二维数组的地址

可以看到第一行的一位数组每个地址之间差4,第二行每个地址之间差4,每行是一个一位数组,它们是连续存放的,那第一行和第二行之间也差4,那只有是连续的才差4个字节;

那么它其实是这样存放的;

另一个视角

二维数组,它的每一行都可以看作成是一个一维数组;那么可以通过每一行的元素下标找到;

既然每一行是一个一维数组,那它的数组名是什么?

int arr[5] = {0};
arr 是数组名
arr[6]  数组名+下标

通过上面两张图,得出二维数组的第一行是通过arr[0]+元素下标找数组元素,那么第一行的数组名是arr[0];,第二行的数组名的arr[1];以此类推;

8、C99变长数组

我们在创建数组的时候,就把数组的大小写上去,数组大小就写死了,我们想自己输入一个值,指定数组的大小,在C语言的C99标准中,通过变量来指定数组大小;

int arr[a];
int arr1[c];

上面的数组的大小是有变量来决定的

注意变长数组是不能初始化的,因为变长数组的大小是运行时才决定的,给它初始化的时候,并不知道这个数组的大小,要存放多少个元素;只有在运行时才知道;

变长数组,并不是数组时变化的,是靠变量来指定数组的大小,一定指定,是不会改变的,要等下一次运行的时候,才会改变;

感谢观看!感谢指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值