1.数组结构
首先介绍一下什么是数组,当面对一系列有规律的,同类型的,长度固定并且还是排列的,就可以使用数组记录
数组声明定义: 类型 数组名 [长度]
成员变量就可以使用 数组名[下标]-------注意数组的第一位是从0开始,假如有三位数,那么就是0,1,2
并且在使用过程中一定不能越界,比如你有四位,你非得弄到五位数,内存不够,就会提醒你,错误如下
对数组的赋值
第一种可以进行一个一个赋值,当然在定义数组之后,也可以使用一次直接赋值
bl[0] = 22;
bl[1] = 32;
bl[2] = 25;
bl[3] = 27;
bl[4] = 19;
//定义一个五位数组
int bl[5]={22,32,25,27,19}
//可以对后面未标出的数值,默认为0
int bl[5]={0,1}//后面未标出的位数默认为0
//
2.对数组名字分析
再定义一个数组之后,会得到数组名,对于这个数组名,就可以理解是这个数组的首位地址
也同样是表示为第一个元素的地址
因此在使用的时候,我们可以用首地址+偏移地址得到我们想要的数据
as+0,as+1--表示对地址进行便宜操作,得到下位元素的操作,这个值与&as[0]的值一样,因此,就完全可以认为
as+0=&as[0], as+1=&as[1]
因为其地址值表示一样,所以对于他们空间的取值,也同样是一样,输出结果完全一样,可以替换
*(as+0)=as[0
*(as+1)=as[1]
3,指针与数组
通过定义一个指针指向数组的首位地址,这样就可以通过改变指针,来对数组进行操作
int as[]={10,20,30,40,50};
int *p;
int i=0;
p = as; //as直接表明的就是地址,所以不需要在进行取地址操作
//指针+1与数组名+1的区别
p++; //指针是变量,可以对其进行改变
as++; //数组名是一个固定的数,不能进行更该
//数组名+[下标] 与 *(指针+移动) 与 指针+[下标] 的应用效果*/
printf("%d %d %d %d", as[2], *(as + 2), *(p + 2), p[2]);------输出的的都是30
// 利用指针变量实现数组的便利操作
for (i = 0; i < 5; i++)
{
printf("%d %d", *(p + i), p[i]);----验证了俩种方法都是一样的,都可以进行输出
}
for (i = 0; i < 5; i++)
{
printf("%d ",*p++ );//*跟++是同一级别,因此,运算的时候,从右往左进行
}
4.二维数组
二位数组的类型:int 数组名[][]
二维数组的成员使用:
arr[0][0] = 1; arr[0][1] = 1; arr[0][2] = 1;
arr[1][0] = 0; arr[1][1] = 1; arr[1][2] = 0;
arr[2][0] = 0; arr[2][1] = 1; arr[2][2] = 0;
对内部成员进行遍历:
int h, l;
for (h = 0; h < sizeof(arr) / sizeof(arr[0]); h++)//arr表示整个二维数组,arr[0]表示第一行的空间大小,相除得到的是数组的行数
{
for (l = 0; l < sizeof(arr[0]) / sizeof(arr[0][0]); l++)//第一行的空间大小除以每个元素的空间得到的是列数
{
printf("%d ", arr[h][l]);
}
printf("\n");
}
对二维数组进行初始化:
int arr1[2][3] = { 1,2,3,4,5,6 };
int arr2[2][3] = { { 1,2,3 } ,{4,5,6 } };
如果有不完全初始化的内容,那就其他位置进行补0操作
int arr3[2][3] = { 1,2,3,4 };
int arr4[2][3] = { { 1 } ,{4,5 } };
尤其注意一下,初始成员的个数时候,行数可以由系统自动算出,但是列行不能省略
5.二维数组的指针
int arr[3][4]={1,2}
首先我们先定义一个指针,int *p;让这个指针p指向二维数组的初始地址,p=&arr[0][0]
对于p的这个指针,因为是按位指的,所以是每次移位是一字节
int arr[3][4]={1,2};
int* p;
p = &arr[0][0];
int i = 0;
for (i = 0; i < 12; i++)
{
/*printf("%d", *p++);*/
printf("%d",*(p+i));
/*printf("%d\n", p[i]);*/
}
所以对这个三部分来说意义是一样的,都是对二维数组进行遍历打印
int arr1[5] = {1,2,3,4,5 };
int arr2[3][4] = { 1,2,3,4,5,6,7,8,9 };
printf("%d %d %d\n", arr1, arr1 + 1, arr1 + 2);//一维数组每进行地址加一,都是加一个字节的变量
printf("%d %d %d\n", arr2, arr2 + 1, arr2 + 2);//二位数组进行加,变化类型的也就是离数组名最近的维度,会变化一行的变量,所以是变化4*4
printf("%d %d %d\n", *(arr1),* (arr1 + 1), *(arr1 + 2));
printf("%d %d %d\n", *(arr2+0), *(arr2+ 1)+1, *(arr2 + 2)+2);// *(arr2+0)这个是相当于取第0行的空间,因为这个是空间,所以表达出的是这个空间的首地址
printf("%d %d \n", *(arr2 + 0), arr2);
************一定不要弄混&arr的意思,这个是表明,对这个arr数组整体整体进行取地址,所以&arr+1不是指arr的地址加一,而是地址横跨这个arr数组的内存大小,arr+1则是指跨行**********
int(*pline)[4]---------定义一个指针,是含有四个字节空间的
int*pline[4]--------里面含有四个指针地址-----int*pline[4]={&a,&b,&c,&d}
-----------------------------------------------------------------------------------------------------------------------
int arr2[3][4] = { 1,2,3,4,5,6,7,8,9 };
int* p;
int(*pline)[4];//定义行指针
p = &arr2[0][0];
pline = arr2 + 0;//*(arr2+0)
printf("%d %d\n", p, pline);
printf("%d %d\n", p+1, pline+1);
for (int j = 0; j < 3; j++)
{
printf("%d %d %d %d\n", (*pline)[0], (*pline)[1], (*pline)[2], (*pline)[3]);
printf("%d\n", *pline++);
}
(*pline)[0]-----表示取pline指向的空间,并且取第0个数,跨度是一行的地址
-------------------------------------------------------------------------------------
行指针遍历
int ge[3][5] = { {1,2},{10,20,30},{111,222} };
int(*p_ge_line)[5];//定义行指针
int h, l;
p_ge_line = ≥//地址指向数组的首地址
for (h = 0; h < 3; h++)
{
printf("%d\n",p_ge_line);//输出当前行指针所指向的行首地址
for (l = 0; l < 5; l++)
{
printf("%d %d\n", (*p_ge_line)[l], ge[h][l]);//对二维数组中的值,进行读取
}
p_ge_line++;//行指针指向下一行
}
--------------------------------------------------------------------------------------------------------------------------
面指针遍历
int ge[3][5] = { {1,2},{10,20,30},{111,222} };
int(*p_ge)[3][5];//设置一个面指针
p_ge = &ge;//指向二维数组的首地址
int h, l;
for (h = 0; h < 3; h++)
{
for (l = 0; l < 5; l++)
{
printf("%d", (*p_ge)[h][l]);//找到面指针指向的空间,进行取空间,然后再找行列对应得值
printf("%d", *(*(*p_ge+h)+l));另一种写法,取二维空间,找到第几行,在取行空间,在找对应的列,再取列空间,就是对应得数值
printf("%d", ge[h][l]);//最常用的写法
printf("%d\n", *(*(ge+h)+l));//另一种写法
}
}