您的位置:首页 > 其它

数组及多维数组

2015-08-23 17:31 260 查看

数组

数组是一个比较特殊的内置类型,数组的大小固定,程序的运行性能较好但是灵活性降低。

数组在定义时,数组的维度必须是已知的,所以需要是常量表达式(否则可以动态new一个数组)

unsigned cnt = 42;  //是常量表达式
constexpr unsigned sz = 42;     //不是常量表达式


默认情况下,数组的元素被默认初始化。

字符数组的特殊性

char a1[]={'C','+','+'};        //列表初始化,没有空字符
char a2[]={'C','+','+','\0'};       //列表初始化,有空字符
char a3[]="C++";


不允许拷贝和赋值

不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值。

int a[]={1,2,3};
int a2[]=a;         //错误,不允许使用一个数组初始化另一个数组


复杂的数组声明

[]的优先级比*高

int *ptrs[10];      //ptrs是一个含有10个元素的数组,元素类型为int指针,可以简称为指针(的)数组。
int &refs[10];      //错误,不存在引用的数组。


不存在引用(的)数组可以这样理解,引用就是变量的别名,不是一个对象。这样引用本身是不占内存空间的(在实现时常常利用指针)。因此,声明引用数组没有办法分配空间,所以不能声明和定义引用数组。

int (*Parray)[10] = &arr;   //Parry指向一个含有10个整数的数组,简称数组的指针
int (&arrRef)[10] = arr;    //arrRef是一个含有10个整数的数组的引用,简称数组的引用。


传引用参数

把引用作为形参,这样对形参的操作实际上是作用在引用所引用的对象上。

使用引用避免拷贝

拷贝大的类型对象或者容器对象比较低效(值传递,需要值拷贝),甚至有些类类型(IO类型)根本就不支持拷贝操作。

使用引用形参返回额外信息

尽量使用常量引用

把函数不会改变的形参定义成(普通的)引用是一种常见的错误,这么做带给函数的调用者一种误导,即函数可以修改它的实参的值。另一方面,使用普通的引用,我们不能把const对象,字面值或者需要类型转换的对象传递给普通的引用。

指针形参

因为数组是以指针的形式传递给函数的,所以一开始函数并不知道数组的确切尺寸,调用者应该为此提供一些额外的信息。管理指针形参有三种常用的技术。

1、使用标记指定数组长度

数组有一个结束标记

2、使用标准库规范

void print(const int *beg, const int *end){
while(beg !=end)
cout <<*beg++<<endl;
}

int j[2]= {0,1};
print(begin(j),end(j));


3、显式传递一个表示数组大小的形参

void print(const int[], size_t size){

}


数组引用形参

前面说了可以有数组的引用,但是不能有引用的数组。所以形参可以是数组的引用。此时,引用形参绑定到对应的实参上,就是绑定到对应的数组上。

void print(int (&arr)[10]{
for(auto elem:arr)
cout <<elem<<endl;
}


上面的例子有一个局限就是执政将函数作用于大小为10的数组。

使用函数模板可以给引用类型的形参传递任意大小的数组。

template<unsigned N, unsigned M>
void print(const int (&p1)
,const int (&p2)[M]){
cout << p1[0] <<" " <<p2[0];
}


多维数组

c++中没有多维数组的概念,多维数组就是数组的数组。按照从内向外的阅读顺序有助于更好地理解其真实含义。

在c++11中增加了范围for的使用

二重for来处理二维数组

size_t cnt=0;
int ia[r][c];
for(size_t i=0; i!=r; ++i)
for(size_t j=0; j!=c; ++j){
ia[i][j]=cnt;
++cnt;
}


使用范围for

size_t cnt=0;
int ia[r][c];
for(auto &row : ia)
for(auto &col : row){
col = cnt;
++cnt;
}


注意使用引用类型

int a[3][4];

int (*a)[4]; //一个指针,它指向一个含有四个int型元素的数组

int a[4]; //一个四个元素的数组,元素的类型为int

void print(int (*a)[4])     //用括号将指针括起来
{
printf("%d\n",a[0][0]);
}

int main()
{
int a[3][4] = {1,2,3,4,5,6};
print(a);
return 0;
}


因此二维数组作为函数参数正确写法如下所示:

void Func(int array[3][10]);

void Func(int array[ ][10]);

因为数组的行数无关紧要,所以还可以写成如下形式:

void Func(int (*array)[10]); 注意*array需要用括号括起来。

这种形式的声明参数是一个指针,它指向具有10个元素的一维数组。因为[]的优先级比*的优先级高,故*array必须用括号括起来,否则变成了

void Func(int *array[10]);

这时候参数相当于是声明了一个数组,该数组有10个元素,其中每个元素都是一个指向整型对象的指针。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: