一、定義和初始化數組
1. int array[10];
2. const int a = 10;
int array[a];
3. int array[f()]; //當f()的返回值是一個常量時正確
4. int array[10] = {0,1,2,3,4,5,6,7,8,9};
5. int array[10] = {1,2,3};
6. int array[10] = {0}; //全部元素初始化為0
7. int array[10] = {1} //array[0] = 1,其他都為默認值0
8. int array[] ={ 1,2,3} //array含3個元素
二、數組不允許拷貝和賦值
不允許使用一個數組初始化另外一個數組,形如 int a[] = {1,2}; int a2[] = a;
不允許把一個數組直接賦值給另外一個數組,形如 int a[] = {1,2}; int a1[] = {3,4}; a1 = a;
三、復雜的數組聲明
1. int *ptrs[10]; //聲明了一個數組,含有10個整形指針
2. int &refs[10] = ... //錯誤,不存在元素為引用的數組
3. int (*ptr)[10] = &arrar; //ptr是一個指向數組的指針
4. int (&ref)[10] = array; //ref是一個數組的引用
5. int *(&ref)[10] = array; //ref是一個元素為指針的數組的引用
四、指針和數組
1. string nums[] = {"one","two","three"};
string *p = &nums[0]; //p指向數組的第一個元素
string *p1 = &nums; //與上一行等價,p1也指向數組的第一個元素
2. int a[3] = {1,2,3};
auto a2 = a; //此時,a2是一個地址,指向數組的第一個元素
auto a2(a); //效果相同
decltype(a) a3 = {1,2,3,4,5}; //一個例外,這里decltype(a)等價於int [] 類型
當使用數組名給其他變量賦值時,數組名代表的就是數組第一個元素的地址,但是反過來,不允許用指針變量給數組變量賦值。
3. int a[3] = {1,2,3};
int *p = a;
++p; //這里++p指向a[1],不能直接++a的原因是,a是一個不能修改的值(左值)
4. int *e = &a[4]; //首先,輸出a[4]時會輸出意想不到的東西
//這里數組a只有3個元素,但語法沒錯,e仍然可以得到后面緊跟着的那個地址
//只是對那個地址表示的變量進行解引用操作*e得到的是意想不到的東西。。。
//這里e的地址 004FF99C與&a[2]的地址 004FF998相差4個字節,++e輸出的是004FF9A0
5. C++11標准庫begin和end
int a[] = {1,2,3,4,5,6,7,8};
int *beg = begin(a); //返回首元素的地址
int *last= end(a); //返回尾元素的下一位置的地址,出了“門”的第一個地址
6. 指針后面加[]
#include<iostream> using namespace std;
void main() { int a[3] = { 1, 2, 3 }; int *p = a; cout << p[0] << endl;//輸出1 cout << p + 1 << endl;//輸出地址 cout << p[2] << endl;//輸出3 cout << p[3] << endl;//輸出一個很大的數 }
五、指針運算
1. int a[5] = {1,2,3,4,5};
int *p = a; //p指向數組的第一個元素
int *p1 = p+4; //p1指向數組的第五個元素(而不是第二個元素),指針地址的增加長度取決於這個指針所指向的變量的類型
2. 指針和下標
int a[5] = {1,2,3,4,5};
int *p = a; //這時p使用下標的方式與數組名相同
int *p1 = &a[2] //這時p1還可以使用負數當下標,如p1[-1],表示a[1]
3. sizeof的區別
#include <iostream> #include <stdio.h> using namespace std; void fun(int arr[]) { cout << sizeof(arr) << endl; } int main() { int a[5] = { 1, 2, 3, 4, 5 }; cout << sizeof(a) << endl;//輸出20 int *p = a; cout << sizeof(p) << endl;//輸出4 fun(a);//輸出4 return 0; }
這里要說明的是,sizeof數組的時候,大小為整個數組的大小,sizeof指針的時候,大小為4,當數組作為函數的實參傳入形參后,其實是作為指針傳入的。
4. 數組的地址
#include<iostream> using namespace std; void main() { short tell[10];//聲明一個20個字節的數組 cout << tell << endl;//第一個元素的地址 cout << &tell << endl;//整個數組的地址 cout << tell + 1 << endl;//相比上面增加了2個字節 cout << &tell + 1 << endl;//相比上面增加了20個字節 }
從數字上來說,這兩個地址相同;但從概念上來說,tell(&tell[0])是一個2字節內存塊的地址,而&tell是一個20字節內存塊的地址。
六、指針數組和數組指針
1.指針數組,顧名思義指的是元素是指針的數組。
int *ptrs[10]; //聲明了一個數組,含有10個整形指針
2.數組指針,指向數組的指針
int (*ptr)[10] = &arrar; //ptr是一個指向數組的指針
int (*p)[5]; //聲明了一個數組指針