1.一维数组
1.1一维数组的定义
数组是⼀组相同类型元素的集合;从这个概念中我们就可以发现2个有价值的信息:
(1)数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
(2)数组中存放的多个数据,类型是相同的。
1.2一维数组的创建
type name[常量值];
eg: int arr[3];
1.3一维数组的初始化
在创建变量或者数组的时候,给定⼀些初始值,被称为初始化。
(1)不完全初始化
不完全初始化就是初始化的元素个数没有达到一维数组的个数。
eg:int arr[4]={0};
(2)完全初始化
eg:int arr[3]={1,2,3};
1.4一维数组的类型
一维数组的类型就是去掉数组名以外的部分。
举个例子:
int arr[3]={0};
char arr1[4]={'0'};
则这两个数组的类型分别是int [3],char [4]。
1.5一维数组的使用
1.5.1下标
人为规定一位数组的下标是从0开始的。
比如一个数组有n个元素,那么他的第一个元素的下标为0,最后一个元素的下标为n-1.
举个栗子:
int arr[10]={1,2,3,4,5,6,7,8,9,10};
1.5.2输入和打印
那么该如何打印一维数组呢,我们只需要按照他的下标数依次打印即可,因此我们可以用到循环。
int arr[4]={0};
int i=0;//确定下标
//以下是如何输入数组
for(i=0;i<4;i++)
{
scanf("%d ",&arr[i]);
}//比如我们输入1 2 3 4
//以下是如何输出数组
for(i=0;i<4;i++)
{
printf("%d ",arr[i]);
}//这时就会打印出1 2 3 4
1.6一维数组在内存中的储存
那么一维数组中的数据是如何储存的呢?
下面我们用一串代码来证明以下。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0; i<10; i++)
{
printf("&arr[%d] = %p\n ", i, &arr[i]);//注意:%p是指针的占位符
}
return 0;
以下是运行结果:
从运行结果不难看出,数组中的元素是连续存储的,他们相邻地址差值都相等,相差四个字节。
1.7sizeof函数
我们可以通过sizeof函数来求出数组的长度
举个栗子:
因为sizeof中的是arr,所以求的是整个数组的长度
int arr[10] = {0};
printf("%d\n", sizeof(arr));
return 0;
那么如何求每个元素的长度呢?
我们只需要把元素确定下来即可,那么就需要加上下标。
int arr[10] = {0};
printf("%d\n", sizeof(arr[0]));
return 0;
如果求出了以上两个数据,那么数组元素的个数我们只需要将两个相除即可。
int arr[10] = {0};
int sz = sizeof(arr)/sizeof(arr[0]);
printf("%d\n", sz);
2.二维数组
2.1二维数组的定义
我们如果把上述的一维数组当作元素,那么就是二维数组。
2.2二维数组的创建
type name[常量1][常量2];
常量一表示的是行,常量二表示的是列,在创建数组时,我们可以省略行但是不能省略列。
2.3二维数组的初始化
在创建变量或者数组的时候,给定⼀些初始值,被称为初始化。
(1)不完全初始化
int arr2[3][5] = {0};
(2)完全初始化
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
注意:
二维数组初始化可以不初始化行,但是不能不初始化列。
int arr5[][5] = {1,2,3};
注意:此处行并不是只有3个,而是只画了三个。
2.4二维数组的使用
2.4.1下标
其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定。
数组中的⼀个元素。
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;
2.4.2输入和打印
那么我们应该如何访问二维数组呢?只要能够按照⼀定的规律产⽣所有的⾏和列的数字就⾏;
因此我们可以选择使用循环来的输入打印他的行和列。
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
int i = 0;//遍历⾏
//输⼊
for(i=0; i<3; i++) //产⽣⾏号
{
int j = 0;
for(j=0; j<5; j++) //产⽣列号
{
scanf("%d", &arr[i][j]); //输⼊数据
}
}
//输出
for(i=0; i<3; i++) //产⽣⾏号
{
int j = 0;
for(j=0; j<5; j++) //产⽣列号
{
printf("%d ", arr[i][j]); //输出数据
}
printf("\n");
}
2.5二维数组在内存中的储存
那么应该如何研究二维数组的储存呢?
和一维数组一样,我们需要打印出二维数组的地址
int arr[3][5] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
结果如下:
从输出的结果来看,每⼀⾏内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的。
就相当于把许多一维数组一行拼接在一起。
3.变长数组
背景:
在我们之前的数组,是我们需要多大的数组就创建多大的数组,这么不仅麻烦,而且还不够灵活。因此在C99中引入了变长数组来解决这一个问题。
3.1定义:
什么是变长数组呢?
顾名思义就是元素个数可以改变的数组,我们可以理解为他创建时的常量换成了变量,这样在我们使用时,需要多大的数组我们输入多大的值即可。
但是VS是不支持变长数组的。
int n = 0;
scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩
int arr[n];
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
3.2注意:
变长数组在使用时是不能初始化的。
int n=0;
scanf("%d",&n);
int arr[n];
int arr[n]={0};//会报错
一定要小心这种情形,在以后刷题的过程中会经常碰到这种情况。
以上是所有内容,谢谢观看。再会。