C++数组使用方法

1、定义和初始化
arr[n]
arr是数组名,n是数组中元素的个数(n为常量表达式)。
        数组是一种符合类型(基于其他类型定义的类型,如,指针、引用)。定义数组时必须定义数组类型,不允许使用auto关键字由初始值推断数组类型。

int arr[10];//含有10个整数的数字
int *parr[20];//含有20个整型指针的数组

2、字符数组
        我们可以直接使用字符串字面值对字符数组进行初始化。注意字符串结尾处有一个空字符。

char arr1[] = {'C','+','+'};//数组维度为3
char arr2[] = {'C','+','+','\0'};//数组维度为4
char arr3[] = "C++";//数组维度为4
const char arr3[3] = "C++";//错误!数组大小不够


3、
不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值。(有一些编译器支持数组赋值,但是最好不用!)

int arr[] = {0,1,2}
int arr2[] = arr;//错误!不能使用一个数组初始化另一个数组
arr2 = arr;//错误!不能把一个数组直接赋值给另一个数组


4、数组本身就是对象,允许定义数组的指针及数组的引用,但不存在引用的数组。

int (*Parray)[10] = &arr;//Parray是一个指针,指向一个含有10个整数的数组
int (&arrDef)[10] = arr;//arrDef是一个引用,引用的对象是一个含有10个整数的数组
int &refs[10] = /*?*/;//错误!不存在引用的数组
int *(&arry[10]) = ptrs;//arry是一个含有10个int型指针的数组的引用

5、对数组声明的理解 

(理解数组声明的含义应当从数组的名字开始按照从内向外的方式理解!)

int (*Parray)[10];

(*Parray):Parray是一个指针,

(*Parray)[10]:Parray是一个指向大小为10的数组的指针;

int (*Parray)[10]:数组中的元素是int,所以Parray是一个指针,指向一个维度为10的int数组。

int *(&arry)[10] = ptrs;

(&arry):arry是一个引用;

(&arry)[10]:arry引用的对象是一个维度为10的数组;

int *(&arry)[10]:数组的元素类型是指向int的指针,所以arry是一个含有10个int型指针的数组的引用。


6、访问数组元素

通过下标运算符访问:

        在使用数组下标时,通常将其定义为size_t类型。size_t是一种机器相关的无符号类型,在头文件<cstddef>中定义。 

使用范围for语句访问:

        维度是数组类型的一部分,数组中有多少个元素系统是已知的,使用范围for语句比较方便。

for(auto i:arr)//对于数组中的每一个元素
    cout<<i;//输出当前的元素

7、数组和指针

        使用数组的时候,编译器会把它转换成指针,对数组的元素使用取值符就能得到指向该元素的指针。取地址符可以用于任何对象,数组的元素也是对象(这些对象本身没有名字,需要通过数组下标访问),对数组使用下标运算符得到该数组对应下标位置的元素。与其他对象一样,对数组的元素使用取地址符就得到指向该元素的指针

string nums[] = {"one","two","three"};//数组元素是string对象
string *p = &nums[0];//p指向nums的第一个元素


        在使用数组名时,编译器会将其替换成一个指向数组首元素的指针

string *p = nums;//等价于p = &nums[0]


        【在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。】

        由此,当使用数组作为一个auto变量的初始值时,编译器推断得到的类型是指针而非数组:

int ia[] = {0,1,2,3,4,5,6,7};
auto ia2(ia);//ia2是一个整型指针,指向ia的第一个元素

        虽然ia是数组,但当ia为一个auto变量的初始值时,编译器实际执行的初始化过程类似如下:

 auto ia2( &ia[0] );//显然,ia2的类型是int * (对数组的元素使用取地址符就得到指向该元素的指针)

        当使用decltype关键字时(是一种类型说明符,用于希望从表达式的类型推断要定义的变量的类型,而不用表达式的值来初始化变量),上述转换不会发生。decltype( ia )返回的类型是由10个整数组成的数组。

int ia[] = {0,1,2,3,4,5,6,7,8,9};
decltype( ia ) ia3 =  {9,8,7,6,5,4,3,2,1,0};
ia3 = p;//非法!不能用整型指针给数组赋值(p为int型指针)
ia3[1] = i;//正确!i为int型整数


8、指针也是迭代器

        与vector和string一样,迭代器支持的运算,数组指针都支持。如,使用递增运算符将指向数组元素的指针向后移动: 

int arr[] = {0,1,2,3,4,5,6,7,8,9}
int *p = arr;//p指向arr的第一个元素
++p;//p指向arr的下一个元素


9、利用指针遍历数组

        下面这段程序和上面程序的作用效果是一样的,都是实现数组遍历:

int *e = &arr[10];//e是指向数组末尾元素下一个位置的指针
for(int *b = arr; b != e;b++)
    cout<<*b<<endl;//输出arr的元素


10、使用C++11新标准引入的两个函数,begin和end(定义在头文件<iterator>中)

int ia[] = {0,1,2,3,4,5,6,7,8,9}
int *beg = begin(ia);//指向数组首元素
int *last = end(ia);//指向数组末尾元素下一个位置的指针
while(beg != last)
    beg++;//遍历数组

        函数begin返回指向ia首元素的指针,函数end返回指向ia尾元素下一位置的指针。使用 begin 和 end 可以很容易写出一个循环用于处理数组中的元素。例如:

//arr是一个整型数组,程序用于找到arr中的第一个负数
int *pbeg = begin( arr );//pdeg是指向arr首元素的指针
int *pend = end( arr );//pend是指向arr尾元素下一个位置的指针
while( pbeg != pend && *pdeg >= 0 )
    ++pbeg;

        while语句的条件部分通过比较 pbeg 和 pend 来确保可以安全地对 pbeg 解引用。如果 pbeg 确实指向一个数组元素,则将其解引用并检查元素的值是否为负值。

        【注意:尾后指针不能执行解引用和递增操作!】

11、指针移动

constexpr size_t sz = 5;
int arr[sz] = {1,2,3,4,5}
int *ip = arr;
int *ip1 = ip + 4;//ip1指向arr的末尾元素
int *e = arr +sz;
while (ip < e)
    ip++;//实现遍历


        两个指针相减是他们之间的距离:

auto n = end(arr) - begin(arr);// n 为数组的长度

        两个指针相减所得的结果的数据类型是一种名为 ptrdiff_t 的标准库类型(定义在头文件<cstddef>中)。因为差值可为负数,所以 ptrdiff_t  是一种带符号类型。
12、解引用和指针运算的交互

        指针加上(减去)一个整数所得结果还是指针。 

int arr[] = {0,2,4,6,8};
int last = *(arr + 4);//计算arr移动四个元素后的新地址,然后解引用该指针,其效果等价于arr[4]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值