文章目录
3.5.1 数组
- 数组是一种复合类型,必须在定义时就指定大小。
- 基本格式: 类型 变量名 [常量表达式],如果同时进行初始化,可以省略常量表达式,由编译器确定大小。
- 注意复杂数组的声明:
声明 | 说明 |
---|---|
int *ptrs[10]; | 存放10个整型指针的数组 |
int &refs[10]; | 写法错误,不存在引用的数组 |
int (*parray)[10]; | parray是一个指针,指向一个数组,这个数组中含有10个整型对象 |
int (&arrRef)[10]; | arrRef是一个引用,引用的对象是一个数组,这个数组中含有10个整型对象 |
int *(&arry)[10]; | arry是一个引用,引用的对象是一个数组,这个数组中含有10个int型的指针对象 |
- 不允许使用一个数组对另一个数组进行赋值或者初始化
3.5.1练习
练习3.27
假设txt_size是一个无参函数,它的返回值是int。请回答下列哪个定义是非法的,为什么?
unsigned buf_size = 1024;
int ia_0[buf_size];
int ia_1[4*7-14];
int ia_2[text_size()];
char st[11] = "fundamental";//不合法,st容量太小
练习3.28
下列数组中元素的值是什么
string sa[10];//10个空string
int ia[10];//10个0
int main()
{
string sa2[10];//10个空string
int ia2[10];//10个0
}
练习3.29
相比vector而言,数组有哪些缺点
数组容量必须在声明时就指定,无法动态变化,无法适应变化的空间。
3.5.2 访问数组元素
- 数组可以使用for或者下标来进行访问,索引从0开始
- 数组下标的类型通常是size_t类型
- 数组也可以使用for范围循环进行访问
- 使用下标访问时一定要注意数据越界的问题
3.5.2 练习
练习3.30
指出下面代码中的索引错误
constexpr size_t array_size = 10;
int ia[array_size];
for(size_t ix = 1;ix<=array_size;++ix)
ia[ix] = ix;
数组的索引开始于0,结束于array_size-1,如题中所用会导致数组越界
练习3.31
编写一段程序,定义一个含有10个int的数组,令每个元素的值就是其下标值
//由于10的数量较小,可以直接定义+初始化
int arr_1[10]{0,1,2,3,4,5,6,7,8,9};
//利用for循环初始化
int arr_2[10];
for(size_t i = 0;i<10;i++)
{
arr_2[i] = i;
}
练习3.32
将上一题刚刚创建的数组拷贝给另外一个数组 。利用vector重写程序,实现类似的功能。
int arr_new[10];
for(size_t i = 0;i<10;i++)
{
arr_new[i] = arr_2[i];
}
std::vector<int> vec;
for(size_t i = 0;i<10;i++)
{
vec.push_back(arr_2[i]);
}
练习3.33
对于下面的程序来说,如果不初始化scores将发生什么 ?
unsigned scores[11] = {};
unsigned grade;
while (cin >> grade)
{
if(grade <= 100)
++scores[grade/10];
}
根据具体编译器,可能会初始化为不同的值
3.5.3 指针和数组
- 在使用数组时,编译器一般会将它转换成指向这个数组的首元素的指针
- 指针也是一种迭代器,迭代器支持的操作在指针上一般也支持
- 使用标准库函数
begin
和end
可以获取一个数组的首元素指针或尾元素指针:
int ia[] = {1,2,3,4,5};
int *beg = begin(ia);
int *last = end(ia);
4.获得的指针可以使用解引用操作
3.5.4 练习
练习3.34
假定p1和p2指向同一个数组中的元素,则下面程序的功能是什么?什么情况下该程序是非法的?
p1 += p2 - p1;
使指针指向p2
当p1为常量指针时非法,此时不允许修改p1
练习3.35
编写一段程序,利用指针将数组中的元素置为0
unsigned scores[] = {1,2,3,4,5,6,7};
for (auto bg = begin(scores),ed = end(scores); bg < ed; bg++)
{
*bg = 0;
}
练习3.36
编写一段程序,比较两个数组是否相等。再一段程序,比较两个对象是否相等
//假定两个数组必须长度和数字必须都相等才相等
unsigned scores_1[] = {1,2,3,4,5,6,7};
unsigned scores_2[] = {1,2,3,4,5,6,7};
//利用begin和end获得数组长度
int length_1 = end(scores_1) - begin(scores_1);
int length_2 = end(scores_2) - begin(scores_2);
bool equals = length_1 == length_2;
if(equals)
{
//确定长度相等之后,可以使用指针迭代器,也可以使用下标,我认为使用下标更简洁
for(size_t i = 0;i< length_1 && i< length_2;i++)
{
equals = equals && (scores_1[i]==scores_2[i]);
if(!equals) break;
}
}
cout << length_1 << endl;
cout << equals << endl;
//vector与数组基本一样,不过获取长度有封装好的成员函数可以直接调用
std::vector<int> vec_1 = {1,2,3,4,5,6,7};
std::vector<int> vec_2 = {1,2,3,4,5,6,7};
bool equals_vec = vec_1.size() == vec_2.size();
if(equals_vec)
{
for(size_t i = 0;i< vec_1.size() && i< vec_2.size();i++)
{
equals_vec = equals_vec && (vec_1[i]==vec_2[i]);
if(!equals_vec) break;
}
}
cout << equals_vec << endl;