阵列

阵列是一系列可以通过添加一个索引的唯一标识符被单独引用的同一类型放置在连续的存储单元的元件。

这意味着,例如,类型的五个值 int可以声明为阵列无需声明5个不同的变量(每个都有其自己的标识符)。相反,使用数组,这五个 int值被存储在连续的存储单元,并且所有五个可使用相同的标识符被访问,以适当的指数。

例如,含有式5的整数值的数组 int称为 foo:如可以表示

 
,其中每个空面板表示数组的元素。在这种情况下,这些都是类型的值 int。这些元件是从0至4的编号,是0,第一和4的最后一个; 在C ++中,数组中的第一个元素总是与零(不是一)编号,无论它的长度。

像一个普通的变量,在使用前数组必须申报。在C ++中的阵列的典型的声明为: 其中,是一个有效的类型(如,...),是一个有效的标识符和字段(其总是包含在方括号),则指定在以下方面的阵列的长度元素的数量。 因此,数组,类型的五个元素,可以声明为:

type name [elements];

type int float name elements []

foo int

 
int foo [5];
 


注: elements括号内场 [],占数组中元素的个数,必须是一个 常量表达式,因为数组是静态存储器的大小必须在编译时确定的块,在程序运行之前。

初始化数组

默认情况下,定期阵列 本地范围(例如,那些在函数内声明)遗留未初始化。这意味着,没有它的元件被设置为任何特定的值; 其内容是在数组声明的一点不确定。

但在数组中的元素,可以显式初始化为特定值时,它被宣布,通过在大括号包围的初始值{}。例如:

 
int foo [5] = { 16, 2, 77, 40, 12071 }; 
 


这个语句声明可以表示一个这样的数组:

 
值的括号之间的数量 {}不得超过数组中元素的数量。例如,在上面的例子中, foo被宣称具有5个元件(如由方括号中的数字指定的 []),并在大括号 {}中包含完全相同的5个值,一个用于每个元素。如果用量少声明的,其余的元素被设置为默认值(其为基本类型,意味着它们用零填充)。例如:

 
int bar [5] = { 10, 20, 30 }; 
 


将创建一个数组是这样的:

 
初始化器甚至可以没有价值,只是括号:

 
int baz [5] = { }; 
 


此创建五个数组 int值,每个具有一个零值初始化:

 
当提供了一种用于数组值的初始化,C ++允许离开的方括号空的可能性 []。在这种情况下,编译器会自动假设一个大小为包含在大括号内的值的数量相匹配的数组 {}

 
int foo [] = { 16, 2, 77, 40, 12071 };
 


在此声明之后,阵列 foo将是5  int长,因为我们提供了5初始化值。

最后,C ++的发展导致了采用 通用的初始化也为数组。因此,对于声明和初始化之间的等号不再需要。这两个语句是等价的:

1
2
int foo[] = { 10, 20, 30 };
int foo[] { 10, 20, 30 }; 
 


静态数组和那些直接在命名空间(任何函数之外)声明的,总是被初始化。如果没有指定明确的初始化时,所有的元素都默认初始化(用零,对于基本类型)。

访问数组的值

的任何数组中的元素的值可以像相同类型的常规变量的值进行访问。语法是:

name[index] 
按照前面的例子中, foo有5个元素,每个元素都是类型的 int,它可以被用来指各元素的名称是:

 
例如,以下语句存储在第三值75元素 foo

 
foo [2] = 75;
 


并且,例如,下面的副本的第三元素的值 foo到一个称为变量 x

 
x = foo[2];
 


因此,表达式 foo[2]是本身类型的变量 int

注意,第三个元件 foo被指定 foo[2]的,因为第一个是 foo[0],第二个是 foo[1],因此,第三个是 foo[2]。通过同样的原因,它的最后一个元素 foo[4]。因此,如果我们写出 foo[5],我们将要访问的第六个元素 foo,并且因此实际上超过阵列的大小。

在C ++中,语法正确超越指数的有效范围为一个数组。这可能会产生问题,因为访问超出范围元素不上编译会导致错误的,但可以在运行时导致错误。这样做的原因被允许将在以后的章节中可以看出介绍指针时。

在这一点上,它是能够在该支架上的两个用途明确区分是重要的 []有相关的阵列。他们执行两个不同的任务:一是在声明时指定数组的大小; 而第二个是将被访问时对混凝土的数组元素指定的索引。不要混淆括号这两种可能的用途 []使用数组。

1
2
int foo[5];         // declaration of a new array
foo[2] = 75;        // access to an element of the array.  
 


主要的区别是,该声明是由元素的类型之前,而访问不是。

与阵列其他一些有效的操作:

1
2
3
4
foo[0] = a;
foo[a] = 75;
b = foo [a+2];
foo[foo[a]] = foo[2] + 5;
 


例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// arrays example
#include <iostream>
using namespace std;

int foo [] = {16, 2, 77, 40, 12071};
int n, result=0;

int main ()
{
  for ( n=0 ; n<5 ; ++n )
  {
    result += foo[n];
  }
  cout << result;
  return 0;
}
12206


多维数组

多维数组可以被描述为“数组的数组”。例如,二维阵列可以被想象成制成元件的二维表,它们全部相同统一的数据类型的。

 
jimmy代表3%5型的元件的二维阵列 int。C ++的这种语法是:

 
int jimmy [3][5];
 


并且,例如,该方式垂直和第四参考第二元件水平地表达为: 

 
jimmy[1][3]
 


 
(记住,数组的索引总是以零开头)。

多维数组不限于两个指数(即,两维)。它们可以根据需要包含尽可能多的指标。虽然要小心:所需要的数组的内存量指数与每个维度增加。例如:

 
char century [100][365][24][60][60];
 


声明与一个类型的元件的阵列 char用于在世纪每个第二。这相当于超过3十亿 char!所以,这个声明会消耗的内存超过3 GB的!

在结束时,多维数组只是为程序员一个抽象的,因为相同的结果可以用一个简单的阵列来实现,通过其指数相乘:

1
2
int jimmy [3][5];   // is equivalent to
int jimmy [15];     // (3 * 5 = 15)  
 


有与多维数组,编译器自动记住每个虚数维的深度唯一的区别。下面的代码两件产生完全相同的结果,而是一个使用了二维数组,而另一个使用一个简单的数组:

多维数组伪多维数组
#define WIDTH 5
#define HEIGHT 3

int jimmy [HEIGHT][WIDTH];
int n,m;

int main ()
{
  for (n=0; n<HEIGHT; n++)
    for (m=0; m<WIDTH; m++)
    {
      jimmy[n][m]=(n+1)*(m+1);
    }
}
#define WIDTH 5
#define HEIGHT 3

int jimmy [HEIGHT * WIDTH];
int n,m;

int main ()
{
  for (n=0; n<HEIGHT; n++)
    for (m=0; m<WIDTH; m++)
    {
      jimmy[n*WIDTH+m]=(n+1)*(m+1);
    }
}

上面的两段代码都没有在屏幕上产生任何输出,但两个赋值给名为吉米以下列方式内存块:

 
请注意,该代码使用定义的常量的宽度和高度,而不是直接使用他们的数值。这使代码更好的可读性,并允许在代码的变化在一个地方容易进行。

数组作为参数

在某些时候,我们可能需要一个数组传递给函数作为参数。在C ++中,这是不可能的表示存储器的整个块由阵列直接传递给函数作为参数。但可以传递的却是它的地址。在实践中,这具有几乎相同的效果,并且它是一个更快,更有效的操作。

接受的函数数组作为参数,该参数可以声明为阵列型,但与空支架,省略了阵列的实际大小。例如:

 
void procedure (int arg[])
 


这个函数接受型“数组的一个参数 int叫”  arg。为了通过这个功能的数组声明为:

 
int myarray [40];
 


这将是足够写这样的电话:

 
procedure (myarray);
 


在这里,你有一个完整的例子: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// arrays as parameters
#include <iostream>
using namespace std;

void printarray (int arg[], int length) {
  for (int n=0; n<length; ++n)
    cout << arg[n] << ' ';
  cout << '\n';
}

int main ()
{
  int firstarray[] = {5, 10, 15};
  int secondarray[] = {2, 4, 6, 8, 10};
  printarray (firstarray,3);
  printarray (secondarray,5);
}
5 10 15
2 4 6 8 10


在上面的代码,第一个参数( int arg[])接受其元素类型的任何数组 int,无论它的长度。出于这个原因,我们已包括告诉函数的每个我们传递给它作为它的第一个参数数组的长度的第二参数。这允许对循环打印出该阵列,以知道传递数组中进行迭代的范围内,不出去的范围。

在函数声明,它也可以包括多维数组。对于三维阵列参数的格式为:

 
base_type[][depth][depth]
 


例如,一个多维数组作为参数的函数可以是: 

 
void procedure (int myarray[][3][4])
 


注意,第一托架 []被留为空,而下述的指定各自的尺寸大小。这是为了必要的编译器能够确定每个附加维的深度。

在某种程度上,传递一个数组作为参数总是输的维度。背后的原因是,由于历史原因,数组不能直接复制,因此,什么是真正传递是一个指针。这是新手程序员错误的常见原因。虽然指针清醒的认识,在未来的一章解释,有很大帮助。

库阵列

该阵列上面的解释,直接实现为语言功能,从C语言继承。他们是一个很大的特点,但通过限制它的拷贝,轻松地衰变成三分球,他们可能从过剩优化之苦。

为了克服这些问题,与语言内置阵列,C ++提供了一种替代数组类型为标准集装箱。这是首部中定义的类型模板(类模板,其实) <array>

容器是一个图书馆的功能,属于本教程的范围,因此,类将不会在这里详细解释。只要说,它们以类似的方式内置的阵列操作,不同之处在于它们允许被复制(一种实际上昂贵的操作,复制存储器的整个块,从而小心使用)和衰变成指针只有当明确地叫这样做(通过其部件的装置 data)。

只是作为一个例子,这些是使用内置本章所述阵列的语言,并在库中容器的相同示例的两个版本:

语言内置阵列集装箱库阵列
#include <iostream>

using namespace std;

int main()
{
  int myarray[3] = {10,20,30};

  for (int i=0; i<3; ++i)
    ++myarray[i];

  for (int elem : myarray)
    cout << elem << '\n';
}
#include <iostream>
#include <array>
using namespace std;

int main()
{
  array<int,3> myarray {10,20,30};

  for (int i=0; i<myarray.size(); ++i)
    ++myarray[i];

  for (int elem : myarray)
    cout << elem << '\n';
}

正如你所看到的,这两种阵列使用相同的语法来访问它的元素: myarray[i]。除此之外,主要区别放置在阵列的声明,和用于列入一个附加报头的 库阵列还要注意它是如何容易访问的大小 图书馆阵列
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值