为什么需要数组
对应某种同类型的存储 是分开储存的
int nValue1=520;
int nValue2=1314;
...
对于同类型的储存,以上方法是比较冗余的
所以发明了数组,去存储同类型的数据
简化以上操作
int Ary[]={520,1314,...};
int main(int argc, char argv[])
{
int Arry[] = {100, 200, 3,5 };
for (size_t i = 0; i < 4; i++)
{
printf("%d\r\n", Arry[i]);
}
return 0;
}
这样就定义了5个int类型的数据
对特定的数值进行 修改
数组名+下标=修改的值
注意数组的下标是从0开始的
int main(int argc, char argv[])
{
int Arry[10] = {100, 200, 3,5 ,};
for (size_t i = 0; i < sizeof(Arry)/sizeof(Arry[0]); i++)
{
printf("%d\r\n", Arry[i]);
}
return 0;
}
对于没有明确给定的值,就会赋值为0
数组一旦初始化,没有机会进行数组的批量赋值
数组名就是数组的首地址
int main(int argc, char argv[])
{
int Arry[10] = {100, 200, 3,5 };
printf("%p,%p", Arry, &Arry[0]);
return 0;
}
sizeof计算 数据类型或者变量大小
当sizeof的对象是数组名时候,是整个数组的大小
int main(int argc, char argv[])
{
int Arry[3][3] = {
1, 2, 3,
3, 4, 5,
6, 7, 8,
};
int Arry2[3] = {
1,
2,
3,
};
printf("%d\r\n", sizeof(Arry));
printf("%d\r\n", sizeof(Arry2));
return 0;
}
Arry大小4x9=36;
Arry2大小3x4=12;
所以根据这个原理,可以计算数组的元素个数。
int ArySize=sizeof(Arry);//总的数组大小
int AryCount=sizeof(Arry[0]);// 单个数组大小
int AryItem=ArySize/AryCount;// 元素个数
但是数组是可以越界的
如果定义为3个元素
但是用第4个元素
char cArry[3]={0};
char c=cArry[4];
是不可未知的,随机地址
超过太多就会崩溃
int main(int argc, char argv[])
{
int Arry2[] = {
1,
2,
3,
};
printf("%p\r\n", Arry2);//0019FF04
printf("%p\r\n", &Arry2[0]);
printf("%p\r\n", &Arry2[1]);
printf("%p\r\n", &Arry2[2]);
printf("%p\r\n", &Arry2[3]);
printf("\r\n");
printf("%p\r\n", &Arry2[-1]);
printf("%p\r\n", &Arry2[-2]);
printf("\r\n");
printf("%p\r\n", &2[Arry2]);
return 0;
}
对于 数组地址如果超过了数组的范围,还是会按规律去计算。
即使是负数 也是从首地址开始计算。
对于调换位置,其实对于寻址是不影响的
对于type以及小标为i的寻址计算
&nArry2[i]=nArry2+i*sizeof(type)
以上以上是数学意义,在C语言中,编译器其实已经帮助我们将i乘以了sizeof(type) 使得我们可以更方便的使用数组。
所以可以理解
&nArry[-2]=nArry + (-2)*sizeof(type);
&2[nArry]=nArry + (2)*sizeof(type);
当我们将数组当作参数传参的时候,传过去的是首地址 (地址占 4个字节)
而不是数组的所有内容传过去
void MyFun(int Arry[])
{
printf("%d\r\n", sizeof(Arry));
}
int main(int argc, char argv[])
{
int Arry2[] = {
1,
2,
3,
};
printf("%d\r\n", sizeof(Arry2));
MyFun(Arry2);
return 0;
}
对于传过去是地址所以可以进行,更改内容,地址是不变的,所以不会被当作局部变量释放掉
void MyFun(int Arry[])
{
Arry[2] = 111;
printf("%d\r\n", sizeof(Arry));
}
int main(int argc, char argv[])
{
int Arry2[] = {
1,
2,
3,
};
printf("%d\r\n", sizeof(Arry2));
MyFun(Arry2);
printf("%d\r\n", Arry2[2]);
return 0;
}
由上面图可以知道,行是可以自动计算的,但是列是不可以的;
由此可以推知 寻址公式与初始化的列数有关
int main(int argc, char argv[])
{
int Arry3[][3] = {
1, 2, 3,
4, 5, 6,
7, 8, 9,
};
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 3; j++)
{
printf("%d\t", Arry3[i][j]);
}
printf("\n");
}
return 0;
}
所以从以上 推理 可以得到公式
对于一个type类型的 M行 N列的数组寻址
&Ary[i][j]=Ary+(i*N+j)*sizeof(type); //是与总列数有关,所以定义的时候 必须定义列数
其实二维数组是特殊的一维数组
int nArry[3];// int[3] nArry
int nArry[2][3];//int [3] nArry[2]
int main(int argc, char argv[])
{
int Arry3[][3] = {
1, 2, 3,
4, 5, 6,
7, 8, 9,
};
printf("%p\r\n", Arry3);
printf("%p\r\n", &Arry3[0]);
printf("%p\r\n", &Arry3[0][1]);
printf("%p\r\n", &Arry3[0][2]);
printf("%p\r\n", &Arry3[1][0]);
return 0;
}
在一个项目中都遵从MVC模式
工程模块划分的意识
Model.h
Model.cpp
View.h
View.cpp
.h文件是申明
.cpp是实现代码
头文件的前面应该加入
#pragma once
全局变量的声明要放在头文件中 用关键字extern
extern char g_chBackGround[GAME_ROW][GAME_COL];