从今天开始,进入C++高级部分了。
1、二维数组
什么是数组?数组,就是多个同类型的元素的有序“组合”。所谓二维数组就是指含有多个数组的数组!
如果把一维数组理解为一行数据,那么,二维数组可形象地表示为行列结构。
二维数组的定义:和数组一样,需要先定义,再使用。
inta[25];//一行女兵
实例:
inta[5][25];//五行女兵
//定义了一个二维数组,
//数组名是“a”,
//包含5行25列,共125元素,//每个元素是int类型的变量
2、二维数组的初始化
inta[3][4];//二维数组元素的值可能是随机的(如果变量没有初始化,全局变量会默认为0,局部变量值随机)
方式一初始化时指定每行的值
inta[3][4]={//等效于inta[][4]
{1,2,3,4},{5,6,7,8},
{9,10,11,12}
};
注:最外围括号内部的每个括号相当于初始化一行,括号中可以省略某些元素的初始化
方式二初始化时从头开始,依次序进行
inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};inta[3][4]={0};//所有元素都初始化为0
注:后面的多个元素可以不指定,不指定全部初始化为0,例如int a[3][4]={1},a[0][0]为1,其余元素默认为0。
#include<stdlib.h>
#include<stdio.h>
intmain(void){
//int ages[5][25];//定义一个二维数组
int i=0,j=0;
//初始化//第一种方式初始化时指定每行的值
int a[3][4]={{1},//省略掉得列会默认置零
{5,6,7},
{9,10,11,12}
};
//第二种方式初始化时从头开始,依次序进行
int a1[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};int a2[3][4]={1};//只初始化第一个,其他得默认置零
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("%d",a[i][j]);
}
printf("\n");
}
system("pause");
return0;
}
3、二维数组的访问
a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
如下图表示,左侧表示的是一个大小为M+1的一维数组,右侧表示的是一个大小为(M+1)*(N+1)的二维数组。
int i=0,j=0;
int a[3][4];
//给数组成员赋值
for(int i=0;i < 12; i++){a[i/4][i%4] = i+1;
}
//或
for(int i=0; i < 3; i++){
for(int j=0; j < 4;j++){a[i][j]=4*i+j+1;
}}
//输出
for(int i=0; i < 3; i++){
for(int j=0; j < 4; j++){
printf("%d",a[i][j]);
}
printf("\n");
}
4、二维数组的存储方式
一维数组是按顺序存储的,二维数组呢?同样也是!
设置断点调试,可以看到二位数组中的所有元素在内存中的存储方式。如下图所示:
左边表示地址,右边表示改地址对应的存储数据,一般我们的变量都是4字节、2字节、1字节,查看的时候根据变量的字节大小调整,由于这里是int类型,因此设置为按4列显示。
5、多维数组
上面讨论的二维数组的相关内容都适用于三维数组或更多维的数组。声明一个三维数组:
int girl[3][8][5];
可以把一维数组想象成一排女兵,把二维数组想象成一个女兵方阵,把三维数组想象成多个女兵方阵。这样,当你要找其中的一个女兵时,你只要知道她在哪个方阵(从0、1、2中选择),在哪一行(从0-7)中选择,在哪一列(从0-4中选择)。
第 5 节 二维数组作为函数的参数
#include <stdio.h>
#include <stdlib.h>
//版本 1 指明参数
void print1(int a[3][4]) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
//版本 1 省略一个高维参数
void print2(int a[][4], int lines) {
for (int i = 0; i < lines; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
int main(void) {
//int arr[3][4]={{},{3,4}};
int a[3][4] = { 0 };
int i = 0;
int j = 0;
//给数组成员赋值
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = 4 * i + j;
}
}
print1(a);
print2(a,3);
}
二维数组作为参数,形参要么写上行数和列数,要么只写列数,但是行数要作为形参传递进去,一般建议在写形参的时候既写上行数又写上列数。
第 6 节 项目精讲-常见错误总结
#include <stdio.h>
#include <stdlib.h>
//int arr[3][4];
void fun(int a[3][4]) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = 0;
}
}
}
int main(void) {
//int arr[3][4]={{},{3,4}};
int a[3][4] = { 0 };
int i = 0;
int j = 0;
//给数组成员赋值
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = 4 * i + j;
}
}
fun(a);
//输出
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
运行结果:
说明数组传递是地址传递而不是只传递!!
完成项目:人工智能之地形导航系统
介绍:2018 年 11 月 26 日,“洞察”号火星探测器在火星上成功着陆,执行人类首次探究火星“内
现在我们要做的就是分析来自地图上的海拔数据,以确定地形中峰点的数目和位置。
项目实现思路:
5039 5127 5238 5259 5248 5310 52995150 5392 5410 5401 5320 5820 53215290 5560 5490 5421 5530 5831 52105110 5429 5430 5411 5459 5630 53194920 5129 4921 5821 4722 4921 51295023 5129 4822 4872 4794 4862 4245
![](https://img-blog.csdnimg.cn/64c61eba9e7f498b9602c274b939af43.png)
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
#define MAX_MAP 64
//判断某点是不是峰点
bool isPeakPoint(int map[MAX_MAP][MAX_MAP], int r, int line);
int main() {
int map[MAX_MAP][MAX_MAP] = { 0 };
int row, col;
string fileName;
ifstream file;
cout << "输入文件名:" << endl;
cin >> fileName;
file.open(fileName.c_str());
if (file.fail()) {
//cerr输出到标准错误的ostream对象,通常用来输出警告和错误信息给程序的使用者
cerr << "打开文件出错!" << endl;
exit(1);//当程序非正常终止时,exit()里面写数字1,正常终止时数字0
}
file >> row >> col;
if (row<0 || row>MAX_MAP || col<0 || col>MAX_MAP) {
cerr << "网格太大,应调整网格大小!" << endl;
}
//从文件读取数据到数组里
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
file >> map[i][j];
}
}
//找出峰点并打印其所在位置
for (int i = 1; i < row - 1; i++) {
for (int j = 1; j < col - 1; j++) {
if (isPeakPoint(map, i, j)) {
cout << "峰点行号:" << i << " 列号:" << j << endl;
}
}
}
file.close();
return 0;
}
bool isPeakPoint(int map[MAX_MAP][MAX_MAP], int r, int line)
{
if (r<0 || r>MAX_MAP || line<0 || line>MAX_MAP) {
cerr << "坐标不合理!" << endl;
exit(1);
}
else {
if ((map[r][line] > map[r - 1][line]) &&
(map[r][line] > map[r + 1][line]) &&
(map[r][line] > map[r][line - 1]) &&
(map[r][line] > map[r][line + 1]))
return true;
}
return false;
}
运行结果:
本项目的思想就是如此,并不是说是那种大项目,因为现在学的知识点不足以开发正式的项目,我们只需把一些项目的思想简化通过编程实现即可。
难点:对文件的输入输出可能有疑问,可以自己补充一下文件输入输出的知识点:
如下: