陣列的本質
-陣列是一段連續的記憶體空間
-陣列的空間大小為sizeof(array_type)* array_size
-陣列名可看做指向陣列第乙個元素的常量指標
問題思考:
1. a+1的意義是什麼?結果是什麼?
2. 指標運算的意義是什麼?結果是什麼?
**示例:
#include
int main()
; int* p = null;
printf("a = 0x%x\n", (unsigned
int)(a));
printf("a + 1 = 0x%x\n", (unsigned
int)(a + 1));
printf("p = 0x%x\n", (unsigned
int)(p));
printf("p + 1 = 0x%x\n", (unsigned
int)(p + 1));
return
0;}
執行結果:
根據執行結果相信大家已經可以知道上面的問題答案了。
2.指標運算
-指標是一種特殊的變數,與整數的運算規則為:p+n;<==>(unsigned int)p + n * sizeof(*p);
-指標之間只支援減法運算
-參與減法運算的指標型別必須相同 : p1-p2; ==> ((unsigned type)p1 - (unsigned type)p2) / sizeof(type)
-只有當兩個指標指向同乙個陣列中的元素時,指標相減才有意義,其意義為指標所指元素的下標差值
-當兩個指標指向的元素不在同乙個陣列中時,結果未定義
3.指標的比較
-指標也可以進行關係運算(, >=)
-指標關係運算的前提是同時指向同乙個陣列中的元素
-任意兩個指標之間的比較運算(==,!=)無限制
-參與比較運算的指標型別必須相同
**示例:
#include
int main()
; int i = 0;
char s2 = ;
char* p0 = s1;
char* p1 = &s1[3];
char* p2 = s2;
int* p = &i;
printf("%d\n", p0 - p1); //-3
printf("%d\n", p0 + p2); //error
printf("%d\n", p0 - p2);
printf("%d\n", p0 - p); //error
printf("%d\n", p0 * p2); //error
printf("%d\n", p0 / p2); //error
return
0;}
編譯結果:
顯然和分析結果一致將錯誤地方**注釋掉再次譯結果為:
這裡值得注意的是第15行雖然通過了編譯符合了c語言的語法但是這個輸出結果是沒有意義的(兩個指標沒有同時指向乙個陣列中的元素)
4.陣列的訪問方式
-以下標的形式訪問陣列中的元素
int main()
;a[1] = 3
;a[2] = 5
;return0;
}
-以指標的形式訪問陣列中的元素
int main()
; *(a + 1) = 3
; *(a + 2) = 5
;return0;
}
5.下標訪問形式和指標訪問形式之間的差異
-指標以固定增量在陣列中移動時,效率高於下標形式
-指標增量為1且硬體具有硬體增量模型時,效率更高
-下標形式與指標形式的轉換: a[n] <==> *(a+n) <==> *(n+a) <==> n[a]
-現代編譯器的生成**優化率已大大提高,在固定增量時,下標形式的效率已經和指標形式相當;但從可讀性和**維護的角度來看,下標形式更好一些
**示例:
#include
int main()
; int* p = a;
int i = 0;
for(i=0; i<5; i++)
for(i=0; i<5; i++)
printf("\n");
for(i=0; i<5; i++)
for(i=0; i<5; i++)
return
0;}
執行結果:
注意**第23行
6.a和&a的區別
-a為陣列首元素的位址
-&a為整個陣列的位址
-a和&a的區別在於指標1運算
a + 1 ==> (unsigned array_type)a + sizeof(*a)
&a + 1 ==> (unsigned array_type)(&a) + sizeof(*&a) ==> (unsigned array_type)(&a) + sizeof(a)
**示例:
#include
int main()
; int* p1 = (int
*)(&a + 1);
int* p2 = (int
*)((int)a + 1);
int* p3 = (int
*)(a + 1);
printf("p1[-1] = %d\n", p1[-1]);
printf("p2[0] = %d\n", p2[0]);
printf("p3[1] = %d\n", p3[1]);
return
0;}
編譯結果:
這裡值得注意的事p2[0]輸出的值並不是個隨機值,它的值受系統的大小端所影響。
7.陣列引數
-陣列作為引數時,編譯器將其編譯成對應的指標
--void f(int a); <==> void f(int* a);
--void f(int a[5]); <==> void f(int* a);
-一般情況下,當定義的函式中有陣列引數時,需要定義另乙個引數來標示陣列的大小
-函式的陣列引數退化為指標
**示例:
#include
void func1(char a[5])
void func2(char b)
int main()
; func1(array);
printf("array[0] = %c\n", array[0]);
func2(array);
printf("array[0] = %c\n", array[0]);
return
0;}
編譯結果:
值得注意第9行和第18行
指標和陣列的對比
指標和陣列在不少地方可以互換使用,但兩者並不等價。陣列名對應著 而不是指向 一塊記憶體,其位址和大小在生命週期內保持不變,只有陣列的內容可以改變 而指標變數則是乙個變數,它可以存放任意相同資料型別變數的位址值,可以隨時指向其他記憶體塊,所以指標比陣列更加靈活。預防指標錯誤方法 一般指標 1 宣告指標...
io對比分析
1 同步阻塞io 使用者執行緒通過系統呼叫read發起io讀操作,由使用者空間轉到核心空間。核心等到資料報到達後,然後將接收的資料拷貝到使用者空間,完成read操作。使用者執行緒使用同步阻塞io模型的偽 描述為 2同步非阻塞io 使用者執行緒系統系統呼叫read 後直接返回,然後通過不斷輪訓的方式,...
指標陣列和陣列指標分析
int指的是陣列元素的型別,而不是陣列的型別 定義陣列型別 c語言中通過typedef為陣列型別重新命名 typedef type name size 陣列型別 typedef int aint5 5 typedef float afloat10 10 陣列定義 aint5 iarray aint5...