为了账号安全,请及时绑定邮箱和手机立即绑定

C++系统学习之四:数组

标签:
C++

与vector的异同

  • 相同:都是存放类型相同对象的容器

  • 不同:数组的大小确定不变,不能随意向数组中增加元素

1、定义和初始化内置数组

  数组中元素的个数也属于数组类型的一部分,编译的时候维度应该是已知的,也就是说,维度必须是一个常量表达式。

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

NOTE:

  • 定义数组的时候必须制定数组类型,不允许用auto

  • 数组元素应为对象,不能是引用

显式初始化数组元素

  可以对数组元素进行列表初始化,此时允许忽略数组的维度。当指定了维度,则维度应比列表初始值的数量多,当维度比初始化列表的数量大时,多的部分默认初始化。

字符数组的特殊性

  字符数组允许用字符串字面值来进行初始化,但数组的维度必须比字符串字面值大1,用来盛放添加的空字符'/0';

char a[]="hi";char a1[2]="hi";    //错误,最后的空字符'/0'没地方放

不允许拷贝和赋值

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

int a[]={0,1,2};int b[]=a;     //不允许使用一个数组初始化另一个数组       int b=a;        //不允许把数组直接赋值给另一数组

理解复杂的数组声明

  数组本身也是对象,因此可以定义指向数组的指针和引用。

?


int *ptrs[10];    //含有10个整型指针的数组int &refs[10]=a;    //错误,不存在引用的数组,数组的元素必须是对象int (*Parray)[10]=&arr;    //Parray指向一个含有10个整数的数组int (&arrRef)[10]=arr;    //arrRef引用一个含有10个整数的数组

2、访问数组元素

  可以使用范围for语句或下标来访问数组元素

  在使用下标的时候,通常将其定义为size_t类型。size_t类型是一种机器相关的无符号类型,它被设计得足够大以便能表示内存中任意对象的大小。在cstddef头文件中定义了size_t类型。

  遍历数组所有元素,最好的方法是范围for语句。

检查下标的值

3、指针和数组

  在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针。

  对数组的元素使用取地址符就能得到指向该元素的指针。

指针也是迭代器

  指向数组元素的指针可以执行迭代器一样的操作。

复制代码

    int a[10] = { 0 };    int n = 0;    for (auto &i : a)
    {
        i = n;
        n++;
    }    int *p1 = a;    //相当于迭代器的begin
    int *p2 = &a[10];    //相当于迭代器的end
    for (int *p3 = p1; p3 != p2; p3++)
    {
        cout << *p3 << endl;
    }

复制代码

标准库函数begin和end

  上述使用a[10]的地址来表示尾后指针很容易出错,因此标准库定义了数组用的begin和end函数来得到数组的首指针和尾后指针,其在iterator头文件中。

复制代码

int a[10] = { 0 };    int n = 0;    for (auto &i : a)
    {
        i = n;
        n++;
    }    /*int *p1 = a;    
    int *p2 = &a[10];*/
    int *p1 = begin(a);    int *p2 = end(a);    for (int *p3 = p1; p3 != p2; p3++)
    {
        cout << *p3 << endl;
    }

复制代码

二者同样的效果。

指针运算

  给指针加上一个整数,得到的新指针仍需指向同一数组的其他元素,或者指向同一数组的尾元素的下一位置。

解引用和指针运算的交互

  指针加上一个整数得到的结果仍是一个指针,因此可以解引用该指针。

下标和指针

  对数组执行下标运算其实是对指向数组元素的指针执行下标运算。

int i=a[2];//上面的下标引用其实是下面的过程int *p=a;
i=*(p+2);

  虽然标准库类型vector和string也能执行下标运算,但是数组与它们相比还是有所不同。标准库类型限定使用的下标必须是无符号类型,而内置的下标运算无此要求。

int *p=&a[2];int j=p[1];    //实际是a[3]int k=p[-2];    //实际上是a[0]

与旧代码的接口

混用string对象和C风格字符串

  C风格字符串:以空字符结尾的字符数组。

  string提供一个名为c_str()的成员函数来将string转换为C风格字符串,返回的是const char*类型。

使用数组初始化vector对象

   指明要拷贝区域的首元素地址和尾后地址即可。

int a[]={0,1,2,3,4,5};
vector<int> v(begin(a),end(a));

NOTE:不能用vector初始化数组。

  • 尽量不使用数组和指针,而使用vector和迭代器

  • 尽量不使用C风格字符串,而使用string

多维数组

  C++语言中没有多维数组,通常所说的多维数组其实是数组的数组。

int a[3][4];  //大小为3的数组,每个元素是含有4个整数的数组int b[10][20][30];

多维数组的初始化

  使用花括号括起来的一组值初始化多维数组,和普通数组初始化一样,只是数组的元素也是数组而已。

复制代码

int a[3][4]={
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}};int a[3][4]={0,,1,2,3,4,5,6,7,8,9,10,11};    //和上面的效果一样int a[3][4]={{0},{1},{3}};    //其余的默认初始化

复制代码

多维数组的下标引用

  表达式含有的下标运算符数量和数组的维度一样多,该表达式的结果将是给定类型的元素;当比数组的 维度数量小时,表示的是内层数组。

使用范围for语句处理多维数组

复制代码

size_t cnt=0;for(auto &row:a)   for(auto &col:row)
        col=cnt;
        cnt++;
}

复制代码

NOTE:

  使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应用是引用类型。为了防止编译器将auto控制变量转换成数组首元素的指针。

指针和多维数组

  当程序使用多维数组的名字时,也会自动将其转换成指向数组首元素的指针。

  也可以通过使用auto或decltype来遍历多维数组

复制代码

    int a[3][4] = {};    int cnt = 0;    for (auto p = a; p != a + 3; p++)
    {        for (auto q = *p; q != *p + 4; q++)
        {            *q = cnt;
            cnt++;
        }
    }    for (auto p = a; p != a + 3; p++)
    {        for (auto q = *p; q != *p + 4; q++)
        {
            cout << *q << " | ";
        }
        cout << endl;
    }

复制代码

也可以使用begin和end来简化

复制代码

        int a[3][4] = {};    int cnt = 0;    for (auto p = begin(a); p != end(a); p++)
    {        for (auto q = begin(*p); q != end(*p); q++)
        {            *q = cnt;
            cnt++;
        }
    }    for (auto p = begin(a); p != end(a); p++)
    {        for (auto q = begin(*p); q != end(*p); q++)
        {
            cout << *q << " | ";
        }
        cout << endl;
    }

复制代码

类型别名简化多维数组的指针

复制代码

    using int_array=int[4];    int a[3][4] = {};    int cnt = 0;    for (auto p = begin(a); p != end(a); p++)
    {        for (auto q = begin(*p); q != end(*p); q++)
        {            *q = cnt;
            cnt++;
        }
    }    for (int_array *p = a; p != a + 3; p++)
    {        for (int *q = *p; q != *p + 4; ++q)
        {
            cout << *q << " | ";
        }
        cout << endl;
    }

复制代码

原文出处:https://www.cnblogs.com/ZhouYong1991/p/9441591.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消