C++语言程序设计——06 数组
目录
一、数组的定义
数组是存储同一种数据类型的多个变量的集合,一个数组只能有一种数据类型,
数据类型 数组名[数组长度];
以下是一个一维数组和二维数组,二维数组可以理解成 X 行 X 列的矩阵:
int a[10];
int b[10][10];
同时定义数组后,也可以修改数组元素,例如通过输入修改元素值:
int a[10] = {1,2,3,4,5,6,7};
cin >> a[4]; // 通过输入修改第5个元素,即 6
例如,int b[10][10] 是定义了一个名为 b 的二维数组,用于存储 10 行 10 列 的整数数据,总共可容纳 10×10=100 个 int 类型值(需手动初始化或赋值),如下图:

二、数组的初始化
要注意数组元素的初始化,如果只对数组的部分元素赋初始值,则其他未赋值的初始值自动会设置为 0 。
int a[5] = {}; // 全部元素初始化为0
int b[] = {1, 2, 3}; // 数组大小是3,包含3个元素:1, 2, 3
int c[10] = {1, 2, 3}; // 前3个是1,2,3,后面7个自动为0
示例如下:
#include<iostream>
using namespace std;
int main()
{
int a[10]; // 定义一个包含10个int元素的数组,未初始化
int b[5]={1,2,3}; // 定义包含5个元素的数组,只初始化前3个,未初始化的后2个元素会被自动设为 0
int c[5]={1,2,3,4,5};
int d[]={1,2,3,4,5}; // 不指定数组大小,
cout << b << endl << *b; // b表示数组首元素的地址,*b表示取数组首元素的值(相当于b[0])
return 0;
}
运行结果如下,输出的第一个值是数组 b 的首地址(十六进制形式),而第二个值是数组 b 第一个元素的值,*b表示取数组首元素的值,相当于b[0]:
三、数组的遍历
通常数组的遍历采用 for 循环,让循环变量 i 从0开始到小于数组的长度,这样循环体内最大的 i 正好是数组最大的有效下标。
如果需要将一个数组的所有元素给另一个元素,可以采用遍历:
for(int i = 0 ; i < length ; i++)
{
b[i] = a[i];
}
二维数组的遍历可以通过两层 for 循环实现,例如下面代码,给数组每个元素赋值,赋值规则为 a[i][j] = i * j(即第 i 行第 j 列的元素值等于行下标与列下标的乘积):
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int a[3][5]; // 声明3行5列的二维数组a
for(int i = 0 ; i < 3 ; i++)
{
for(int j = 0 ; j < 5 ; j++)
{
a[i][j] = i * j; // 给数组元素赋值:值为行下标i与列下标j的乘积
}
}
return 0;
}
四、数组的应用
(一)数组元素依次输入输出
例如,a[101] 是表示数组的下标(用于访问单个元素)从 0 开始,到 100 结束(即 a[0]、a[1]、a[2]、……、a[100]),一共101个元素。下面代码中,定义了一个能存储 101 个整数的数组 s,通过循环输入 101 个整数到数组中,再通过循环将这 101 个整数逐个输出(每个数占一行):
#include <iostream>
using namespace std;
int s[100];
int main()
{
for(int i =0;i<100;i++)
cin>>s[i];
for(int i =0;i<100;i++)
cout<<s[i]<<endl;
return 0;
}
也可以改进成范围 for 循环,但是要注意输入时必须用引用 &。
因为,范围 for 循环中,如果直接写 int num : s,num 只是数组元素的副本,修改 num 不会改变原数组。加上 & 后,num 成为原数组元素的引用,才能通过 cin >> num 修改数组:
#include <iostream>
using namespace std;
int s[101];
int main()
{
// 范围 for 循环输入(需要用引用 & 才能修改数组元素)
for (int &n : s) // & 表示引用,否则只能读取不能修改
cin >> n;
// 范围 for 循环输出(无需引用,只读即可)
for (int n : s)
cout << n << endl;
return 0;
}
(二)复制数组
例如,复制数组 A 的元素到 数组 B ,可以通过 for 循环实现:
#include <iostream>
using namespace std;
int main()
{
int A[10] = {1, 2, 3, 3, 4, 5, 6, 7, 8, 9};
int B[10];
for(int i=0; i<10; i++)
{
B[i] = A[i];
}
for(int i=0; i<10; i++)
{
cout << B[i] << " ";
}
return 0;
}

也可以通过导入 algorithm 库,使用 rotate() 函数:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, x, a[100];
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
cin >> x;
x = x % n; // 处理x大于n的情况
rotate(a, a + n - x, a + n);
for(int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}

(三)移动数组元素
例如,移动数组元素 x 位,通过 for 循环完成。每次右移1位,重复 x 次即可。每次保存最后一个,其他元素后移,再把最后一个放数组第一个。如下代码:
#include <iostream>
using namespace std;
int main()
{
int n, x, a[100];
cin >> n;
for(int i=0; i<n; i++)
{
cin >> a[i];
}
cin >> x; // 向右移动 x 位
x = x % n; // 处理 x 大于 n 的情况
for(int j=0; j<x; j++) // 循环右移 x 次,每次右移 1 位
{
int temp = a[n-1]; // 保存最后一个元素
for(int i=n-1; i>=1; i--) // 向右移动 1 位
{
a[i] = a[i-1];
}
a[0] = temp; // 把之前最后一个元素放到第一个位置
}
for(int i=0; i<n; i++)
{
cout << a[i] <<" ";
}
return 0;
}
也可以使用 algorithm 库的 rotate() 函数直接进行移动:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, x, a[100];
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
cin >> x;
x = x % n; // 处理x大于n的情况
rotate(a, a + n - x, a + n);
for(int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}

如果需要左移,需要修改每次保留的元素,右移是保存最后一个元素,左移需要保存第一个元素,同时 for 循环也要更改,从前往后移动,从 0开始,到 i < n-1。最后,是元素需要向前移动以及将元素放到最后一个位置。
#include <iostream>
using namespace std;
int main()
{
int n, x, a[100];
cin >> n;
for(int i=0; i<n; i++)
{
cin >> a[i];
}
cin >> x; // 现在改为:向左移动 x 位
x = x % n; // 处理 x 大于 n 的情况
for(int j=0; j<x; j++) // 循环左移 x 次,每次左移 1 位
{
int temp = a[0]; // 保存第一个元素(修改这里)
for(int i=0; i<n-1; i++) // 向左移动 1 位(修改这里)
{
a[i] = a[i+1]; // 元素向前移动(修改这里)
}
a[n-1] = temp; // 把原第一个元素放到最后一个位置(修改这里)
}
for(int i=0; i<n; i++)
{
cout << a[i] <<" ";
}
return 0;
}
左移,如果使用 rotate()函数 ,需要更改 为 rotate(a, a + x, a + n)。
(四)动态分配数组
在 C++ 中,动态分配数组最简单的方法是使用 new 关键字,步骤如下:
①确定数组大小;
②用 new 关键字分配对应类型和大小的数组;
③使用数组;
④最后用 delete[] 来释放内存,避免泄漏。
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n; // 确定数组大小
int* arr = new int[n]; // 动态分配int数组(最简单方式)
// 使用数组(示例:赋值并输出)
for (int i = 0; i < n; i++)
{
arr[i] = i * 10; // 赋值
cout << arr[i] << " "; // 输出
}
delete[] arr; // 释放动态分配的内存
return 0;
}
(五)输出不包括某个元素(排除元素)
在数组中,如果我们要输出某个不包括该元素的数组,可以通过条件语句进行判断:
for(int i = 1; i <= n; i++)
{
if(a[i]!=s) // 循环数组,只输出那些不等于s的元素
cout << a[i] << " ";
}
(六)判断回文数(逆转数组)
另外,如果我们想判断一个输入的数是不是回文数,可以先进行逆转,然后再判断,其中在判断回文数组时,只需要比较前半部分和后半部分对应位置的元素,不需要重复比较:
当n=5(奇数)时,n/2=2,循环执行 2 次(比较第 0 与 4、1 与 3,中间的 2 无需比较)
当n=4(偶数)时,n/2=2,循环执行 2 次(比较第 0 与 3、1 与 2)
#include<iostream>
using namespace std;
int n,a[100];
int main()
{
cin >> n; // 输入数字有多少位
for(int i = 0; i < n; i++)
cin >> a[i];
for(int i = 0; i < n/2; i++) //只需要比较前半部分和后半部分对应位置的元素
{
if(a[i] != a[n-1-i])//使用第i个元素和第n-1-i个元素(因为 0 开始的最后一个元素索引是n-1)
{
cout << "NO";
return 0;
}
}
cout << "YES";
return 0;
}
如果不用数组,也可以直接通过循环以及取余实现判断回文数:
int n;
cin >> n;
int temp = n; // 临时变量,用来反转
int rev = 0; // 用来存反转后的数
// 把数字反转
while(temp > 0)
{
int last = temp % 10; // 取最后一位
rev = rev * 10 + last; // 拼到反转数里
temp = temp / 10; // 删最后一位
}
if(rev == n){
cout << "YES";
}
else{
cout << "NO";
}
(七)获取数组中最大值元素
例如,下面代码中,读取一组整数存储到数组中,再找出其中的最大值以及该最大值第一次出现的位置(从 1 开始计数),并输出结果:
#include <iostream>
using namespace std;
int main()
{
int n,a[100],max=0,max_num=0;
cin >> n;
for(int i=0;i<n;i++)
cin>>a[i]; // 循环读取n个整数,存入数组a中
for(int i=0;i<n;i++) // 遍历数组
{
if(a[i]>max) // 若当前元素大于当前记录的最大值
{
max=a[i]; // 更新最大值为当前元素
max_num=i; // 记录当前元素的下标(从0开始)
max_num++; // 将下标+1,转为从1开始的位置计数
}
}
cout <<max<<endl<<max_num;
return 0;
}
运行结果如下:
这里在用 for 循环遍历数组时,只有当遇到大于当前 max 的元素时,才会更新 max 和 max_num。从而,保证了 max_num 最终记录的是第一个最大值的位置(后续出现的相等最大值不会触发更新)。
(八)字符串比较是否相等
通过定义两个字符串数组,进行比较两个字符串是否相等,如果相等输出YES,否则输出NO:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char a[100], b[100];
cin.getline(a, 100); //读取一行
cin.getline(b, 100);
if (strcmp(a,b)==0) // 使用strcmp()函数
cout << "YES";
else
cout << "NO";
return 0;
}
(九)字符串删除某字符(空格为例)
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char str[] = " Hello World C++ ";
int j = 0; // 新字符串的索引
for(int i = 0; str[i]; i++) {
if(str[i] != ' ') { // 如果不是空格
str[j] = str[i]; // 复制到前面
j++;
}
}
str[j] = '\0'; // 添加字符串结束符
cout << str ;
return 0;
}
(十)字符串转换大小写
#include <iostream>
#include <cctype> // 包含字符处理函数(tolower)
using namespace std;
int main()
{
char a[10]="AAAadd"; // 数组大小10,实际使用6个字符+1个'\0'
char b[10]="dfGERS";
for (int i = 0; a[i] != '\0'; i++) // 遇到 '\0'(字符串结束符)时停止循环,将字符串a中的所有字符转换为小写
a[i] = tolower(a[i]); // 将每个字符转换为小写
for (int i = 0; b[i] != '\0'; i++)
b[i] = tolower(b[i]);
cout << a << endl << b;
return 0;
}

更多推荐



所有评论(0)