C的陣列與指標

2021-07-03 05:34:58 字數 3449 閱讀 9663

陣列

如果陣列中只有部分元素被初始化,則其他未被初始化的元素將會被設為0

c99之後,如果只想初始化陣列中的乙個元素,可以:int array[6] = ; 這樣,其他的元素會被設為0

int days[7] = ;

結果:[0]:31,[1]:29,[2]:0,[3]:0,[4]:31,[5]:30,[6]:31,[7]:0

說明:初始化是從標註出標號的開始,如果乙個元素被初始化多次,則有效的是最後一次初始化

用大括號列出數值對陣列進行賦值只能用於初始化,而不能用於陣列元素賦值

c99和c11都支援變長陣列(vla)。vla有一些限制,例如不能在宣告陣列時進行初始化

指標

不能解引用(dereference)乙個未初始化的指標。因為建立乙個指標變數時,只是分配了儲存這個指標的記憶體,但並沒有分配儲存資料的記憶體(即並未給指標所將要指向的變數分配空間)。所以在使用指標之前,它所指向的變數應該是已經被分配了記憶體的(兩種方法,一是將已經存在的變數的位址賦給指標;二是使用malloc)

例如double *p; *p = 2.1; 這就是乙個錯誤的用法

函式,指標與陣列

指標的值+1時,加的是乙個以byte為單位,所指向的儲存單元的值

函式呼叫陣列的格式(其中array是陣列名):int sum(int* array); 或 int

sum(int array, int n); 還可以不傳入陣列的大小,sizeof(array)可以獲得整個陣列所佔的空間,再除以每個元素的大小(如sizeof(array[0]))即可得到陣列的元素個數

(可以這麼理解,(int *)代表函式的引數是乙個指標,其值應該是指標變數本身的值,是乙個位址,而array恰好是陣列中第乙個變數的位址)

c保證在為陣列分配空間時,指向陣列最後乙個元素後的第乙個位置的指標是合法的

"*"和"++"的優先順序是相同的,並且從右到左應用:*start++ == *(start++)

array[i] == *(array+i),但是array++只有當array是指標變數時才能使用(也就是說,如果array是乙個陣列名,則不能使用array++這種改變array自身值的用法)

只有當兩個指標都指向同乙個陣列時,將兩個指標相減才是合法的

const double* p = rates;  

指向const的指標不能用於改變所指向變數的值,*p的值不能改變, 但可以指向另乙個變數;同時,也可以把const或不是const的資料賦給指向const的指標。只有non-const的資料能被賦給普通指標,也就是說,如果乙個變數是const的,那它不能賦給普通的指標,只能賦給指向const的指標(所以將函式形參變數宣告為const不僅可以保護資料,還使函式可以處理const的變數)

double* const p = rates;

這種情況下指標只能指向rates而不能再指向其他變數,但是*p的值可以被改變

const double* const p = rates;

也可以使用const兩次,表示指標所指向的變數值不能被更改,並且也不能指向其他變數 例:

const int y;

const int* p2 = &y;

int* p1;

p1 = p2; // error in c++,possible warning in c

c中可以將乙個指向const的指標賦給乙個non-const指標,但當用non-const指標修改const變數的行為是無法定義的(c++直接不允許這種賦值)

指標與多維陣列

int zippo[4][2];

因為zippo[0]是陣列第乙個元素,所以zippo的值和&zippo[0]相同;因為zippo[0]是乙個長度為2的int型陣列,所以zippo[0]的值與&zippo[0][0]相同;又因為int和長度為2的int型陣列都從記憶體中的同乙個位置開始,所以zippo和zippo[0]的數值是相等的(zippo == zippo[0],二者本質上是同乙個變數;但zippo+1和zippo[0]+1的結果是不一樣的)

邏輯上,**zippo == *zippo[0] == zippo[0][0],*zippo == zippo[0] == &zippo[0][0]

數值上,zippo == zippo[0] == &zippo[0][0],也就是說&zippo[0] == zippo[0]

宣告乙個指向二維陣列指標的方法:int (* p)[2];  (2是二維陣列中,最低維陣列的大小)

由於""的優先順序比"*"高,所以:int * p[2]  //表示p是乙個長度為2的陣列,陣列的元素是指向int型的指標

例:int ar[3][2]; int **p;

則*p = ar[0];  // 合法

p = ar;      // 不合法 

因為p是乙個指標,指向的是指向int型指標;雖然ar也是乙個指標,但它指向的是指向長度為2的int型陣列的指標。所以,p與ar型別不同,不能互相賦值;但*p和ar[0]都是指向int型的指標,所以可以互相賦值

函式與多維陣列

函式使用二位陣列作為形參的方法:(第二種方法比較好)

1. void func (int (*p)[4], int row);

2. void func (int p[4], int row);  // 第乙個中括號內可以填上數字,但編譯器會無視它

多維陣列:void func(int ar[12][20][30], int row);

變長陣列(vla):

vla必須是自動儲存(atuomatic storage)類,也就是說它們在函式內部或作為函式形參都不能使用static或extern進行宣告,也不能在宣告時進行初始化。vla一旦被建立,大小就不能再改變。

宣告以二維變長陣列作為形參的函式:void func(int row, int col, int ar[row][col]);

因為變長陣列的宣告要使用行、列大小,所以"row"和"col"必須要在"ar"之前宣告

需要注意的一點是,在函式宣告中宣告vla並未實際建立陣列,陣列的名字只是乙個指標。這也意味著所有對陣列的更改都會對原始資料進行更改

復合文字(compound literal):

c99開始支援,可以這樣宣告:(int [2]);   // ""中的數字可以省略

由於沒有名字,所以只能在宣告時使用(例如:int *p; p = (int [2]);),也可以直接傳給函式作為引數例如:

void sum(const int ar, int n);

sum( (int ), 6)

C 指標陣列與陣列指標

說實話,c語言真的很讓人蛋疼,它不像物件導向的語言,我們重心在設計程式上。而使用c語言,你不僅要考慮程式的設計,你還要考慮很多他的使用細節,不然一不小心你怎麼死的都不知道。但是,個人感覺,c語言的魅力是其他任何語言都比不了的!繼續看。陣列指標 範例 typedef int aint5 5 typed...

C 指標陣列與陣列指標

陣列指標 也稱行指標 陣列指標 a pointer to an array,即指向陣列的指標 定義 int p n 優先順序高,首先說明p是乙個指標,指向乙個整型的一維陣列,這個一維陣列的長度是n,也可以說是p的步長。也就是說執行p 1時,p要跨過n個整型資料的長度。如要將二維陣列賦給一指標,應這樣...

指標陣列與陣列指標 C

關於陣列指標 1 對於二維陣列,初始化時,必須指定乙個引數 int a 3 int a 這樣是不允許的,因為要確定指標移動一步要走多遠。對於一位陣列int a 這樣可以。也就數說只有乙個引數位置可以不用設定引數。2 int p 3 必須加上小括號,這代表乙個指向陣列的指標,數字3,代表每一列有三個數...