1、该系列为ACWing中c++语法课,已购买正版,课程作者为yxc(请大家支持正版)。
2、为啥写在这儿,问就是oneNote的内存不够了QAQ
ACwing C++ 语法笔记4数组
1. 一维数组
1.1 数组的定义
数组的定义方式和变量类似。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[10], b[10];
float f[33];
double d[123];
char c[21];
string g[15];
return 0;
}
1.2 数组的初始化
在main函数内部,未初始化的数组中的元素是随机的。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[3] = {0, 1, 2}; // 含有3个元素的数组,元素分别是0, 1, 2
int b[] = {0, 1, 1}; // 维度是3的数组
int c[5] = {0, 1, 2}; // 等价于c[] = {0, 1, 2, 0, 0}
char d[] = {'a', 'b', 'c'}; // 字符数组的初始化
int f[10] = {0}; // 定义一个值全部为0的数组
return 0;
}
- 凡是定义在函数内部的变量(局部变量),值都是随机的。因此定义在函数内部的数组,值也是随机的。
#include <iostream> using namespace std; int main() { int a[100]; for (int i = 0; i<100; i++){ cout << a[i] << endl; //1142008024/32670/1151542512/32670/0/0... } return 0; }
- 一般C++默认的栈空间是1MB,如果开一个100万的数组(int类型需要4MB),那么栈空间不够大,就会报运行时错误或段错误。
- 解决方法,将数组定义为全局变量(函数外面)。全局变量会放到堆空间中,除内存限制外没有任何长度限制。
- 定义到函数外面的变量默认一定都是0。
1.3 访问数组元素
通过下标访问数组。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[3] = {0, 1, 2}; 数组下标一定从0开始
cout << a[0] << ' ' << a[1] << ' ' << a[2] << endl;
a[0] = 5;
cout << a[0] << endl;
return 0;
}
-
练习题1: 使用数组实现求斐波那契数列的第 N 项。
#include <iostream> #include <algorithm> using namespace std; int main() { int n; int f[100]; cin >> n; f[0] = 0, f[1] = 1; for (int i = 2; i <= n; i ++ ) f[i] = f[i - 1] + f[i - 2]; cout << f[n] << endl; return 0; }
-
练习题2:输入一个 n,再输入 n 个整数。将这 n 个整数逆序输出。
#include <iostream> #include <algorithm> using namespace std; int main() { int n; int a[100]; cin >> n; for (int i = 0; i < n; i ++ ) cin >> a[i]; for (int i = n - 1; i >= 0; i -- ) cout << a[i] << ' '; cout << endl; return 0; }
-
练习题3:输入一个 n,再输入 n 个整数。将这个数组顺时针旋转
k
(k≤n)次,最后将结果输出。 -
reverse(a, a+k)
函数,a
是翻转的起始索引位置,a+k
是终止位置的下一个索引位置(共k个数)。 -
翻转字符串的用法为:
string str = "abcdefg";
reverse(str.begin(), str.end());
#include <iostream> #include <algorithm> using namespace std; int main() { int n, k; int a[100]; cin >> n >> k; for (int i = 0; i < n; i ++ ) cin >> a[i]; reverse(a, a + k); 定义a是数组第一个元素的地址; reverse(a + k, a + n); reverse(a, a + n); for (int i = 0; i < n; i ++ ) cout << a[i] << ' '; cout << endl; return 0; }
-
练习题4:输入 n 个数,将这 n 个数按从小到大的顺序输出。
#include <iostream> #include <algorithm> using namespace std; int main() { int n; int a[100]; cin >> n; for (int i = 0; i < n; i ++ ) cin >> a[i]; for (int i = 0; i < n; i ++ ) for (int j = i + 1; j < n; j ++ ) if (a[i] > a[j]) swap(a[i], a[j]); for (int i = 0; i < n; i ++ ) cout << a[i] << ' '; cout << endl; return 0; }
-
练习题5:计算 2 的 N 次方,N≤10000(3000位)。int大小有限制,最多10位,double最多15-16位。肯定存不下来,因此用数组来表示一个整数,数组中每一位是数字中的每一位(如将1234567891234算加减乘的时候存为
{4,3,2,1,9,8,7,6,5,4,3,2,1}
,算除的时候存为{1,2,3,4,5,6,7,8,9,1,2,3,4}
)。算加减的时候会有进位,而在数组的a[0]
位置加数据(进位)非常困难,因此个位存在前面。 -
数字x的位数是 log 10 x \log_{10}x log10x
#include <iostream> #include <algorithm> using namespace std; int main() { int a[10000], size = 1, n; a[0] = 1; cin >> n; while (n -- ) { int t = 0; for (int i = 0; i < size; i ++ ) { t += a[i] * 2; a[i] = t % 10; t /= 10; } if (t) a[size ++ ] = t; } for (int i = size - 1; i >= 0; i -- ) cout << a[i]; cout << endl; return 0; }
2. 多维数组
多维数组就是数组的数组。
int a[3][4]; // 大小为3的数组,每个元素是含有4个整数的数组。
int arr[10][20][30] = {0}; // 将所有元素初始化为0
// 大小为10的数组,它的每个元素是含有20个数组的数组
// 这些数组的元素是含有30个整数的数组
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int b[3][4] = { // 三个元素,每个元素都是大小为4的数组
{0, 1, 2, 3}, // 第1行的初始值
{4, 5, 6, 7}, // 第2行的初始值
{8, 9, 10, 11} // 第3行的初始值
};
return 0;
}
- 练习题:输入一个 n 行m列的矩阵,从左上角开始将其按回字形的顺序顺时针打印出来。
#include <iostream> #include <algorithm> using namespace std; int main() { int n, m; int arr[50][50]; cin >> n >> m; for (int i = 0; i < n; i ++ ) for (int j = 0; j < m; j ++ ) cin >> arr[i][j]; bool st[50][50] = {false}; int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; int d = 1, x = 0, y = 0; for (int i = 0; i < n * m; i ++ ) { int a = x + dx[d], b = y + dy[d]; if (a < 0 || a >= n || b < 0 || b >= m || st[a][b]) { d = (d + 1) % 4; a = x + dx[d], b = y + dy[d]; } cout << arr[x][y] << ' '; st[x][y] = true; x = a, y = b; } cout << endl; return 0; }
3.数组的清空
-
用于清空数组的
memset
函数在<cstring>
库中。 -
第一个参数是数组名
a
;第二个参数是要初始化的值;第三个参数是需要初始化的数组长度(a
是从0开始)。 -
memset
所有的单位都是字节Byte的数量而不是int的数量(1Byte=8bit)。平常说的1KB(1024Byte),1MB(1024KB)都是Byte。 -
memset
不是把数组赋成0,而是把数组中的每个字节赋成0。如果初值设置为1,最终显示的数组的数并不是1,而是16843009(0000 0001 0000 0001 0000 0001 0000 0001)。 -
一般设置为全0数组
memset(a, 0, 40)
或全负1数组memset(a, -1, 40)
。 -
求某一个数组的字节数量
sizeof a
(不是函数,不用括号)。#include <iostream> #include <cstring> using namespace std; int main() { int a[10], b[10]; memset(a, 0, 40); memset(b, -1, sizeof b); for(int i=0; i <10; i++) cout<< a[i]<< ' '; cout << endl; for(int i=0; i <10; i++) cout<< b[i]<< ' '; return 0; }
4.数组的复制
-
把a复制给b:memcpy(b)函数,参数一是复制的目标数组的变量,参数二是原数组是多少,参数三是复制多长。
#include <iostream> #include <cstring> #include <cmath> using namespace std; int main() { int a[10], b[10]; for (int i=0; i<10; i++) a[i] = i; memcpy(b, a, sizeof a); for(int i=0; i<10; i++) cout << b[i] << ' '; return 0; }