数组
1.int数组
- 数组的定义
int arr[5]; //定义一个未初始化的能存放3个数据的int数组
相当于找了块连续的内存,占位置。每一小块位置根据类型占多少字节,比如这里是int,那就占4个字节,总共20字节。如果这时,想arr[0]输出到控制台,那将会看到一串奇怪的数字,垃圾值没有价值。
这个0,1,2通常称为下标,索引,角标。
- 数组的初始化
实际开发中,并不会int arr[5];,而是在定义时就要将数组初始化,如果不知道初始化为什么值,那就0,有时也会-1。
int arr[5] = {0}; //将5个值初始化为0
将数组置0也可以这么干:
#include<stdlib.h> //需要用到memset函数
int arr[5];
memset(arr, 0, sizeof(arr)); //sizeof用来计算内存大小,
常用的初始化方法:
int arr[5]={0,1,2,3,4}; //定义一个数组,并初始化为
int arr[]={0,1,2,3,4}; //当数组长度确定时,[]内可以省略长度
注意:定义数组时,要让编译器知道你想定义多长的数组
遍历初始化:
int arr[5] = {0};
int i = 0;
for(i;i<5;i++)//以i作为数组下标,那就要控制好范围,arr[6]超出了范围会报错
{
arr[i] = i; //此处需要赋的值可以用表达式,比如i*10
}
2.struct数组
- struct数组定义
struct MyStruct
{
int num1;
float num2;
int arr[3];
};
struct MyStruct struct[3]={0};
- struct数组初始化:
struct MyStruct struct1[]={{1,2.12,{1,2,3}},{0},{11,0.66,{0}}};
这里看着有点复杂,实际开发时也很少这么干,但只要掌握了它赋值的逻辑,那就说明你更进一步了。首先是最外层的花括号,然后是进一层的括号,有3个,那就代表定义了3个struct结构体,再进一层,是给arr数组初始化的花括号。可以看到,赋值是严格按照顺序来的先是int,再到float,然后是arr。当然,也可以给其中一个struct赋值为0。
事实上你也可以像上述提到的int数组那样用memset,遍历方法给结构体赋值。
struct MyStruct struct1[3];
memset(struct1, 0, sizeof(struct MyStruct) * 3);//或者sizeof(struct1)
当然,如果你相当熟悉struct的内存对齐,你可以memset不同大小类型的数据。
int i;
for(i = 0;i<3;i++)
{
struct1[i].num1 = i;
struct1[i].num2 = (float)i; //强转为float类型
int j;
for(j=0;j<3;j++)
{
struct1[i].arr[j] = j;
}
}
3.指针数组
- 指针数组的定义
int* pInt[3] = {0}; //将3个指针指向空
- 指针数组初始化
指针数组存放的是指针,而指针一般都是用来指向地址的,所以类似于前面的将一些数赋值给它,意义不大。当然,你也可以多此一举,先定义一个int,再将int的地址给指针(那为什么不直接弄个int数组呢)。 或者你比较熟悉底层硬件,你可以将指针指向硬件的地址。
突发奇想,既然每个类型数据都有地址,那我让这几个指针存放数组的地址会怎样?
int arr1[3] = {0,1,2};
int arr2[3] = {3,4,5};
int arr3[3] = {6,7,8};
int* pInt[3] = {&arr1, &arr2, &arr3};
怎么使用里面的数据?
printf("%d", (pInt[0])[1]);
按照之前的逻辑,pInt[0]取得arr1,arr1[1]取得数1,很好。
也就是说,如果将arr也换成指针,那套娃不就套起来了。
&arr1其实就代表了取arr1[0]的地址(毕竟整个数组地址是从第0个开始的),而数组允许省略&,以arr1直接代表数组的地址。那我们就可以简化一下写法。
int* pInt[3] = {arr1, arr2, arr3}; //去掉&
事实上我们称这种结构为二维数组,它有更简便的写法,也不需用到指针。
二维数组
前面提到的称为一维数组。 看看二维数组的写法。
- 二维数组的定义
//定义一个3×3的二维数组
int arr[3][3]={{0,1,2},{3,4,5},{6,7,8}};
实际上二维数组在内存里也是连续的。但我们仍然可以想象成上图那样,并用坐标表示法理解。比如(1,1)的位置是4。以(i,j)的形式表示,方便使用,以及对遍历初始化的理解。
- 二维数组的使用
和前面提到的指针数组(pInt[0])[1]的使用相似。
printf("%d", arr[1][1]); //输出4
- 二维数组的初始化
memset仍然可行。
遍历:
int i;
int j;
int num=0;
for(i=0;i<3;i++) //一般而言,最外层循环代表(i,j)的i
{
for(j=0;j<3;j++)
{
arr[i][j] = num;
num++;
}
}
你也可以尝试着理解三维数组,它们的思想是类似的。
最后
如果文章有什么错误的地方,或者补充,欢迎各位指正讨论。