指標和陣列對比分析

2021-08-28 04:06:09 字數 3977 閱讀 3991

陣列的本質

-陣列是一段連續的記憶體空間

-陣列的空間大小為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...