C++ 数组详解
概述
数组是一个集合,用于存放相同类型的数据元素。
特点 1:数组中的每个数据元素具有相同的数据类型。
特点 2:数组占用一段连续的内存空间。
举个例子,就像城市中的那种高层楼房,占用了一块连续的空间,而且那个楼里边呢每一个屋子基本都是一个类型的,这个就是数组,当然我举的这个例子是一位数组,二维数组呢就像一个棋盘,每一个格子中放的类型都是一样的,还有三维四维五维等等,但是我们都不常用,我也就不去挨个的举例子了
一维数组
定义方式
注 1:数组名的命名规范与变量名命名一致,且数组名不能与变量重名。
注 2:数组的下标/索引从 0 开始。
一维数组定义的 3 种方式:
1. 数据类型 数组名 [ 数组长度 ];
int zty[114514];
注:定义数组时,若未给定数组元素的初始值,则必须指定
初始数组长度,否则提示错误:'不允许使用不完整的类型'。
2. 数据类型 数组名 [ 数组长度 ] = { 值 1,值 2 ...};
int zty[6]={1,1,4,5,1,4};
注:数组初始化时,若大括号{ }内的元素个数小于定义的数组长度,则剩余数组元素 默认使用 0 填充。
3. 数据类型 数组名 [ ] = { 值 1,值 2 ...};
int zty[]={1,1,4,5,1,4};
注:定义数组元素初始值时,数组可以不指定初始数组长度。
来个示例要不然不清楚
#include <iostream>
using namespace std;
int main() {
// 定义方式 1:数据类型 数组名 [元素个数];
int arr[10];
// 使用数组下标对数组元素进行赋值或访问
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
// 定义方式 2:数据类型 数组名 [元素个数] = {值 1,值 2 ,值 3 ...};
// 若大括号{ }内的元素个数小于定义的数组长度,则剩余数据默认使用 0 填充
int arr2[10] = { 100,90,80,70,60,50,40,30,20,10 };
// 定义方式 3:数据类型 数组名 [] = {值 1,值 2 ,值 3 ...};
int arr3[] = { 100,90,80,70,60,50,40,30,20,10 };
return 0;
}
一维数组名
一维数组名称的作用
(1)统计整个数组的长度,例:sizeof(arr) / sizeof(arr[0]);
数组占用内存空间大小:
sizeof(arr)
数组单个元素占用内存空间大小:sizeof(arr[0])
数组长度:sizeof(arr) / sizeof(arr[0])
(2)获取数组在内存中的首地址,例:arr。
获取数组首地址:
arr或&arr[0]。
注:
arr或&arr[0]:数组首元素的地址 ;
&arr:整个数组的地址【地址值相同,含义不同】。
一维数组名的 2 种特例情况
一维数组名不表示数组首元素地址的两种特例:
①
sizeof(数组名):整个数组的大小;
②&数组名:整个数组的地址(地址值与首元素地址相同,但意义不同),表示数组指针。
注:其它情况下,一维数组的数组名均表示数组首元素地址,等价于相应的指针类型。
示例:
#include <iostream>
using namespace std;
int main() {
// 数组名用途
// 1、获取整个数组占用内存空间大小
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << "整个数组所占内存空间为:" << sizeof(arr) << endl;
cout << "每个元素所占内存空间为:" << sizeof(arr[0]) << endl;
cout << "数组的元素个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;
// 2、获取到数组首地址
cout << "数组首地址为:" << (int)arr << endl;
cout << "数组中第一个元素地址为:" << (int)&arr[0] << endl;
cout << "数组中第二个元素地址为:" << (int)&arr[1] << endl;
// arr = 10; // 错误:数组名是常量,不可赋值
return 0;
}
注 1:数组名是常量,不能进行赋值,否则报错:表达式必须是可修改的左值。
注 2:对数组名使用 sizeof,可获取整个数组占内存空间的大小。
一维数组的地址
【以整型一维数组 int arr[n] 为例】
(1) arr等价于&arr[0]
- 表示数组首元素地址,指向数组第 1 个元素,
arr + 1或&arr[0] + 1会跳过第 1 个元素【加上 1 个数组元素的字节数】,指向数组的下 1 个元素。 arr或&arr[0]的地址类型为int *类型,使用int 类型的指针(指向数组首元素的指针)接收。
(2) &arr
- 表示整个数组的地址,指向整个数组,
&arr + 1会跳过整个数组【加上整个数组的总字节数】,如int *p = (int *)(&arr + 1),指针 p 指向数组的末尾。 &arr的地址类型为int (*)[数组长度]类型,使用数组指针(指向数组的指针)接收。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 一维数组
int arr[5] = { 1, 2, 3, 4, 5 };
/* 一维数组的地址与指针 */
int* p1 = (int *)(&arr + 1); // &arr:整个数组的地址
// &arr + 1:指向数组的末尾处
int* p2 = (int*)(arr + 1); // arr 等价于&arr[0],类型为 int * 类型:数组首元素地址
cout << p1[-2] << endl;
cout << *p2 << endl;
cout << arr << endl;
cout << *arr << endl;
cout << arr + 1 << endl;
cout << *(arr + 1) << endl;
cout << &arr[0] << endl;
cout << *(&arr[0]) << endl;
cout << &arr[0] + 1 << endl;
cout << *(&arr[0] + 1) << endl;
cout << &arr << endl;
cout << *(&arr) << endl;
cout << &arr + 1 << endl; // 后移 4*5=20 字节【跳过整个数组】
cout << *(&arr + 1) << endl;
return 0;
}
一维数组的排序
通常的一维数组主要是用 sort 进行排序。
sort
sort 使用起来这非常的简单,只需要一行代码
sort(数组名,数组名 + 数组需要排序的长度,排序方法);
这三个参数我们一个个来讲
第一个参数是数组名,这个好理解这个应该就不需要讲了吧,就是你需要排序的数组名
第二个参数呢,只需要排序的长度,这个地方可以填树也数也可以填变量
第三个参数呢是排序方法,这个是可以不填的,不填的话默认就是从大到小排序,如果是填的话需要单独写一个函数,这个函数呢要有两个参数而且不能是 void 类型,返回值是排序方法
给大家来个示例啊
#include <bits/stdc++.h>
using namespace std;
int cmp(int a, int b) {//这个是从小到大排序
return a > b;
}
int main() {
int zty1[6] = {1, 1, 4, 5, 1, 4};
int zty2[6] = {1, 1, 4, 5, 1, 4};
// 不填第 3 个参数的情况下
sort(zty1, zty1 + 6);
for (int i = 0; i < 6; i++) {
cout << zty1[i] << " ";
}
cout<<endl;
// 填第 3 个参数的情况下
sort(zty2, zty2 + 6, cmp);
for (int i = 0; i < 6; i++) {
cout << zty2[i] << " ";
}
return 0;
}
一维数组呢我们就讲完了,接下来我们讲二维数组
二维数组
二维数组的每个元素均为一个一维数组,可用矩阵的形式表示。
二维数组定义方式
二维数组定义的 4 种方式:
(1)数据类型 数组名 [ 行数 ][ 列数 ];
(2)数据类型 数组名 [ 行数 ][ 列数 ] = { {数据 1,数据 2} ,{数据 3,数据 4} };
(3)数据类型 数组名 [ 行数 ][ 列数 ] = { 数据 1,数据 2,数据 3,数据 4};
(4)数据类型 数组名 [ ][ 列数 ] = { 数据 1,数据 2,数据 3,数据 4};
注 1:第 (2) 种定义方式更直观,可提高代码的可读性;第 (3)、(4)种根据二维数组的列数推断数组元素(可省略行数,不可省略列数)。
注 2:定义二维数组时,若已初始化数据,则可以省略行数。
#include <iostream>
using namespace std;
int main() {
int arr[2][3] = { {1,2,3},{4,5,6} };
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
for (int j = 0; j < sizeof(arr[i]) / sizeof(arr[i][0]); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
二维数组数组名
二维数组名称的作用:
(1)计算二维数组所占内存空间
二维数组占用内存空间大小:
sizeof(arr)
二维数组第 i 行占用内存空间大小:sizeof(arr[i])
二维数组某个元素占用内存空间大小:sizeof(arr[i][j])
(2)计算二维数组的行数与列数
二维数组的行数:
sizeof(arr) / sizeof(arr[0])
二维数组的列数:sizeof(arr[0]) / sizeof(arr[0][0])
(3)获取二维数组的首地址
二维数组首地址:
arr[0]或&arr[0][0]
二维数组第 1 个元素的地址:arr[0]或&arr[0][0]二维数组第 0 行的地址:
arr或arr[0]或arr + 0【或*(arr + 0)】
二维数组第 i 行的地址:arr[i]或arr + i【或*(arr + i)或&a[0] + i】
注:
arr[0]或&arr[0][0]:二维数组首元素的地址 ;
二维数组名arr:二维数组第 0 行(首行)的地址,等价于arr[0]或arr + 0
(4)二维数组的其它地址
二维数组第 i 行首元素的地址:
arr[i]或arr + i或*(arr + i)或&a[0] + i
二维数组第 i 行第 j 列元素的地址:&arr[i][j]或*(arr + i) + j
(5)通过指针解引用访问或操作某元素:*(*(arr + i) + j)
#include <iostream>
using namespace std;
int main() {
int arr[2][3] = { {1,2,3},{4,5,6} };
// 二维数组占用的内存空间
cout << "二维数组大小:" << sizeof(arr) << endl; // 24
cout << "二维数组一行大小:" << sizeof(arr[0]) << endl; // 12
cout << "二维数组元素大小:" << sizeof(arr[0][0]) << endl; // 3
// 二维数组的行数与列数
cout << "二维数组行数:" << sizeof(arr) / sizeof(arr[0]) << endl; // 2
cout << "二维数组列数:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl; // 3
// 地址
cout << "二维数组首行地址:" << (int)arr << endl;
cout << "二维数组第一行地址:" << (int)arr[0] << endl;
cout << "二维数组第一个元素地址:" << (int)&arr[0][0] << endl;
cout << "二维数组第二行地址:" << ()arr[] << endl;
cout << << ()&arr[][] << endl;
;
}
二维数组的地址
【以整型二维数组 int arr[m][n] 为例】
(1) arr[0]等价于&arr[0][0]
1,表示二维数组首元素地址,指向二维数组第 0 行第 0 列元素, arr[0] + 1等价于&arr[0][0] + 1会在二维数组第 0 行跳过第 1 个元素【加上 1 个数组元素的字节数】,指向二维数组第 0 行的下 1 个元素。
2,arr[0]或&arr[0][0]的地址类型为 int * 类型,使用int 类型的指针(指向数组第 0 行首元素的指针)接收。如 int *p = arr[0];或int *p = &arr[0][0];。
(3) &arr
1,表示整个二维数组的地址,指向整个二维数组,&arr + 1会跳过整个二维数组【加上整个二维数组(共 m * n 个元素)的总字节数】,指向数组的末尾。
2,&arr的地址类型为 int (*)[数组行数][数组列数] 类型,使用二维数组指针(指向数组的指针)接收。如 int (*p)[3][4] = &arr;。
示例:
#include <iostream>
using namespace std;
int main() {
// 二维数组 3 行 4 列
int arr[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
cout << &arr << endl; // 整个二维数组的地址
cout << &arr + 1 << endl; // 后移 4*3*4=48 字节【跳过整个二维数组的全部 12 个元素】
cout << arr << endl; // 二维数组第 0 行的地址
cout << arr + 1 << endl; // 后移 4*4=16 字节【跳过二维数组 1 行共 4 个元素】
cout << arr[1] << endl; // 后移 4*4=16 字节【跳过二维数组 1 行共 4 个元素】
cout << &arr[0] + 1 << endl; // 后移 4*4=16 字节【跳过二维数组 1 行共 4 个元素】
cout << *(arr + 1) << endl;
// 二维数组第 1 行首元素的地址
cout << *(arr + 1) + 1 << endl; // 后移 4 字节【跳过 1 个元素】
cout << arr[0] << endl; // 二维数组首元素地址
cout << arr[0] + 1 << endl; // 后移 4 字节【跳过 1 个元素】
cout << &arr[0][0] << endl; // 二维数组首元素地址
cout << &arr[0][0] + 1 << endl;
(*p1)[] = arr;
(*p2)[] = &arr[];
(*p)[][] = &arr;
;
}


