数组及多维数组

18 篇文章 0 订阅

数组

数组是一个比较特殊的内置类型,数组的大小固定,程序的运行性能较好但是灵活性降低。
数组在定义时,数组的维度必须是已知的,所以需要是常量表达式(否则可以动态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)[N],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个元素,其中每个元素都是一个指向整型对象的指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值