陣列與指標

2021-10-04 00:19:49 字數 4100 閱讀 2432

c語言中陣列和指標經常會放在一起講,因為對於陣列遍歷的時候,可以通過指標的移動來代替。所以,陣列和指標的關係有時候會讓人很模糊,甚至讓人混淆。本篇博文將試圖說明陣列的特性,指標的特性,以及陣列和指標的聯絡與區別。

float candy[365], char code[12], int states[50], int powers[8] = 。若使用const關鍵字,則陣列為唯讀陣列,不能被改變。

特殊說明:

float rain[5][12]; 二維陣列,也可以說是有12個float的一維陣列。宣告方式就是指定行和列大小。

若flizeny為一維陣列名,flizny == &flizny[0]成立,說明一維陣列名為陣列首元素的位址。並且,filzny為常量,可以進行加減運算,但不能進行自加或自減(變數才能進行)。但陣列名可以賦值給指標變數,從而指標變數可以進行各種運算操作。

#include#define size 4

int main(void)

return 0;

}

上例中在for迴圈中可以使用陣列名進行代替。由於陣列名即為位址,則可以進行諸如類似指標的運算,如*(arr + 1),取陣列第二個元素。

指標變數和陣列都可以作為函式引數型別。但若在函式中進行陣列的遍歷操作,則應指明陣列長度,如int sum(int * ar, int n)或int sum(int ar, int n),否則產生陣列越界的問題。第二種方式更直觀,一看就知道是陣列操作。

在函式宣告時,以下4種方式都可以。

int sum(int *ar, int n);

int sum(int *, int n);

int sum(int ar, int n);

int sum(int , int);

除了指定遍歷長度,也可以使用頭指標和尾指標的方式:int sump(int * start, int * end);在函式內進行start < end; start++,以避免陣列越界的問題。

獲取指標變數指向位址的值,如*ptr。

獲取指標的位址,如&ptr,若用ptt = &ptr,則ptt為指向指標的指標。

指標+/- integer:指標移位操作。

自增自減操作

兩個指標變數做差值,得到位址差值,然後除以位元組數(相應的資料型別)。

關係運算進行比較。

例項:int * pt; *pt = 5(嚴重錯誤)。原因:將pt指向的位址儲存的值賦值為5,但pt未初始化,只有乙個隨機的值,可能指向記憶體中的任意位置,即有可能覆蓋系統重要資料,造成資料覆蓋,甚至程式崩潰。

int sum(const int ar, int n); 在函式體內不允許通過ar改變陣列內的資料,但實際傳入的函式引數不一定為常量陣列。使用const以保護陣列內的資料不發生改變。

常量可以使用#define定義,但const可以定義諸如常量陣列,常量指標,指標常量等。

double rates[5] = ; const double *pd = rates;

陣列為普通陣列,指標為常量指標,不能通過指標來修改指標指向的內容。*pd = 29.89; // not allowed,pd[2] = 222.22; // not allowed,rates[0] = 99.99; // allowed because rates is not const。

無論是否使用指標表示法或陣列表示法,總是不允許使用pt(常量指標)來改變指標指向的資料的值。

常量資料和非常量資料的位址都可以賦值給常量指標。

double rates[5] = ;

const double locked[4] = ;

const double *pd = rates; // valid

pc = locked; // valid

pc = &rates[3];

然而,只有非常量資料的位址可以賦值給一般指標變數。

double rates[5] = ;

const double locked[4] = ;

double *pnc = rates; // valid

pnc = locked; // not valid

pnc = &rates[3]; // valid

很好理解,如果pnc = locked被允許,那麼可以使用pnc修改常量陣列的值。

const有更多可能的用途。 例如,您可以宣告並初始化指標,以使其無法指向其他位置。

double rates[5] = ;

double * const pc = rates; // pc 指向陣列的首元素位址

pc = &rates[2]; // invalid,不允許指向其他位置

*pc = 92.99 // valid,可以通過指標修改指向的值。

double rates[5] = ;

const double * const pc = rates;

pc = &rate[2]; // invalid

*pc = 92.99; // invalid

說明指標一旦初始化,則指標指向的位址不能改變,同時也不能通過指標修改其指向的值。

int zippo[4][2] = , , , };

資料描述

zippo

the address of the first two-int element

zippo+2

the address of the third two-int element

*(zippo+2)

the third element, a two-int array, hence the address of its first element, an int

*(zippo+2) + 1

the address of the second element of the two-int array, also an int

*(*(zippo+2) + 1)

the value of the second int in the third row(zippo[2][1]

如何宣告乙個指向二維陣列的指標呢?int (* pz)[2]; // pz 指向乙個包含2個int型別的陣列,陣列每個元素為2個int型的陣列。

int * pax[2]; // pax是乙個陣列指標,每個指標均為指向int型。

將乙個指標指定給另乙個指標的規則比數字型別的規則更嚴格。例如,可以將int型別值賦值給double型別的變數,但不能將指向int型的指標變數賦值給指向double型別的指標變數。

int n = 5; double x; int * pl = &n; double *pd = &x; x= n(隱式型別轉換); pd = pl(編譯錯誤,不能轉換);

這些限制擴充套件到更複雜的型別,以下例子可以說明。

int * pt; int (*pa)[3]; int ar1[2][3]; int ar2[3][2]; int *p2(指向指標的指標);

pt = &ar1[0][0]; // both pointer-to-int

pt = ar1[0]; // both pointer-to-int

pt = ar1; // not valid, ar1 is a array of three-int

pa = ar1; // both pointer-to-int[3]

pa = ar2; // not valid, pa is a array of three-int ar2 is a array of two-int

p2 = &pt // both pointer-to-int

p2 = ar2; // not valid, p2 is a pointer-to-int *, ar2 is array of two-int

宣告方式

void sum_row(int ar[cols], int rows);

void sum_cols(int [cols], int);

int sum2d(int (*ar)[cols], int rows);

c99新特性,int sum2d(int rows, int cols, int ar[row][cols]);

int sum2d(int, int, int ar[*][*]);

注意,行和列的int型應該放在陣列引數的前面,使用vla可以靈活使用可變行列的陣列。

指標與陣列,指標陣列 陣列指標

int a 10 print n a p,a p a,a print n a 1 p,a 1 p a 1,a 1 a做乙個指標,步長為4,指向乙個元素,a做乙個指標,步長為40,指向乙個維陣列 int b 3 4 print n b p,b p,b p b,b,b print n b 1 p,b 1...

指標陣列與陣列指標

1.指標陣列 指標陣列中每乙個元素都是乙個指標,也既是存放字串的首位址。所以指標陣列適合處理若干個長度不等的字串。定義的一般形式為 型別說明符 指標陣列名 陣列長度 例如 int p 3 宣告乙個陣列,指標陣列p,由3個int型別指標變數元素組成 從運算子的優先順序分析,由於 的優先順序大於 所以p...

指標陣列與陣列指標

呵呵,實在是厭倦了繞口的解釋。指標陣列,故名思義,就是指標的陣列,陣列的元素是指標 陣列指標,同樣,就是直想陣列的指標。簡單舉例說明 int p 2 首先宣告了乙個陣列,陣列的元素是int型的指標。int p 2 宣告了乙個指標,指向了乙個有兩個int元素的陣列。其實這兩種寫法主要是因為運算子的優先...