標籤:兩種方法 記憶體 字串 標識符 改變 概念 sizeof 變數定義 防止
一、數組的概念1.1 數組
數組是一組具有相同資料類型的有序變數的集合,在記憶體中表現為一塊連續的儲存地區。
1.2 數組的定義
數組定義:在普通變數定義後加[常量]
- 類型標識符 數組名[常量運算式]
- 錯誤:[變數]:error C2057: expected constant expression
1.3 數組的初始化
數組初始化:用{}給數組賦予初值
- 初始化元素的個數可以不全。(用1個到總數個常量和變數)
- 未初始化全,把其餘的歸零。
- 數組清零:char array[10] = {0};
- 不指定個數 int array[] = {2,23,5,6};
1.4 求數組空間
- sizeof(array)也可以說是:sizeof(元素)*元素的個數。
- 求數組個數:int i = sizeof(array)/sizeof(int);
- 實際在開發中,不直接寫數組個數,而是用求數組個數。以利於總數發生變化時,遍曆數組時不需要修改每一處。
- 除法在編譯時間運算是常數,不會減低運行效率
1.5 數組元素的調用
1.6 冒泡排序
- 比較相鄰的元素。如果前者比後者大,就交換這兩個元素。
- 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。
- 這樣迴圈一輪下來,最終會將數組中最大數值的元素推到數組尾部。
- 針對所有的元素重複以上的步驟,除了最後一個。
- 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
1.7 數組做參數
數組作為參數時,有如下特徵:
- 可以不指定長度,也可以隨便指定任何長度。
- 數組做參數時性質已經變了,本質上是傳遞了數組的地址(指標)給形參。
- 數組的空間特徵已經消失了,無法通過形式參數擷取來源數組的元素個數。
- 無論實參數組有多少個元素,使用sizeof擷取形式參數的大小結果一定是4。(因為任何一個指標變數佔用的大小都是4個位元組)
二、字串數組2.1 定義
字串數組是一種特殊的數組。特徵是:
- 必須是char類型的數組。
- 在數組定義的有效空間內,必須含有一個數值是‘\0’的位元組。
- ‘\0‘作為字串的結束標誌。
2.2 字串數組初始化2.2.1 指定元素個數的數組
1 char str1[10] = {‘a‘,‘b‘};2 char str2[10] = "aab";//不可超過9個有效字元2.2.2 不指定個數的字串數組,根據初始化個數包括‘\0‘
1 char str3[] = "abcdef"; //申請7個位元組的數組空間2 char str4[] = {‘x’, ‘y‘, ‘z‘,108}; // 申請是4個位元組的數組空間2.2.3 數組長度和字串長度
- strlen函數:是用來計算字串中有效字元的長度。(不包括結尾符)
- sizeof:求字串數組的元素個數,sizeof得出的結果至少比strlen大1以上。
- strlen函數:計算方法是從數組頭迴圈到結尾符‘\0‘結束,得出的字串有效字元長度總是小於sizeof得出的的數值。
- sizeof:得出的數組長度與數組內每個元素儲存的數值無關;而strlen函數返回的字串長度,與結尾符‘\0‘在數組中的位置有關。
三、指標3.1 指標的概念
- 指標的定義:一個記憶體變數或陣列變數記憶體位址就是指標。
- 在32位作業系統中,任何記憶體變數的地址都是一個0-4G之間的數字。0x00000000---0xffffffff
3.2 指標變數
- 指標變數 :存放指標(記憶體位址)的變數稱為指標變數。
- 任何類型的指標變數的空間大小都是4個位元組。
- 指標變數記錄的記憶體位址,也稱為它指向的地址。
3.3 指標變數的定義
- 變數類型 * 指標變數名稱[=地址]例如:int i=0;int *p=&i;
- 同時定義2個以上的指標變數時,每個變數前面都要加*
- int *p1,p2;//p2是int類型。
- int p1,*p2;//p2才是int*類型。
3.4 指標變數的賦值
- 指標變數不可以直接使用整數變數或常量賦值;
- int *p = 200; //錯誤:不能使用整數常量賦值
- int i=100,*p1 = i; //錯誤:p1是指標變數,i是整型變數
- 各種不同種類的指標變數之間不能直接賦值。 (除非強制轉換語句)
- int i = 10;
- int *p=&i; //正確:類型相同
- char*pc =p; //錯誤:類型不同
- 使用*符號:對指向的記憶體位址上的內容進行讀或寫操作。
- 指標變數指向了某個記憶體位址,就可以通過*符號或者[]符號,來讀寫所指向的記憶體位址上的資料。
- 讀寫操作的所覆蓋的記憶體空間的長度,要依據這個指標變數的來源類型的長度來決定。(對記憶體空間賦值或者取值)
- 指標的降級:使用了*符號或[]符號都能是指標變數降級為它的來源類型。
- int *p = &i; //定義指標變數時使用的*符號
- int j = *p; //調用指標變數操作指向記憶體位址上的內容使用*符號
- p[0]=10; //就如同陣列變數定義時使用的是[],調用元素時也使用[]符號
- 以上的*p和p[0]都降級為了int類型
- 使用*和[]符號取值或賦值的效果:
1 int i = 0x12345678, *p=&i;2 char*pc =(char*)p; //強制轉化3 printf("*p=0x%x,*pc=0x%x\n",*p,*pc);4 printf("*p=%d,*pc=%d\n",p[0],pc[0]);5 pc[0]=-1;6 pc[1] =-3;7 *p=100;
儘管所有類型的指標變數佔用的記憶體空間都是4個位元組,但是不同類型的指標變數到指向的記憶體位址上取值和賦值效果是大不相同的。
這就是為什麼同樣是4個位元組的變數,當指標變數類型不同時不能相互賦值的原
- 指標加減的加減運算:
- 指標加減1(++ --): 位移指標的1個來源類型的尺寸(sizeof)。
- 指標加減n(+= -=):p += n; //物理上:位移4*n個位元組,邏輯上:位移n個int的空間
- 指標法和下標法的對比:指標變數仍然可以按照數組的取值方式,例如:int* p;
- p[0]等價於*p
- p[n]等價於*(p+n)
- 兩種方法都會降級為來源類型,例如:p[1]和*p都是int類型
- 其他指標運算:
- 兩個指標加減:
- int *p1=&i,*p2=a;
- p1+p2; //錯誤:cannot add two pointers
- p1-p2; //正確:(只能相同類型指標相減)
- 物理上:p1-p2的結果是6而不是24,是sizeof(int)的整數倍
- 邏輯上:兩個指標相距6個int的空間
- 兩個指標變數或常量比較:== != < > <= >=
- 指標變數做形式參數時,經常用於改變主調函數的實參數值:(使用取值符號*或者下標[]來遠程操作實參)
C語言(八)---數組與指標