C++学习笔记-数组

定义数组

维度(数组的元素个数)也是数组类型的一部分,必须是编译时已知,因此维度必须是常量表达式

常量表达式

1.字面值常量及其复合运算

  20,20+12,"hello"等

2.const变量且用初始值是常量表达式(字面值常量,已知的常量表达式以及它们的复合运算)

const int n=10;

const int m=n+10;

3.constexpr变量,且初始值是常量表达式

constexpr int mf=20;

数组元素的初始化

默认情况下,数组元素被默认初始化。当数组元素是内置类型时:

对于是全局变量的数组,元素都被初始化为0;对于非全局变量的数组,元素含有未定义的值

当数组元素是类时:

若该类有默认构造函数,用默认构造函数初始化,否则必须显示初始化

字符数组的初始化

可以用若干个字符列表初始化数组 char a[]={'a','b'};此时数组a长度为2

也可以用字符串字面值初始化数组 char b[]="ab";此时数组b长度为3,比a多个表示字符串结尾的空字符

数组不允许拷贝和赋值

char c[]=a;  //错误,不允许拷贝

char c[2];c=a;  //错误,不允许赋值

复杂数组

int arr[10]={1,2,3,4,5,6};

int *ptrs[10];   //ptrs是数组名,它是含有10个整型指针的数组

int (*parray)[10]=&arr;  //parray是指针,其指向含有10个元素的数组arr

int (&arrRef)[10]=arr;  //arrRef是引用,其引用一个含有10个元素的数组arr

先看数组名,分析是一般数组名还是指针或者引用,按照由内向外的顺序阅读,分析至int *ptrs[10]这种层次,就从右向左理解,也可借助右侧的初始值的类型判断

数组下标

通常将其定义为size_t类型,是机器相关的无符号类型。注意用检查其合法性。应大于等于0且小于数组大小。

遍历数组

可用范围for语句 for(auto i:arr){}

或者用下标for语句 for(size_t i=0;i<10;i++){}

把数组当成指向数组首元素的指针

可以把数组名当作指向数组首元素的指针。编译器就是这么转换的。

auto和decltype作用于数组名得到不同的类型

int a[10];

auto a2(a)  得到a2是整型指针

decltype(a) a3[10]; 得到a3是10个整数构成的数组

定义指向数组第一个元素和最后一个元素的下一个位置的指针

int a[10]={}

int *b=a;(或者int *p=&a[0];)  //指向第一个元素

int *e=&a[10];//指向最后一个元素的下一个位置

也可用下面的方法:

int *b=begin(a);

int *e=end(a);

用指针遍历数组

while(b!=e){}

指针也支持所有的迭代器运算

指针 数组名与下标

int a[10]={};

int *p=a;

p[2]等价于a[2],等价于*(p+2)(数组就是指向数组首元素的指针),均指a中第三个元素

p[i]与a[i]不同的在于,p[i]中的i可以是负数,而a[i]中的i只能是非负数

int a[10]={};

int *p=&a[3];

p[-2]等价于a[1]

C风格的字符串

是指存放在字符数组中,以空字符结束的字符串。一般用指针操作这些字符串。

例 char a[]="hello";或char b[]={'a','b','\0'};

操作的函数

定义在cstring(string.h的C++版本)中,常用的有strlen(p),strcmp(p1,p2),strcat(p1,p2),strcpy(p1,p2)它们的参数必须是指针,例如:

strcmp(a,b);

建议:用vector和迭代器,代替内置数组和指针;用string代替C风格的基于数组的字符串

可以用数组初始化vector对象:

int a[]={1,2,3,4,5,6};

vector<int> iv(begin(a),end(a));

可以用C风格字符串初始化string对象,给string对象赋值,或者加法运算的一个运算对象

char a[]="hello";

string s1(a);

string s2;

s2=a;

string s3=a+s1;

不能用vector对象初始化数组

可以用string对象的c_str成员函数得到常量C风格字符串

string s("hello");

const char *str=s.c_str();

多维数组

实质是数组的数组。

int ia[3][4];//ia是有3个元素 的数组,这3个元素每个都是含有4个整数的数组

int arr[10][20][30];//arr是大小为10的数组,它的每个元素是大小为20的数组,这些数组的元素是含有30个整数的数组

多维数组的初始化

二维数组的第一维称作行,第二个维度称作列

int ia[3][4]={

{0,1,2,3},//第一行

{4,5,6,7},//第二行

{8,9,10,11}//第三行

};

遍历多维数组

int ia[m][n];

for(size_t i=0;i<m;i++){

for(size_t j=0;j<n;j++){

ia[i][j]=i*m+j;

}

}

也可用范围for语句

size_t cnt=0;

for(auto &row:ia)

for(auto &col:row){

col=cnt;

++cnt;

}

使用引用的原因是:

1.col写成引用是因为,需要改变col的值

2.row也必须写成引用是因为,若row不是引用,则编译器会将其转换为指向数组首元素的指针,这会引起内层范围for循环不合法。

所以使用范围for循环处理多维数组时,除最内层外,其他所有的控制变量都应该是引用类型

使用指针和数组名遍历多维数组

程序会把多维数组的名字,自动转换为指向数组首元素的指针,例

int ia[3][4];

int (*p)[4]=ia;//ia是&ia[0],而ia[0]是一个含有4个元素的数组,p是指向有4个元素的数组的指针

for(auto p=ia;p!=ia+3;p++){  //p是指向有4个元素的数组的指针,++p使得p指向下一个有4 个元素的数组

for(auto q=*p;q!=*p+4;q++){  //*p是数组,数组名被转换成指向该数组首元素的指针,q指向数组首元素

...

}

}

如果必须写出变量类型的话,借助于以下类型别名

typedef int int_array[4];

或者using int_array=int[4];

则上面的双重for循环可写成

for(int_array *p=ia;p!=ia+3;p++){  //*p是数组   for(int (*p)[4]=ia;p!=ia+3;p++)

for(int *q=*p;q!=*p+4;q++){  //q指向数组首元素

...

}

}

用begin和end更简洁

for(auto p=begin(ia);p!=end(ia);p++){

for(auto q=begin(*p);q!=end(*p);q++){

...

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值