C++ 篇 数组

数组是含有多个数据项的数据结构,并且这些数据项都具有相同的数据类型。这些数据项称为数组的元素,我们可以根据元素在数组中的位置来选取元素。

最简单的数组就是一维数组。数组元素在内存中是依次排列的,如下图所示:

声明一个数组,我们需要指定数组元素的类型和数量。如:

int a[10];
const int* p; // pointer to const 常量指针
int* const p; //constant pointer  指针常量
const int* const p;

数组元素可以是任何类型,数组的长度则必须是常量表达式 (能够在编译期间求值的表达式)。因为程序以后可能需要调整数组的长度,所以一般情况下,我们会使用宏来定义数组的长度:

数组索引
我们可以用数组索引来访问数组中的元素。在 C 语言中,数组索引是从 0 开始的,所以长度为 n 的数组索引范围为 0 ~ n-1。假如 a 是含有 10 个元素的数组,那么这些元素可以依次标记为 a[0], a[1], ..., a[9],如下图所示:

/* clears a */for (i = 0; i < N; i++)    a[i] = 0;
/* reads data into a */for (i = 0; i < N; i++)    scanf("%d", &a[i]);
/* sums the element of a */for (i = 0; i < N; i++)    sum += a[i];

C 语言有一个常被人诟病的问题:不检查数组索引越界 (why?)。当数组索引越界时,程序的行为是未定义的,也就是说任何情况都可能发生。

#include<iostream> 
//#include<stdio.h>
using namespace std;void test0(){int arr[] = {1, 2, 3};printf("arr[3] = %d\n", arr[3]);
}int main()
{test0();}

数组初始化

数组可以像其它变量一样进行初始化,不过数组的初始化需要一些技巧。
数组初始化式最常见的形式是,用大括号包含一组常量表达式,常量表达式之间用逗号分隔。
 

int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

如果初始化式比数组短,那么剩余元素被初始化为 0:

int a[10] = {1, 2, 3, 4, 5, 6}; /* initial value of a is {1, 2, 3, 4, 5, 6, 0, 0, 0, 0} */

利用这个特性,我们很容易把数组元素全部初始化为 0:

int a[10] = {0};

注意:初始化式不能比数组长,也不能完全为空。

如果给定了初始化式,我们也可以省略数组的长度:

int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

对数组使用 sizeof 运算符
我们可以使用 sizeof 运算符确定数组的大小 (字节)。如果数组 a 包含 10 个整数,那么 sizeof(a) 的值通常为 40。sizeof 运算符也可以确定数组元素的大小,两者相除即得到数组的长度:

sizeof(a) / sizeof(a[0])

这样做有个好处:即使日后数组的长度发生改变,这个 for 循环是不需要发生变化的。为了可读性和通用性,我们往往把 sizeof(a) / sizeof(a[0]) 定义为带参数的宏:

#define SIZE(a) (sizeof(a) / sizeof(a[0]))
...
for (i = 0; i < SIZE(a); i++)    a[i] = 0;

【练】用户输入初始金额,利率和投资年数,程序将打印一张表格。表格将显示输入的利率以及紧随其后 4 个更高利率下的总金额。程序的会话如下:

#include<iostream> 
//#include<stdio.h>
using namespace std;void test0(){double init_balance, rate;int years;cout<<"Enter initial balance:";cin>>init_balance;cout<<"Enter initial rate:";cin>>rate;cout<<"Enter number of years:";cin>>years;cout<<"\nYears ";for(int i = 0; i < 5; i++){//cout<<i+rate<<"% ";printf("%5.2lf%%", i+rate);}cout<<endl;double value[5];for(int i = 0; i < 5; i++)value[i] = init_balance;for(int j = 1; j <= years; j++){cout<<j<<"   ";for(int i = 0; i < 5; i++){ value[i] += value[i] * (rate+i)/100;printf("%7.2lf",value[i]); }cout<<endl;}}int main()
{test0();return 0;
}

多维数组
数组可以有任意维数。其中最常用的是一维数组,其次是二维数组,一般很少见到更高维的数组。如下,我们声明了一个二维数组 (类似数学上的矩阵):
 

int matrix[5][9];

数组 matrix 有 5 行 9 列,且行和列的索引都是从 0 开始的,如下图所示:

就像一维数组和 for 循环是好伙伴一样,二维数组和嵌套的 for 循环是好伙伴。例如,我们可以通过下面的方式创建一个维度为 10 的单位矩阵:

#define N 10 double identity[N][N];
int row, col;for (row = 0; row < N; row++)    for (col = 0; col < N; col++)        if (row == col)  identity[row][col] = 1.0;        else             identity[row][col] = 0.0;

多维数组初始化
通过嵌套一维数组初始化式,我们可以构建二维数组的初始化式:

int matrix[5][9] = {{1, 1, 1, 1, 1, 0, 1, 1, 1},                    {0, 1, 0, 1, 0, 1, 0, 1, 0},                    {0, 1, 0, 1, 1, 0, 0, 1, 0},                    {1, 1, 0, 1, 0, 0, 0, 1, 0},                    {1, 1, 0, 1, 0, 0, 1, 1, 1}};

更高维数组的初始化式可以采取类似的方法构建,C 语言提供了多种方法来简化多维数组的初始化。

  • 如果初始化式的长度不够,那么剩余元素被初始化为 0。如,下面的初始化式只填充了数组的前 3 行,后面 2 行将被初始化为 0。
int matrix[5][9] = {{1, 1, 1, 1, 1, 0, 1, 1, 1},                    {0, 1, 0, 1, 0, 1, 0, 1, 0},                   {0, 1, 0, 1, 1, 0, 0, 1, 0}};
  • 如果内层初始化式不足以填满数组的一行,那么这一行剩余的元素会被初始化为 0。
    int matrix[5][9] = {{1, 1, 1, 1, 1, 0, 1, 1, 1},                   {0, 1, 0, 1, 0, 1, 0, 1},                    {0, 1, 0, 1, 1, 0, 0, 1},                    {1, 1, 0, 1, 0, 0, 0, 1},                    {1, 1, 0, 1, 0, 0, 1, 1, 1}};
  • 甚至,我们可以省略内存的大括号 (不推荐)。
    int matrix[5][9] = {1, 1, 1, 1, 1, 0, 1, 1, 1,                    0, 1, 0, 1, 0, 1, 0, 1, 0,                    0, 1, 0, 1, 1, 0, 0, 1, 0,                    1, 1, 0, 1, 0, 0, 0, 1, 0,                       1, 1, 0, 1, 0, 0, 1, 1, 1};

    编译器一旦发现值足以填满一行,它就开始填充下一行。
    注意:在初始化式中省略内层大括号是非常危险的,因为不小心多写或者少写一个值都会影响后面元素的初始化。

     

常量数组 

无论是一维数组还是二维数组,我们都可以在声明时加上const修饰符而变成 "常量":

const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',         'A', 'B', 'C', 'D', 'E', 'F'};

程序在运行期间不会对数组进行修改。
const不仅仅可以修饰数组,它可以修饰任意变量。但是const在数组声明中特别有用,因为数组经常包含一些不会发生改变的信息。编译器酌情进行优化,运行效率更高。

【练】写一个随机发牌的程序。用户指定发几张牌,程序打印手牌。程序的会话如下:

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

穿越牛熊,股市的春天还有多远?

2023年&#xff0c;资本市场的严冬令无数投资者和机构投资者都感受到了前所未有的压力。VC/PE、公募基金、股权投资类公司等机构&#xff0c;在这一年里业绩普遍不佳&#xff0c;寒意弥漫。VC/PE机构的营业收入普遍呈现负增长&#xff0c;公募基金更是历史上首次连续两年亏损&a…

LLM 加速技巧:Muti Query Attention

MQA 是 19 年提出的一种新的 Attention 机制&#xff0c;其能够在保证模型效果的同时加快 decoder 生成 token 的速度。在大语言模型时代被广泛使用&#xff0c;很多LLM都采用了MQA&#xff0c;如Falcon、PaLM、StarCoder等。 在介绍MQA 之前&#xff0c;我们先回顾一下传统的…

穷人想赚钱该怎么选打工VS创业?2024年如何把握新机遇?

在贫穷的困境中&#xff0c;打工与创业似乎成为了两条截然不同的道路&#xff0c;摆在每一个渴望改变命运的人面前。然而&#xff0c;这并非简单的选择题&#xff0c;而是一场关于勇气、智慧与机遇的较量。打工&#xff0c;对于许多人来说&#xff0c;是稳定且相对安全的收入来…

遗传算法理解与代码实战(二)- demo(python+deap)

前文介绍了遗传算法&#xff0c;并且手动python代码进行了实践&#xff0c;但是在遇到复杂的问题时&#xff08;遗传算法理解与代码实战&#xff08;三&#xff09;会介绍&#xff09;&#xff0c;手写代码很麻烦&#xff0c;所以需要借助专门的遗传算法库来实现&#xff0c;这…

社区医院智慧管理:Java+SpringBoot新实践

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

酷炫!向数字世界 AGI 迈进!让智能体直接控制键盘、鼠标,与一切软件交互

信息革命催生了数字世界&#xff0c;这个世界为大模型提供了海量数据&#xff0c;同时也为通用人工智能&#xff08;AGI&#xff09;的实现提供了可能。在迈向数字世界的 AGI 的过程中&#xff0c;北京智源人工智能研究院、新加坡南洋理工大学和北京大学联合提出了一种名为 Gen…

数据结构——lesson7二叉树 堆的介绍与实现

前言&#x1f49e;&#x1f49e; 啦啦啦~这里是土土数据结构学习笔记&#x1f973;&#x1f973; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所属专栏&#xff1a;数据结构学习笔记 &#x1f4a5;对于数据结构顺序表链表有疑问的都可以在上面数据结…

ai直播数字人:AI大模型应用开发的神奇世界

当AI技术的发展走向一个新的高峰&#xff0c;AI直播数字人逐渐成为人们关注的焦点。这种全新的数字人形态&#xff0c;通过大模型应用开发&#xff0c;带来了一个神奇世界。 在这个神奇世界里&#xff0c;AI直播数字人可以展现出与真实人类相媲美的外貌和声音。通过先进的图像…

[递归、搜索、回溯]----递归

前言 作者&#xff1a;小蜗牛向前冲 专栏&#xff1a;小蜗牛算法之路 专栏介绍&#xff1a;"蜗牛之道&#xff0c;攀登大厂高峰&#xff0c;让我们携手学习算法。在这个专栏中&#xff0c;将涵盖动态规划、贪心算法、回溯等高阶技巧&#xff0c;不定期为你奉上基础数据结构…

ROS 2基础概念#6:服务(Service)| ROS 2学习笔记

服务&#xff08;Service&#xff09;是 ROS 2 计算图中节点通信的另一种方法。 服务基于调用和响应模型&#xff0c;而不是主题的发布者-订阅者模型。 虽然主题允许节点订阅数据流并获取持续更新&#xff0c;但服务仅在客户端专门调用时才提供数据。 ROS 2服务的基本概念 ROS…

UE4升级UE5 蓝图节点变更汇总(4.26/27-5.2/5.3)

一、删除部分 Ploygon Editing删除 Polygon Editing这个在4.26、4.27中的插件&#xff0c;在5.1后彻底失效。 相关的蓝图&#xff0c;如编辑器蓝图 Generate mapping UVs等&#xff0c;均失效。 如需相关功能&#xff0c;请改成Dynamic Mesh下的方法。 GetSupportedClass删…

微服务超大Excel文件导出方案优化

1、在导出Excel时经常会碰到文件过大&#xff0c;导出特别慢 2、微服务限制了请求超时时间&#xff0c;文件过大情况必然超时 优化思路&#xff1a; 1、文件过大时通过文件拆分、打包压缩zip&#xff0c;然后上传到oss,并设置有效期&#xff08;30天过期&#xff09; 2、把…