數組就是一個能夠一次性定義多個相同類型的變量,並能夠放到一個連續的內存中去。
數組
只有在定義的時候順便賦值才叫初始化。測試
int a = 1024 ; int arr[5] = {1,2,3,4,5}; // 徹底初始化 int arr1[] = {1,2,3,4,5,6,7,8,9,10} // 正確,定義的時候並無肯定大小, 初始化後才肯定的大小 arr2 = {1,2,3,4,5,}// 不可行, 數組只有在初始化的時候能夠統一賦值 int arr2 [5] = {1,2,3,4,5,6,7}; // 語法上能夠,可是邏輯上不容許, 涉嫌越界 int arr3[50] = {1,2,3,4,5}; // 不徹底初始化 , 沒有初始化部分自動填充0
數組名在不一樣的環境中表示的意思不同3d
a.在定義的時候 int a[10];
b.在sizeof(a)語句中;
c.在取地址&a時。指針
a.除了上面三種狀況之外,其餘全部狀況都表示首元素的首地址。code
存儲方式:一片連續的內存空間,按照具體的數據類型進行分割
數組下標:以數組首地址爲起點的偏移量
blog
int arr1[5] = {1, 2, 3, 4, 5}; printf("arr1[1]:%p\n", &arr1[1]); printf("arr1[2]:%p\n", &arr1[2]); printf("arr1[3]:%p\n", &arr1[3]); printf("arr1[4]:%p\n", &arr1[4]); printf("arr1[5]:%p\n", &arr1[5]); //輸出結果,可得相鄰的數組元素地址相差4,與數組的類型所佔的大小相等 arr1[1]:0x7fffeec8c1f4 arr1[2]:0x7fffeec8c1f8 arr1[3]:0x7fffeec8c1fc arr1[4]:0x7fffeec8c200 arr1[5]:0x7fffeec8c204
注意:
1.一位數組中arr表示首元素的起始地址,&arr表示整個數組的起始地址,雖然值是同樣的可是表明的意義卻不同;
2.arr+1與arr[1],arr+2與arr[2].....arr+n與arr[n]是相同的意思;
3.a[1]與1[a],a[2]與2[a]....a[n]與n[a]是相同的意思。內存
專門用來存放字符數據的數組,成爲字符數組。字符串
char s1 [5] = {'a' ,'b' , 'c' ,'d' , 'e'}; // 中存放的是字符數據 char s2 [6] = {'a' ,'b' , 'c' ,'d' , 'e' , '\0'}; // 中存放的是字符串數據 char s3 [6] = {"hello"} ; // s3中存放的是字符串 , 注意數組大小必須能完整存儲下整個字符串包括結束符 char s4 [6] = "hello"; // 使用雙引號的時候大括號能夠省略 s4[1] = 'E' ; printf("s1:%s\n" , s1 ); // 注意該數組爲字符數組,不該該使用%s來訪問輸出,他會涉嫌越界,%s須要遇到'\0'才願意停下來 printf("s2:%s\n" , s2 ); // 常規操做 printf("s2:%s\n" , s2+2 ); s2+2 加了兩個 char 的大小 , printf("s3:%s\n" , s3 ); printf("s4:%s\n" , s4 );
二維數組能夠理解爲:數組內容爲數組。
it
/* 測試代碼 */ int arr[3][3] = {{1, 11, 111} , {2, 22, 222} , {3, 33, 333}}; printf("&arr: %p\n", &arr); printf("&arr+1:%p\n", &arr+1); printf("arr[0][0]:%p\n", *arr+0); printf("arr[0][1]:%p\n", *arr+1); printf("arr[0][2]:%p\n", *arr+2); printf("arr[0][0]:%p\n", *(arr+0)); printf("arr[1][0]:%p\n", *(arr+1)); printf("arr[2][0]:%p\n", *(arr+2)); printf("arr[0][1]:%d\n", *(*(arr+0)+0)); printf("arr[0][2]:%d\n", *(*(arr+0)+1)); printf("arr[0][3]:%d\n", *(*(arr+0)+2));
注意:
1.若是將代碼中的&arr,arr+0,(arr+0)傳遞給相應的指針,其所表明的意義也將傳遞給指針。變量
長度爲零的數組
int a[0];
其主要的功能是放在結構體的末尾,做爲結構的最後一個成員,能夠做爲結構體內存擴容入口,數組是C語言中惟一一個容許越界訪問的東西。
越界訪問:只是訪問原本不屬於某個變量的內存(數組本來申請大區域)不必定就是非法訪問
越界是訪問的內存只要都屬於我當前程序所用的內存就不屬於非法訪問。
非法訪問:訪問的內存地址不屬於你這個程序的內存。
概念: 在定義數組以前可能他的長度是未知的, 定義語句執行後他的長度是固定的。
重點: 在定於語句中數組的長度是一個變量,定義結束以後即便長度的變量有所變化也不會影響數組的長度了。
說白了就是數組的長度是一個變量;
int i = 90 ; 。。。 。。 int buf[ i ] ; int a = 10 ; int arr[ a ] = {0} ; // error: variable-sized object may not be initialized
注意:
變長數組不能夠初始化。
用來存放指針的數組
int * arr[5] ; int a , b ,c ,d, e ; arr[0] = &a ; arr[1] = &b ; char * str [3] = {"Hello" , "GZ2075" , "eVEN"}; for (int i = 0; i < 3; i++) { printf("str[%d]:%s\n" , i , str[i]); }
常量:不能夠被修改的量
存儲在常量區的字符串數據稱爲字符串常量,其實是一個匿名數組
printf("%d\n" , sizeof("GZ2075")); // "GZ2075"表示的整個數組 printf("%p\n" , &"GZ2075"); // "GZ2075"表示的整個數組 printf("%c\n" ,"GZ2075"[1]); // 使用與數組相似的方法來訪問某一位元素 char * p1 = "GZ2075" ; // p1指向 "GZ2075" 匿名數組的首元素的首地址 char * p2 = "GZ2075" + 1; // p2 指向 "GZ2075" 匿名數組的第二個元素 ‘Z’
注意: 字符串常量都是以'\0'結尾的,不可忽略它的存在。