C++ 数组基础

C++C++Beginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习 C++ 中的数组。你将学习如何定义和初始化数组,以及如何使用数组函数。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL cpp(("C++")) -.-> cpp/ControlFlowGroup(["Control Flow"]) cpp(("C++")) -.-> cpp/AdvancedConceptsGroup(["Advanced Concepts"]) cpp(("C++")) -.-> cpp/IOandFileHandlingGroup(["I/O and File Handling"]) cpp(("C++")) -.-> cpp/BasicsGroup(["Basics"]) cpp/BasicsGroup -.-> cpp/variables("Variables") cpp/BasicsGroup -.-> cpp/data_types("Data Types") cpp/BasicsGroup -.-> cpp/arrays("Arrays") cpp/BasicsGroup -.-> cpp/strings("Strings") cpp/ControlFlowGroup -.-> cpp/for_loop("For Loop") cpp/ControlFlowGroup -.-> cpp/while_loop("While Loop") cpp/AdvancedConceptsGroup -.-> cpp/references("References") cpp/IOandFileHandlingGroup -.-> cpp/output("Output") cpp/IOandFileHandlingGroup -.-> cpp/user_input("User Input") subgraph Lab Skills cpp/variables -.-> lab-178535{{"C++ 数组基础"}} cpp/data_types -.-> lab-178535{{"C++ 数组基础"}} cpp/arrays -.-> lab-178535{{"C++ 数组基础"}} cpp/strings -.-> lab-178535{{"C++ 数组基础"}} cpp/for_loop -.-> lab-178535{{"C++ 数组基础"}} cpp/while_loop -.-> lab-178535{{"C++ 数组基础"}} cpp/references -.-> lab-178535{{"C++ 数组基础"}} cpp/output -.-> lab-178535{{"C++ 数组基础"}} cpp/user_input -.-> lab-178535{{"C++ 数组基础"}} end

内容预览

数组通常用于存储相同类型的数据。它们高效、紧凑且易于访问。结合循环,对数组中元素的操作非常简单。

要创建一个数组,你需要提前知道数组的长度(或大小),并相应地分配内存。一旦数组被创建,其长度是固定的,无法更改。

图片描述

数组的声明与使用

假设你想计算一个班级 30 名学生的平均分数,你肯定不希望创建 30 个变量:mark1mark2、……、mark30。相反,你可以使用一个名为 数组 的变量,它包含 30 个元素。

数组是 相同类型元素的列表,由一对中括号 [ ] 标识。要使用数组,你需要用 3 个要素来 声明 数组:名称类型维度(或 大小长度)。我们建议为数组使用复数形式的名称,例如 marksrowsnumbers。例如:

int marks[5];        // 声明一个包含 5 个元素的 int 数组,名为 marks
double numbers[10];  // 声明一个包含 10 个元素的 double 数组
const int SIZE = 9;
float temps[SIZE];   // 使用 const int 作为数组长度

// 某些编译器支持使用变量作为数组长度,例如:
int size;
cout << "Enter the length of the array: ";
cin >> size;
float values[size];

请注意,在 C++ 中,数组声明后元素的值是未定义的。

你也可以在声明时用逗号分隔的值列表初始化数组,如下所示:

// 声明并初始化一个包含 3 个元素的 int 数组
int numbers[3] = {11, 33, 44};
// 如果省略长度,编译器会计算元素数量
int numbers[] = {11, 33, 44};
// 初始化列表中的元素数量应等于或小于数组长度
int numbers[5] = {11, 33, 44};  // 剩余元素为 0。容易混淆!不要这样做
int numbers[2] = {11, 33, 44};  // 错误:初始值过多

// 使用 {0} 或 {} 将所有元素初始化为 0
int numbers[5] = {0};  // 第一个元素为 0,其余也为 0
int numbers[5] = {};   // 所有元素也为 0
/* 测试局部数组初始化 */
#include <iostream>
using namespace std;

int main() {
   int const SIZE = 5;

   int a1[SIZE];   // 未初始化
   for (int i = 0; i < SIZE; ++i) cout << a1[i] << " ";
   cout << endl;   // ? ? ? ? ?

   int a2[SIZE] = {21, 22, 23, 24, 25}; // 所有元素已初始化
   for (int i = 0; i < SIZE; ++i) cout << a2[i] << " ";
   cout << endl;   // 21 22 23 24 25

   int a3[] = {31, 32, 33, 34, 35};   // 大小由初始值推断
   int a3Size = sizeof(a3)/sizeof(int);
   cout << "Size is " << a3Size << endl;   // 5
   for (int i = 0; i < a3Size; ++i) cout << a3[i] << " ";
   cout << endl;   // 31 32 33 34 35

   int a4[SIZE] = {41, 42};  // 前导元素已初始化,其余为 0
   for (int i = 0; i < SIZE; ++i) cout << a4[i] << " ";
   cout << endl;   // 41 42 0 0 0

   int a5[SIZE] = {0};  // 第一个元素为 0,其余也为 0
   for (int i = 0; i < SIZE; ++i) cout << a5[i] << " ";
   cout << endl;   // 0 0 0 0 0

   int a6[SIZE] = {};   // 所有元素也为 0
   for (int i = 0; i < SIZE; ++i) cout << a6[i] << " ";
   cout << endl;   // 0 0 0 0 0

   for (int i=0;i<5;i++){
       // 为数组的每个元素赋值,如下所示
       a6[i] = i;
       cout << a6[i] << " ";
   }
}

输出:

6299128 0 485160213 32595 0 ## 一些意外的值
21 22 23 24 25
Size is 5
31 32 33 34 35
41 42 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 2 3 4
图片描述

你可以使用表达式 sizeof(arrayName)/sizeof(arrayName[0]) 来获取数组的长度,其中 sizeof(arrayName) 返回数组的总字节数,sizeof(arrayName[0]) 返回第一个元素的字节数。

数组与循环

数组与循环紧密配合。你可以通过循环处理数组中的所有元素。C++11 引入了基于范围的 for 循环(或称为 for-each 循环)来遍历数组,例如:

/* 测试 For-each 循环 */
#include <iostream>
using namespace std;

int main() {
   int numbers[] = {11, 22, 33, 44, 55};

   // 对于数组 numbers 中的每个成员 number - 只读
   for (int number : numbers) {
      cout << number << " ";
   }

   // 要修改成员,需要使用引用 (&)
   for (int &number : numbers) {
      number = 99;
   }

   for (int number : numbers) {
      cout << number << endl;
   }
   return 0;
}

输出:

11 22 33 44 55
99 99 99 99 99
图片描述

多维数组

例如:

int[2][3] = { {11, 22, 33}, {44, 55, 66} };
图片描述
/* 测试多维数组 */
#include <iostream>
using namespace std;
void printArray(const int[][3], int);

int main() {
   int myArray[][3] = {{8, 2, 4}, {7, 5, 2}}; // 2x3 初始化
                 // 只有第一个索引可以省略并由编译器推断
   printArray(myArray, 2);
   return 0;
}

// 打印 rows-by-3 数组的内容(列数是固定的)
void printArray(const int array[][3], int rows) {
   for (int i = 0; i < rows; ++i) {
      for (int j = 0; j < 3; ++j) {
         cout << array[i][j] << " ";
      }
      cout << endl;
   }
}

输出:

8 2 4
7 5 2
图片描述

字符数组

在 C 语言中,字符串是一个以 NULL 字符 '\0'(十六进制 0 的 ASCII 码)结尾的 char 数组。C++ 在头文件 <string> 中提供了一个新的 string 类。C 语言中的原始字符串被称为 C-String(或 C 风格字符串或字符字符串)。你可以通过以下方式分配一个 C-string:

char message[256];     // 声明一个 char 数组
                       // 可以容纳最多 255 个字符的 C-String,以 '\0' 结尾
char str1[] = "Hello"; // 使用 "字符串字面量" 声明并初始化
                       // 数组的长度是字符数 + 1(用于 '\0')
char str1char[] = {'H', 'e', 'l', 'l', 'o', '\0'};  // 与上述相同
char str2[256] = "Hello";  // 数组长度为 256,存储一个较短的字符串

对于初学者,建议避免使用 C-string。使用之前讨论过的 C++ string(在头文件 <string> 中)。

你可以使用 cincout 来处理 C-string。

  • cin << 读取以空白字符分隔的字符串;
  • cin.getline(*var*, *size*) 读取一行字符串到 var 中,直到换行符,长度最多为 size-1,丢弃换行符(替换为 '\0')。*size* 通常对应于 C-string 数组的长度。
  • cin.get(*var*, *size*) 读取字符串直到换行符,但将换行符保留在输入缓冲区中。
  • cin.get(),不带参数,读取下一个字符。
/* 测试 C-string */
#include <iostream>
using namespace std;

int main() {
   char msg[256]; // 容纳最多 255 个字符的字符串(以 '\0' 结尾)

   cout << "输入一条消息(带空格)" << endl;
   cin.getline(msg, 256);  // 读取最多 255 个字符到 msg 中
   cout << msg << endl;

   // 通过以 NULL 结尾的字符数组访问
   for (int i = 0; msg[i] != '\0'; ++i) {
      cout << msg[i];
   }
   cout << endl;

   cout << "输入一个单词(不带空格)" << endl;
   cin >> msg;
   cout << msg << endl;

   // 通过以 NULL 结尾的字符数组访问
   for (int i = 0; msg[i] != '\0'; ++i) {
      cout << msg[i];
   }
   cout << endl;
   return 0;
}

输出:

输入一条消息(带空格)
hello, how are you?
hello, how are you?
hello, how are you?
输入一个单词(不带空格)
helloworld
helloworld
helloworld
图片描述

总结

C/C++ 不会执行数组的 索引边界检查。换句话说,如果索引超出数组的边界,它不会发出警告或错误。尽管如此,你需要估计长度并分配一个上限。这可能是使用数组的主要缺点。C++ 提供了一个 vector 模板类(C++11 还添加了一个 array 模板类),它支持动态可调整大小的数组。