C++数组
c++数组
数组是用来存储相同类型的变量的顺序集合。
所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
type arrayName [ arraySize ][arraySize1]; arraySize必须是一个大于等于零的整数常量。
一维数组
声明和初始化
- 存储数组类型
- 数组名字
- 数组中元素个数
type arrayName [ arraySize ];
// 整型数组
int array[12]; // 声明,数据长度
array[0]=0;
array[1]=1;
array[2]=2;
int array2[3]={20,30,5}; // 声明+初始化
编译器不会检测使用下标是否有效
int arr[10]; //arr是含有10个整型的数组
int arr[10]={}; //arr是含有10个整型的数组,进行了初始化,每个元素的值都是10
int *arr[10]; //arr是含有10个整型指针的数组
int arr[] = {1,2,3}; //arr是含有3个整型的数组
int arr[5] = {1,2,3}; //等价于int arr[5] = {1,2,3,0,0}
string arr[3] = {"hello","world"}; //等价于 string arr[3] = {"hello","world",""};
char arr[6] = "hello"; // 这里不能声明维度为5,因为字符串末尾还有一个空字符('\0'),所以应该是"hello\0"
char arr[6] = {'h','e','l','l','o','\0'}; //等价于 char arr[] = "hello";
char arr[6] = {'h','e','l','l','o'}; //这条语句和上面一条语句是一样的。默认字符初始化值是'\0'
字符串数组
//字符串数组
char str[] = "hello world!";
//与字符串的区别
//字符串 string类
string ss=("hello wrld!");
字符串数组的长度
//字符串数组的长度
char str[] = "hello world!";
int len = strlen(str);
cout << len << endl;
//另外一种结构
int len = sizeof(str) / sizeof(str[0]); //算结尾的'/0'
cout << len << endl;
访问数组中元素
int myNum[6] = {89,85,90,75,69,95};
cout << myNum[0] << endl;
// 输出89
修改数组数据
int myNum[6] = {89,85,90,75,69,95};
cout << myNum[0] << endl;
myNum[0] = 100;
cout << myNum[0] << endl;
//89
//100
遍历数组
#include <cstddef>
#include <iostream>
using namespace std;
//下标法
int main(){
size_t size = 20;
int arr[size] = {};
for(size_t index=0; index < size; index++){
cout << arr[index] << " ";
}
cout << endl;
return 0;
}
// 直接结果
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#include <iostream>
#include <iomanip>
using namespace std;
using std::setw;
int main() {
int n[5]; // n 是一个包含 10 个整数的数组
// 初始化数组元素
for (int i = 0; i < 5; i++) {
n[i] = i + 100; // 设置元素 i 为 i + 100
}
cout << "Element" << setw(13) << "Value" << endl;
// 输出数组中每个元素的值
for (int j = 0; j < 10; j++) {
cout << setw(7) << j << setw(13) << n[j] << endl;
}
return 0;
}
// 执行结果
Element Value
0 100
1 101
2 102
3 103
4 104
C++新标准提供了auto关键字
double prices[] = {5.99, 3.2, 9.99, 29.99};
for(double x: prices) {
cout << x << endl;
}
for(auto a : arr)
cout << a << " ";
指针遍历取值
#include <iostream>
using namespace std;
int main(){
int nums[]={0,1,2,3,4,5,6,7,8,9};
int i;
for(i=0;i<=9;i++){
cout << *(nums + i)<< endl;
// 这种写法和下标法其实是等价的,下标法也会转换为 * (nums + i),这种写法更加接近底层
}
return 0;
}
指针变量指向数组元素
#include <iostream>
using namespace std;
int main(){
int nums[]={0,1,2,3,4,5,6,7,8,9};
int *p;
for(p = nums;p<=(nums + 9);p++){
cout << *p << endl;
}
return 0;
}
多维数组
定义和初始化
当一个数组中的元素依然是一个数组时,通常使用两个维度来定义它。
二维数组,大小为m的数组,每个数组的元素都是大小为n的数组。
三维数组,大小为m的数组,每个数组的元素都是大小为n的数组,然后大小为n的数组中的每个元素又是大小为q的数组。
int arr1[m][n];
int arr2[m][n][q];
int arr[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
该数组有两个维度,3行和4列。
使用数组的行索引和列索引可以访问数组元素:
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
cout << seats[1][2];
嵌套循环遍历
#include <iostream>
using namespace std;
int main() {
// 一个带有 5 行 2 列的数组
int a[3][4] = {
{0, 1, 2, 3}, /* 初始化索引号为 0 的行 */
{4, 5, 6, 7}, /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
// 输出数组中每个元素的值
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
// 执行结果
0 1 2 3
4 5 6 7
8 9 10 11
指针数组
指针和数组
在c/c++语言中,数组和指针有着非常紧密的联系,在使用数组编译的时候通常会把它转化为它的第一个元素的指针。
string nums[] = {"one","two","three"};
string *p = &nums[0]; //定义了一个指针
string *p2 = nums; //定义了一个指针
p和p2其实等价的,都是表示指向nums首元素的指针。
&a表示数组地址,其结果是指向该数组的指针。
&a[0]表示数组首元素的地址,其结果是指向该数组首元素的指针。
int *ptrs[10]; //声明了一个数组,含有10个整形指针
int (*ptr)[10] = &arrar; //ptr是一个指向数组的指针
int (&ref)[10] = array; //ref是一个数组的引用
int *(&ref)[10] = array; //ref是一个元素为指针的数组的引用
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[3][4] = { { 0, 1, 2, 3 },{ 4, 5, 6, 7 },{ 8, 9, 10, 11 } };
int(*p)[4];
p = a;
printf("%d,%d,%d,%d\n", sizeof(*(p)),sizeof(*(p + 1)),sizeof(*(p + 2)),sizeof(*(p + 3)));
printf("%d\n", **p);//a[0][0]
printf("%d\n", *(*(p + 1)));//a[1][0]
system("pause");
return 0;
}
动态数组
数组大部分情况下是知道数组长度的,一旦定义了数组,系统会为他分配一个固定大小的内存,以后不能改变,这种数组叫做静态数组。
动态数组是从堆上分配的空间,在执行过程中进行分配,所以叫做动态数组。
动态数组的内存由程序员申请,所以应该由程序员手动释放。
int n;
scanf("%d",&n); //手动输入数组长度
int* parr = new int[n]; //动态申请数组内存
...... //进行必要的操作
delete[] parr; //手动释放申请的内存