C++青少年简明教程:数组

C++青少年简明教程:数组

C++数组是一种存储固定大小连续元素的数据结构。数组中的每个元素都有一个索引,通过索引可以访问或修改数组中的元素。

在C++中,数组中的元素数据类型必须一致。数组是一个连续的内存区域,用于存储相同类型的元素。在声明数组时,需要指定数组元素的数据类型,并且在数组中的所有元素都必须是该指定类型。

如果需要存储不同类型的元素,可能需要使用结构体、类或模板等其他方式来实现。

C++数组的基本特点:

固定大小:创建时必须指定数组的大小,且大小在数组生命周期内不可改变。

同一类型:数组中所有元素必须是相同的数据类型。

连续内存:数组元素在内存中连续存储,这意味着可以通过指针算术来访问元素。

数组依据维度可分为:
一维数组:用于存储线性排列的数据。由单一的索引访问每个元素,适用于表示单行或单列的数据集合。
多维数组:用于存储表格形或更高维度的数据。二维数组(或矩阵)是最常见的多维数组形式。通过多个索引访问每个元素,每个额外的维度为数据结构增加一个层级,适用于更复杂的数据组织方式,如表格、立方体等。

一维数组

一维数组是一个线性的数据结构,它包含相同类型的元素,并通过一个索引来访问每个元素。一维数组可以看作是一个行或者一列的元素列表。如:

可以使用一排糖果或者水果来比喻一维数组。每个位置的糖果或者水果可以看作是数组的一个元素。你可以请示学生,如果我们想要找到第3个位置的糖果,应该搜索哪个位置呢?

C++ 中,声明(定义)数组语法格式

元素的数据类型  数组的名称[元素数目]

【数组元素指的是数组中存储的单个数据项。数组下标和索引是同一个概念,用于标识数组中每个元素的位置。数组下标从0开始递增,表示元素在数组中的位置。】

元素数目也称为数组大小,即数组中元素的个数,是一个常量值。【元素数目也称为数组大小是一个常量值(常量表达式)。特别说明:虽然某些编译器可能会支持变量数组,但这并不是标准的一部分。在C++中,如果你需要一个可以动态调整大小的数组,推荐使用vector容器,vector是一个动态数组,它可以在运行时动态地增加或减少元素。与数组(array)相比,vector提供了更多的灵活性,例如自动调整大小、插入和删除元素等。】

以下是一个声明了大小为5的整数数组的示例:

int numbers[5]; // 创建了一个能够存储5个整数的数组

也可以使用常量声明数组:

const int n = 5;

int numbers[n]; // 创建了一个能够存储5个整数的数组

【如果您需要在运行时动态地调整数组的大小,可以考虑使用动态数组或者标准库提供的容器类,例如vector。这些容器类提供了更灵活的数据结构,可以动态地增加或减少其大小。

以下是使用vector容器来实现动态大小的数组的示例:

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> numbers; // 创建一个使用int类型存储的动态数组

    // 在运行时向数组中添加元素
    numbers.push_back(10);
    numbers.push_back(20);
    numbers.push_back(30);

    // 输出数组中的元素
    for (int i = 0; i < numbers.size(); i++) {
        cout << numbers[i] << " ";
    }

    return 0;
}

在这个示例中,vector容器可以存储动态数量的整数。通过使用push_back函数,我们可以在运行时向容器中添加元素。同时,通过调用size函数,我们可以获取容器中的元素数量,从而实现动态大小的数组。】

一维数组的初始化

1)使用大括号 {} 初始化数组,可以指定每个元素的初始值。例如:

int arr1[] = {1, 2, 3, 4, 5}; // 初始化一个包含5个元素的整型数组

2)指定整个数组的初始值。例如:

int arr2[5] = {1, 2, 3, 4, 5}; // 初始化一个包含5个元素的整型数组

3)不指定数组大小,直接使用大括号 {} 初始化数组,编译器会自动根据初始值的个数确定数组大小。例如:

int arr3[] = {1, 2, 3, 4, 5}; // 初始化一个包含5个元素的整型数组

4)部分初始化,未指定的元素将被默认初始化为零。例如:

int arr[5] = {1, 2, 3}; // 初始化前3个元素为1、2和3,其他两个元素默认初始化为0

5)使用循环进行初始化:

int arr[5];
for (int i = 0; i < 5; i++) {
    arr[i] = i + 1; // 初始化元素为1到5
}
 

数组元素赋值示例:

#include <iostream>
using namespace std;

int main() {
  // 声明一个整数数组,包含5个元素
  int numbers[5];

  // 初始化数组元素
  numbers[0] = 10;
  numbers[1] = 20;
  numbers[2] = 30;
  numbers[3] = 40;
  numbers[4] = 50;
  // 还可以这样声明数组并初始化int numbers[5] = {10, 20, 30, 40, 50};

  // 访问数组元素并输出
  cout << "第一个元素: " << numbers[0] << endl;
  cout << "第三个元素: " << numbers[2] << endl;

  // 修改数组元素
  numbers[1] = 100;

  // 输出修改后的数组元素
  cout << "修改后的第二个元素: " << numbers[1] << endl;

  return 0;
}

需要注意,一维数组的索引是从0开始的,即第一个元素的索引是0,第二个元素的索引是1,依此类推。

对一维数组进行赋值或修改元素的值,示例如下:

#include <iostream>
using namespace std;

int main() {
    int arr[5];

    // 赋值
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;

    // 修改元素值
    arr[2] = 4;

    // 访问数组元素
    cout << arr[0] << endl; // 输出:1
    cout << arr[2] << endl; // 输出:4

    return 0;
}

、统计数组中正数和负数和0的个数

#include <iostream>
using namespace std;
 
int main() {  
    int a[10] = {1, -10, 20, 0, 5, -6, 7, 0, -2, 0};  
    int positiveCount = 0; // 用于统计正数的个数  
    int negativeCount = 0; // 用于统计负数的个数  
    int zeroCount = 0; // 用于统计零的个数  
  
    // 遍历数组并统计  
    for (int i = 0; i < 10; ++i) {  
        if (a[i] > 0) {  
            ++positiveCount;  
        } else if (a[i] < 0) {  
            ++negativeCount;  
        } else {  
            ++zeroCount;  
        }  
    }  
  
    // 输出结果  
    cout << "正数的个数: " << positiveCount << ",";  
    cout << "负数的个数: " << negativeCount << ",";  
    cout << "零的个数: " << zeroCount << endl;  
  
    return 0;  
}

运行之,输出如下:

数组中正数4个,负数3个,零3个

C语言代码:

#include<stdio.h>
 
int main() {  
    int a[10] = {1, -10, 20, 0, 5, -6, 7, 0, -2, 0};  
    int positiveCount = 0; // 用于统计正数的个数  
    int negativeCount = 0; // 用于统计负数的个数  
    int zeroCount = 0; // 用于统计零的个数  
  
    // 遍历数组并统计  
    for (int i = 0; i < 10; ++i) {  
        if (a[i] > 0) {  
            ++positiveCount;  
        } else if (a[i] < 0) {  
            ++negativeCount;  
        } else {  
            ++zeroCount;  
        }  
    }  
  
    // 输出结果  
    printf("数组中正数%d个,负数%d个,零%d个\n",positiveCount ,negativeCount, zeroCount);
}  

二维数组

二维数组是一个包含多行和多列的表格结构,它由多个一维数组组成。二维数组的元素可以通过两个索引进行访问,第一个索引表示行号,第二个索引表示列号。可以将二维数组看作是一个矩阵,其中每个元素由其在矩阵中的行和列决定。

例如,以下是一个包含3行和4列的二维数组的示例:

在这个示例中,通过两个索引可以访问每个元素,例如a[0][2]表示行号为0、列号为2的元素。

二维数组和一维数组在使用和实现上有一些区别,二维数组需要使用两个索引来访问元素,而一维数组只需要一个索引。此外,二维数组在内存中被连续存储,每行的元素紧密相邻,而一维数组的元素在内存中是连续存储的。

可以使用一个矩阵或者棋盘来表示二维数组。你可以在黑板上画出一个3x4的方格矩阵,并把每个方格标上数字。然后向学生解释,我们可以使用两个索引来找到每个方格,第一个索引表示行号,第二个索引表示列号。

可以使用珠子串来比喻二维数组。你可以用不同颜色的珠子串成一条线,然后叠加多条珠子串,每条珠子串代表二维数组的一行。然后可以请示学生,如果我们想找到第2行第3列的珠子,应该搜索哪些珠子串?

二维数组的初始化

1)使用大括号 {} 初始化二维数组,可以指定每个元素的初始值。例如:

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 初始化一个包含2行3列的二维整型数组

也可以这样写:

int arr[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

每个括号对应一个维度,外层括号对应第一维,内层括号对应第二维。如果已经给出了足够的初始化项,就可以不用写内部嵌套的花括号了,需要注意的是,如果只给出了一部分初始化项,必须显式地使用大括号。

2)不指定二维数组的行数,直接使用大括号 {} 初始化二维数组,编译器会自动根据初始值的个数确定行数。例如:

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 初始化一个包含2行3列的二维整型数组

二维数组的列数必须在初始化时指定,行数可以根据初始值的个数自动确定。

3)部分初始化。例如:

int arr[2][3] = {{1, 2}, {4, 5}}; // 初始化部分元素,其他元素将默认初始化为0,相当于:

int arr[2][3] = {{1, 2,0}, {4, 5,0}};

内部嵌套的括号是可选的。

4)嵌套循环进行初始化。例如:

int arr[2][3];
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        arr[i][j] = i + j; // 根据需要自行给元素赋值
    }
}

二维数组的示例:

#include <iostream>
using namespace std;
 
int main() {
    int a[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    // 输出二维数组的元素
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 4; ++j) {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

这个示例中,定义了一个 3 行 4 列的二维整数数组 a,并初始化其元素。然后,使用嵌套的 for 循环遍历二维数组并输出其元素。输出结果如下:

1 2 3 4
5 6 7 8
9 10 11 12

 

三维数组

C++中,三维数组的初始化和二维数组类似,但有点除外,二维数组的列数必须在初始化时指定,行数可以根据初始值的个数自动确定。但三维数组的每一维的大小都必须在定义时指定。

定义一个3维数组并赋初值

int a[2][3][4] = {{{1, 2, 3, 4},{5, 6, 7, 8}, 9, 10, 11, 12}}, {{13, 14, 15, 16}, {17, 18, 19, 20},{21, 22, 23, 24}}};

也可以这样写:

int a[2][3][4] = {
  {{1, 2, 3, 4},
   {5, 6, 7, 8}, 
   {9, 10, 11, 12}}, 
  {{13, 14, 15, 16}, 
   {17, 18, 19, 20}, 
   {21, 22, 23, 24}}
};

如果已经给出了足够的初始化项,就可以不用写内部嵌套的花括号了。

每个括号对应一个维度,外层括号对应第一维,内层括号对应第二维,再内层括号对应第三维。需要注意的是,如果只给出了一部分初始化项,必须显式地使用大括号。

多维数组的构成元素优先按末尾的下标递增的顺序排列。

a[i][j][k] 中,最内层(从编程循环遍历访问数组元素的角度看)的下标是 k,其变化最快;次内层的下标是 j,其次变化;最外层的下标是 i,变化最慢。这种索引方式确实使得我们可以方便地访问任意一个多维数组中的元素。

请结合下面的示例理解,三重循环遍历三维元素的每个元素示例:

#include <iostream>
using namespace std;

int main() {	
    int a[2][3][4]; // 定义一个3维数组
    // 给数组赋值
    int num=1;
    for(int i=0; i<2; i++){
        for(int j=0; j<3; j++){
            for(int k=0; k<4; k++){
                a[i][j][k] = num++;
            }
        }
    }

    // 输出数组
    for(int i=0; i<2; i++){
        for(int j=0; j<3; j++){
            for(int k=0; k<4; k++){
                cout << "a[" << i << "][" << j << "][" << k << "] = " << a[i][j][k] << "  ";
            }
            cout << endl;
        }
        cout << endl;
    }

    return 0;
}

这个例子中,我们定义了一个 a[2][3][4] 的3维数组。然后我们使用三重循环遍历每个元素,并给数组赋值。

最后,我们使用嵌套循环来遍历数组并输出每个元素的值。

这个程序的输出应该是以下这个样子:

a[0][0][0] = 1  a[0][0][1] = 2  a[0][0][2] = 3  a[0][0][3] = 4
a[0][1][0] = 5  a[0][1][1] = 6  a[0][1][2] = 7  a[0][1][3] = 8
a[0][2][0] = 9  a[0][2][1] = 10  a[0][2][2] = 11  a[0][2][3] = 12

a[1][0][0] = 13  a[1][0][1] = 14  a[1][0][2] = 15  a[1][0][3] = 16
a[1][1][0] = 17  a[1][1][1] = 18  a[1][1][2] = 19  a[1][1][3] = 20
a[1][2][0] = 21  a[1][2][1] = 22  a[1][2][2] = 23  a[1][2][3] = 24

 

定义数组时进行赋值,上面程序可修改为:

#include <iostream>
using namespace std;

int main() {
    // 定义一个3维数组并赋初值
    int a[2][3][4] = {{{1, 2, 3, 4}, 
                   {5, 6, 7, 8}, 
                   {9, 10, 11, 12}}, 
                  {{13, 14, 15, 16}, 
                   {17, 18, 19, 20}, 
                   {21, 22, 23, 24}}};


    // 输出数组
    for(int i=0; i<2; i++){
        for(int j=0; j<3; j++){
            for(int k=0; k<4; k++){
                cout << "a[" << i << "][" << j << "][" << k << "] = " << a[i][j][k] << "  ";
            }
            cout << endl;
        }
        cout << endl;
    }

    return 0;
}

小结

在 C++ 中,数组是一种用于存储同类型数据集合的简单且高效的方式。以下是使用数组时需要注意的重要事项:

☆数组的大小在编译时确定,并且不能改变:

数组的大小必须在编译时指定,并且一旦定义,数组的大小在程序的生命周期内是固定的。

int arr[5]; // 定义一个包含5个整数的数组

☆数组名实际上是指向数组第一个元素的指针:

数组名本身可以作为指针使用,指向数组的第一个元素。

int* ptr = arr; // ptr 指向 arr[0]

☆当将数组作为函数参数传递时,传递的是数组的指针,而不是整个数组:

传递数组给函数时,实际上传递的是指向数组第一个元素的指针,这意味着函数内对数组的修改会影响到原数组。

void printArray(int* array, int size) {
    for(int i = 0; i < size; ++i) {
        std::cout << array[i] << " ";
    }
}

☆使用 sizeof 运算符可以获取数组的大小(以字节为单位),但通常需要除以元素的大小来得到元素的数量:

int arr[10];

int size_in_bytes = sizeof(arr); // 获取数组大小(字节数)

int element_count = sizeof(arr) / sizeof(arr[0]); // 获取数组元素的个数

☆数组越界访问是未定义行为:

访问数组时索引超出范围会导致未定义行为,可能会导致程序崩溃或其他不可预测的结果。因此,务必确保访问数组时索引在有效范围内。

int arr[5];

arr[5] = 10; // 错误:索引越界

对于多维数组,需要按照对应的维度来访问元素。例如,对于二维数组arr,可以通过arr[i][j]来访问第i行第j列的元素。

☆数组是 C++ 中存储同类型数据集合的简单且有效的方式:

它提供快速的元素访问,适用于已知元素数量固定的场景。然而,对于需要动态调整大小的情况,可以考虑使用 C++ 标准模板库(STL)中的 std::vector。

关于数组更多情况可见 https://blog.csdn.net/cnds123/article/details/108936055

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/676124.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

std::shared_ptr,reset()函数

感慨&#xff1a;不深入阅读源代码&#xff0c;真的心虚&#xff0c;也用不好。 上代码&#xff1a; class A01 { public://std::weak_ptr<B0> b_ptr;int data{ 1234 };~A01() {std::cout << "A01 deleted\n";}void Print() { std::cout << &quo…

C++进阶:C++11

C11简介 在 2003 年 C 标准委员会曾经提交了一份技术勘误表 ( 简称 TC1) &#xff0c;使得 C03 这个名字已经取代了 C98 称为 C11 之前的最新 C 标准名称。不过由于 C03(TC1) 主要是对 C98 标准中的漏洞 进行修复&#xff0c;语言的核心部分则没有改动&#xff0c;因此人们习…

初始操作系统

概念&#xff1a; 1.系统资源的管理者&#xff1a;实质控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机地工作和资源的分配 2.向上层提供方便易用的服务&#xff1a;以提供给用户和其他软件方便接口和环境 封装思想&#xff1a;操作系统把一些丑…

小熊家务帮day10- 门户管理

门户管理 1 门户介绍1.1 介绍1.2 常用技术方案 2 缓存技术方案2.1 需求分析2.1.1 C端用户界面原型2.1.2 缓存需求2.1.3 使用的工具 2.2 项目基础使用2.2.1 项目集成SpringCache2.2.2 测试Cacheable需求Service测试 2.1.3 缓存管理器&#xff08;设置过期时间&#xff09;2.1.4 …

React@16.x(17)Portals

目录 1&#xff0c;使用2&#xff0c;事件冒泡 一句话总结&#xff1a;和 Vue3 的 Teleport 一个效果。 1&#xff0c;使用 import React, { PureComponent } from "react"; import ReactDOM from "react-dom";// 返回一个 React 元素&#xff08;ReactNo…

【Go语言精进之路】构建高效Go程序:零值可用、使用复合字面值作为初值构造器

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言一、深入理解并利用零值提升代码质量1.1 深入Go类型零值原理1.2 零值可用性的实践与优势1.2.1 切片(Slice)的零值与动态扩展1.2.2 Map的零值与安全访问1.2.3 函数参数与零值 二、使用复合字面值作为初值构造器2.1 结构体…

十分钟快速搭建检索、排序的大模型RAG系统

以上为实现效果 RAG是目前最火的大模型应用之一&#xff0c;如何能快速实现一个不错的demo呢&#xff1f; 参考 https://github.com/LongxingTan/open-retrievalshttps://colab.research.google.com/drive/1fJC-8er-a4NRkdJkwWr4On7lGt9rAO4P?uspsharing#scrollTo2Hrfp96UY…

【算法】一文搞懂归并排序

概念 归并排序利用了分治思想&#xff0c;将待排序的数组范围层层划分&#xff0c;每次划分会得到两个大小相近的区间。当无法划分时&#xff0c;递归结束&#xff0c;自下而上进行区间合并merge操作&#xff0c;合并操作依次比较两个区间的元素&#xff0c;进而使合并后的区间…

开发和渗透偷懒利器utools

目录 1.前言 1.1 工具简介 1.2 核心特性 1.3 使用场景 1.4 安装与使用 1.4.1 下载&#xff1a; 1.4.2 安装&#xff1a; 1.4.3 配置&#xff1a; 1.4.4 插件市场&#xff1a; 2.懒狗插件介绍 基本介绍 2.1 数据模拟 2.2 随机生成虚假数据 2.3 API市场 2.4 Hoppscot…

学习小心意——简单的循坏语句

for循坏 基本语法格式 for 变量 in 序列:代码块 示例代码如下 for i in range(10):print(i)#输出结果:0 1 2 3 4 5 6 7 8 9 简单案例代码如下 利用for语句遍历序列 # 遍历字符串打印每个字母 for letter in "python":print(letter)# 遍历列表并打印每个元素 a …

Spring Boot API 编写的十个最佳实践,你知道几个?

一个好的 API 不仅能提高开发效率&#xff0c;还能确保系统的安全性和稳定性。 第一部分&#xff1a;RESTful API 设计 资源名称&#xff1a;使用名词表示资源&#xff0c;比如 /users。 HTTP 方法&#xff1a;GET、POST、PUT、DELETE 分别对应查询、创建、更新和删除操作。 …

SaaS 电商设计 (十一) 那些高并发电商系统的限流方案设计

目录 一.什么是限流二.怎么做限流呢2.1 有哪些常见的系统限流算法2.1.1 固定窗口2.1.1 滑动窗口2.1.2 令牌桶2.1.3 漏桶算法 2.2 常见的限流方式2.2.1 单机限流&集群限流2.2.2 前置限流&后置限流 2.3 实际落地是怎么做的2.3.1 流量链路2.3.2 各链路限流2.3.2.1 网关层2…

【Java面试】七、SpringMvc的执行流程、SpringBoot自动装配原理

文章目录 1、SpringMVC的执行流程1.1 视图阶段1.2 前后端分离阶段 2、SpringBoot自动配置原理3、框架常用的注解3.1 Spring的注解3.2 SpringMvc的注解3.3 SpringBoot的注解 4、面试 1、SpringMVC的执行流程 1.1 视图阶段 旧项目中&#xff0c;未前后端分离时&#xff0c;用到…

计算机视觉与模式识别实验2-2 SIFT特征提取与匹配

文章目录 &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1;SIFT算法原理总结&#xff1a;实现SIFT特征检测和匹配通过RANSAC 实现图片拼接更换其他图片再次测试效果&#xff08;依次进行SIFT特征提取、RANSAC 拼接&#xff09; &#x1f9e1;&#x1f9e1;全部代…

(CVPRW,2024)可学习的提示:遥感领域小样本语义分割

文章目录 相关资料摘要引言方法训练基础类别新类别推理 相关资料 论文&#xff1a;Learnable Prompt for Few-Shot Semantic Segmentation in Remote Sensing Domain 代码&#xff1a;https://github.com/SteveImmanuel/OEM-Few-Shot-Learnable-Prompt 摘要 小样本分割是一项…

JMeter性能测试实现与分析分享

JMeter是由著名开源软件巨头Apache组织开发的纯Java的压力测试工具&#xff0c;它即能测试动态服务&#xff08;WebService&#xff09;&#xff0c;也能测试静态资源&#xff0c;包括Servlet服务、CGI脚本等&#xff0c;还能测试动态语言服务&#xff08;PHP、Java、ASP.NET等…

外汇天眼:总是权衡利弊,投资注定失败

投资股票的人往往会频繁地评估自己的投资结果&#xff0c;尤其是在信息时代&#xff0c;手机上随时可以查看股票行情&#xff0c;导致很多人时不时地打开行情软件&#xff0c;看一看自己的股票是涨了还是跌了&#xff0c;盈利了还是亏损了。 频繁评估结果的弊端 一、引发急躁…

JVM学习-监控工具(二)

jmap&#xff1a;导出内存映像文件&内存使用情况 基本情况 jmap(JVM Memory Map)&#xff1a;一方法获取dump文件(堆转储快照文件&#xff0c;二进制文件)&#xff0c;还可以获取目标Java进程的内存相关信息&#xff0c;包括Java堆各区域的使用情况、堆中对象的统计信息、…

Golang TCP网络编程

文章目录 网络编程介绍TCP网络编程服务器监听客户端连接服务器服务端获取连接向连接中写入数据从连接中读取数据关闭连接/监听器 简易的TCP回声服务器效果展示服务端处理逻辑客户端处理逻辑 网络编程介绍 网络编程介绍 网络编程是指通过计算机网络实现程序间通信的一种编程技术…

成功解决“ModuleNotFoundError: No Module Named ‘utils’”错误的全面指南

成功解决“ModuleNotFoundError: No Module Named ‘utils’”错误的全面指南 在Python编程中&#xff0c;遇到ModuleNotFoundError: No Module Named utils这样的错误通常意味着Python解释器无法找到名为utils的模块。这可能是由于多种原因造成的&#xff0c;比如模块确实不存…