数组
数组是一种类似于标准库类型vector的数据结构,它们都可以存放同种类型的对象,对象本身没有名字,需要根据位置进行访问。不同之处在于,数组大小固定,注意:如果不清楚元素的确切个数,请用vector。
1.定义初始化数组
1. unsigned cnt=42;
string bad[cnt]; // 错误 cnt不是常量表达式 数组中元素的个数必须是固定的
2. 和内置类型一样,如果在函数内部定义了某种类型的数组,默认初始化会让数组含有未定义的值,声明变量最好先初始化。
3.char a1[]={‘C','+’,‘+’}; char a2[]="C++"; 注意 字符数组可以用字符串进行初始化,可是a1的维度是3,a2的维度是4,后边还有个‘\0’
4.数组不允许拷贝和赋值 Int a[]={1,2}; int a2[]=a; // 错误 a2[]=a; // 错误
5.理解复杂的数组声明
和vector一样,数组能存放大多数类型对象,可以存放指针的数组,int *ptrs[10]; // 数组中含有10个指向整型的指针
int &refs[10]= /*?*/; // 引用数组 错误 数组是占存储空间的,它实际上是指针,保存了N个相同大小的内存地址,引用是不占用内存的,所以如果出现了引用数组,引用不占内存,数组占内存,这是相互矛盾的
int (*Parray)[10]; // Parray指向一个含有10个元素的数组的指针
int (&refs)[10]=arr; // 数组引用 int[10](&refs)=arr;
int *(&arry)[10]=ptrs; // arry是个数组的引用,引用包含10个指向整型的指针的数组
2访问数组元素
1.使用数组下标的时候,定义的类型为size_t类型,这种类型是与机器有关的无符号类型
2. // 以10分为一个分数段 统计成绩数量 0--9 10--19 20--29...90-99 100
unsigned scores[11]={0}; unsigned grade; 范围for循环 for(auto i:scores) // 维度本来就是数组一部分,scores后不需要加[10]
while(cin>>grade) cout<<i<<" "; {
if(grade<=100)
++scores[grade/10]; }
cout<<endl;
3. 大多数安全问题都源于缓冲区溢出,当数组下标越界并试图访问它,就会出现错误,而编译器还检查不出这样的错误 使用数组一定注意此类错误
3.指针和数组
1. 很多用到数组名字的地方,编译器都会自动将数组名转换为指向数组首元素的指针 int *p=nums; // 等价于 &nums[0]
2. 指针也是迭代器 // 数组遍历可以这样写代码 简单明了
int arr[]={0,1,2,3,4,5,6,7,8,9};
int *e=&arr[10];
for(int *b=arr;b!=e;++b)
cout<<*b<<" ";
3.标准库函数begin end函数
C++新标准引入名为begin和end的函数,这两个函数存放在头文件iterator中
int *beg=begin(arr); int *last=end(arr); // last尾后指针不能执行解引用和递增操作,可执行递减操作
4. int i=0,sz=42;
int *p=&i,*e=&sz;
while(p<e) // 错误 p和e无关 比较无意义 若pe指向同一个数组中的元素 比较可以进行
5. int *p=&arr[2]; int k=p[-2]; // p[-2]相当于arr[0] 内置类型下标运算符可以不是无符号类型,而string、vector标准库类型下标为无符号类型
4.C风格字符串
1.string函数
strlen(p); // p类型为char*类型 string类型错误 看string类型长度string::size()函数
strcmp(p1,p2); strcat(p1,p2); strcpy(p1,p2); // char *类型
2. char ca1[],ca2[];
if(ca1<ca2) // 比较两个无关地址,未定义 string类型可以直接进行字符串的比较
3. 对大多数应用来说,使用标准库string要比C风格字符串更安全、更高效
5.与旧代码的接口
1.string对象加法运算允许使用一个以空字符结束的字符数组作为其中一个运算对象(不能为两个);
2.char *str=s; // 错误 不能用string类型初始化char *
char *str=s.c_str(); // 正确
3.使用数组初始化vector对象
int arr[]={0,1,2,3,4,5,6,7,8,9};
vector<int> ivec(begin(arr),end(arr)); // ivec次序和值与arr完全一样
4.现代C++程序中,尽量使用vector和迭代器,避免使用数组和指针;尽量使用string,避免使用C风格基于数组的字符串