Essential C++ 学习笔记02--Array/Vector 与指针
Essential C++ 1.5-1.6节,3.1节笔记
Array/Vector/指针,难度偏大,
但若学习初期不熟悉基本用法,则难以写出有效代码。
1. 基本概念
- Array 是一段连续内存,数组名就是指向首地址的指针。是内建数据结构,兼容 C。
- Vector 可以理解为大小可变的数组,是一个类 class。
2. 指针的算术运算
指针可以进行自增(++), 自减(--), 加上一个整数(+, +=), 减去一个整数(-, -=)等算术运算。
在数组中使用频繁。
指针存的是内存地址,+/- 1 时,并非简单地加上或减去该整数值,而是加上该整数与指针引用的对象的大小的乘积。
这种实现方式的好处是,方便template模板编程。例如:ptr 指向数组的某个元素,ptr+1 就是下一个元素的地址(如果没有越界的话)。
int 的长度是 4,int型指针+1,内存地址+4.
double 的长度是 8,double 型指针+1,内存地址+8.
代码和执行结果如下:
#include <iostream> using namespace std; int main(){ int num[] = {10, 20, 30, 40}; double f[] = {10, 20, 30, 40}; int *ptr_int = num; double *ptr_double = f; for (int i=0; i<4; i++){ cout << ptr_int + i << " " << *(ptr_int + i) << ", " << ptr_double + i << " " << *(ptr_double + i); cout << endl; } }
执行结果:
3. Array
-
定义 Array 时,尺度必须是常量表达式,建议使用 const 变量。
Array 尺度无需执行期计算其值,则可在编译时分配栈内存。效率高,内存碎片小。
new/delete 分配的是堆内存。
- a[5] == 5[a]
[] 运算符的定义是 a[b] = *(a+b),所以,a[5] == *(a+b) == 5[a] - Array 不知道自己的大小。
但可以用 sizeof(Array_name) / sizeof(Array_type) 算出来。
#include <iostream> using namespace std; int main(){ int num[] = {10, 20, 30, 40}; double f[] = {10, 20, 30, 40, 11}; cout << sizeof(num) / sizeof(int) << endl; cout << sizeof(f) / sizeof(double); }
4. Vector
- 知道自己的大小。
Vector 大小可变,增加元素时需要判断是否需要 resize,所以,必须知道自己的大小。 - 不能像 Array 一样一次初始化多个变量(用{}括起)。原因?
练习1.5
撰写一个程序,使之能够询问用户姓名,并读取用户所输入的内容。
请确保用户输入的名称长度大于两个字符。如果用户的确输入了有效信息,就响应一些信息。
#include <iostream> #include <string> // String object using namespace std; int main(){ string name; cout << "What's your name? "; while ((cin >> name) && (name.size() <= 2)){ cout << "Please input your anme(more than 2 characters: "; } cout << "Hello, " << name << " ... and goodby!"; return 0; }
#include <iostream> #include <string.h> // C-Style using namespace std; int main(){ char name[10]; cout << "What's your name? "; while ((cin >> name) && (strlen(name) <= 2)){ cout << "Please input your anme(more than 2 characters: "; } cout << "Hello, " << name << " ... and goodby!"; return 0; }
练习1.6
撰写一个程序,从标准输入装置读取一串整数,并将读入的整数依次置入 array 及 vector。
然后遍历这两种容器,求取数值总和,将总和及平均值输出至标准输出装置。
分析:
1. 读取一串整数,可选择以字符串形式接收,或一个数字。
后者容易导致数据溢出,且需要反复转换数据类型。
2. char 转 int,直接减去 ASCII 的差值(48)即可。
3. 求和时,如果 Array 长度大于输入数字的个数,则无需遍历整个 Array 求和。
4. 求平均值时,不能直接用 int 除以 int。
#include <iostream> #include <vector> #include <string> using namespace std; int main(){ const int size_max = 100; int num_arr[size_max]; vector<int> num_vec(size_max); string raw_num; int num_count = 0; int sum_arr=0, sum_vec=0; double avg_arr=0.0, avg_vec=0.0; cout << "Input some numbers(no more that 100)" << " "; cin >> raw_num; num_count = raw_num.length(); // put numbers into array/vector for (int i=0; i<num_count; i++){ num_arr[i] = raw_num[i] - 48; num_vec[i] = num_arr[i]; } // array calculate for (int i=0; i<num_count; i++){ sum_arr += num_arr[i]; } if (num_count != 0) { avg_arr = double(sum_arr) / num_count; } else { avg_arr = 0.0; } cout << "array sum: " << sum_arr << ", " << "avg: " << avg_arr << endl; // vector calculate for (int i=0; i<num_count; i++){ sum_vec += num_vec[i]; } if (num_count != 0) { avg_vec = double(sum_vec) / num_count; } else { avg_vec = 0.0; } cout << "vector sum: " << sum_vec << ", " << "avg: " << avg_vec << endl; return 0; }