C++ Array的一些探讨
Array 与 Pointer 的关系
Array 不是 Pointer 。
Array 是 藉由 pointer 来操作 ,就像是 Iterator 与 STL Container 的关係。
STL Algorithm 可以藉由 Iterator 来操作 STL Container,也可以使用 pointer来操作 array。 Iterator 就是去模仿 pointer 的行为,像是提领 *i,取下十个位置 i+10、步进 i++、与赋值 *i=element,利用隐性介面来让 STL Algorithm 可以适用 相同行为 的 Iterator 类操作。
Iterator 与 Pointer 在 const 上的相似性 。
皆指向 int ,没有 const 相关 限制。
vector
::iterator a; int a;
皆指向 int ,不能藉由 a 去修改被指向的 element 。
vector
::const_iterator a; const int a;
皆指向 int ,可以藉由 a 去修改被指向的 element ,不能修改 pointer 本身,像是无法 a++。
const vcctor
::iterator a; int const a;
皆指向 int ,不能藉由 a 修改被指向的 element ,也不能修改 pointer 本身,像是无法 a++。
const vector
::const_iterator a; const int const a;
Array 的隐性转型
对 array 做任何加减,都会隐性转型成 pointer to first element of arraytype,取值后的 type 就已经不是塬本的 array type。
int a[10];
auto b = a;
auto b = static_cast
(a); // 与第二行等价 auto c = a + 0;
auto c = static_cast
(a); // 与第四行等价 // b 与 c 都一样是 pointer to first element to array 型别
无法对 array 做 increment(operator++) 与 decrement (operator--)。
int a[10];
a++; // compile error
a--; // compile error
因为 a++ 即为 a = a + 1 ,你无法使 int array type 接收一个 pointer to inttype。
array 不支援 copy assignment,但可以被 initializer list 初始化。
int a[10] = { 3, 3, 4, 5, 6, 7, 8}; // 你可以藉由 initializer list 去 initial array , 后面叁个元素会被 value-initilization 为 0
int b[10];
a = b; // compile error; 你无法对 array 做 assignment
int c[10] = b; // compile error 你无法藉由 array 去 initialize 另一个 array 。
以 Array 进出 Function
Function 以 pass by value 传递 array 参数 。
以 value 传递 array 时,第一维度一律皆自动转型成 pointer to first element of array type 。
一维阵列
int a[10];
void check1(int a[10]){ cout << typeid(a).name() << endl;}
void check2(int a[]){ cout << typeid(a).name() << endl;}
void check3(int *a){ cout << typeid(a).name() << endl;}
check1(a);
check2(a);
check3(a);
// 这叁种函式是等价的
array 参数自动转型于多维阵列,只限于第一个维度 。
void check4(int a[10][20][30]){
cout << typeid(a).name() << endl; // 印出 pi_A20_A30
}
请记住 array 皆会转型成 pointer to first element of array type,所以check4 函式中的 a 的型别,即为一个 pointer to first element of array ,这个 element 的型别是 int[20][30],所以 a 型别是 pointer to int[20][30]type。
Function 以 pass by reference 传递 array 参数 。
array 会被完整传递,不会有任何转型,因为 reference 只是一种别名。
对 a 修饰成一个 reference
void check4(int a[10][20][30]){
cout << typeid(a).name() << endl; // 印出 pi_A20_A30
}
Function 传回一个 array reference。
可以把 func() 本身当做是上一个例子的 a ,遵照 array 宣告格式:
ArrayElementType Target [ARRAY_SIZE][ARRAY_SIZE]...
如果你要传回一个 reference ,就是要修饰 function 的本体,把本体包起来,对它使用 & 修饰,再遵照宣告格式,把 function 摆在 Target 的位置上,就会很好思考了。
int (&func())[10][20] // 回传一个 Array int [10][20] 的 reference
{...}
cout << typeid(func()).name() << endl; // gcc 印出 A10_A20_i
其他
Class 的 array data member。
含有 array data member 的 class 在做 copy assignment 时,class A{int a[10];}; A a,b; a = b; 。因为 array 无法被 assignment ,应该是无法做 copy assignment 。不过实际测试过后, C++ 对于 array 这种 built-in type ,似乎会逐一将 array的 element copy 到 target object 的 array 中。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
