数组及多维数组
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个元素,其中每个元素都是一个指向整型对象的指针。
相关文章推荐
- BZOJ 2120: 数颜色 分块
- ural Parliament 二叉排序树前/...序遍历的转换
- 报错:ORA-02287: 此处不允许序号
- C语言中,数组名作为参数传递给函数时,退化为指针
- wireshark相关
- 20150820 - 作业 【自行学习命令】
- Redhat7安装Madagascar简易教程
- Cypher自己常用语句
- day08
- Windows上安装使用MongoDB(一)
- js算法:分治法-归并排序
- android viewinject 反射 注解 IOC
- Python中的ORM
- Android :内部文件中写操作
- Java精确运算(BigDecimal)
- ios图文混排简单演示
- LeetCode(6) ZigZag Conversion
- BNU 39423 最大团
- 黑马学习笔记_面向对象
- noip2012初赛-坐标统计