天天看點

c語言 —— 指針與數組

  數組和指針的關系比較密切,這裡再總結一下這個知識點。由問題引入話題:

    1. char a[] 和char *a等價嗎?

    不是。      數組定義char a[6]請求預留6個字元的位置,并用名稱a表示。也即:有一個用a辨別的位置,可以放入6個字元。     而指針聲明char *p :請求一個位置放置一個指針,用名稱p表示。這個指針可以指向任何字元或任何連續的字元,或者哪裡都不指。通過圖像來說明:     若有下面語句:
char a[] = "hello";
    char *p = "world";
           
 它們在記憶體中的表現形式如下(當然,箭頭是我們人為添加的):
c語言 —— 指針與數組
 注意:數組不能被指派。但是指針可以。在使用指針過程中一定要清楚指針本身和指針指向的内容,尤其是指針運算。指針運算總是居于所指對象的大小的。      2. 如何了解“指針和數組等價”?          在C語言中知識指針算數和數組下标運算等價,指針和數組是不同的。那麼,在作為函數形參的數組和指針為何可以互換呢?其實,給函數傳入數組隻是一種便利的做法。在這個過程中,數組會馬上退化為指針,事實上,數組從來沒有被傳入函數。 例如:
void fun(int a[])
{...}
           

在編譯器裡都被當做指針來處理。因為在傳入數組的時候,函數接受到的正是指針。     注意:這種轉換僅限于函數形參的聲明,在别的地方并不适用。

3.  如何動态配置設定數組?      (1)動态配置設定一維數組:用指向malloc配置設定的記憶體的指針來高效模拟數組。          int *dArray = (int *)malloc(10 * sizeof(int));           (2)動态配置設定二維數組:       方法一:配置設定一個指針數組,然後把每個指針初始化為動态配置設定的“行”。

int **arr1 = (int *)malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++)
{
        arr1[i] = (int *)malloc(cols * sizeof(int));
 }
           
記憶體布局:
c語言 —— 指針與數組
    方法二:讓數組的内容連續。但在配置設定行的時候要使用一點指針運算:         
int **arr2 = malloc(rows * sizeof(int *));
 	arr2[0] = malloc(rows * cols * sizeof(int));
  	for (i = 1; i<rows; i++)
        {
               arr2[i] = arr2[0] + i * cols;
        }
           
           記憶體布局:
c語言 —— 指針與數組

    方法三:用一個動态配置設定的一維數組來模拟二維數組:           int *arr3 = malloc(rows * cols * sizeof(int));           但是在使用是偶必須手工計算下标,如:arr3[i * cols + j]通路第i、j個元素。           方法四:使用數組指針:           int (*arr4)[COLS] = malloc(rows * sizeof(*arr4));

          或,

          int (*arr5)[ROWS][COLS] = malloc(sizeof(*arr5));

          這種方法的文法比較可怕,并且運作時最多隻能确定一維。 4. 如何釋放前面動态配置設定的數組?     對于arr1和arr2:     

for (i=0; i<rows; i++)
        free((void *)arr1[i]);
    free((void *)arr1);
           

    注意:釋放的原則:每個malloc()都必須有一個對應的free();

5. 如何給函數傳遞一個二維數組?     數組退化為指針的規則不能遞歸應用。數組的數組(二維數組)退化為數組的指針,而不是指針的指針。     若想函數傳遞二維數組:

 int arr[ROWS][COLS];  fun(arr);
    那麼,函數的聲明也必須比對:          
void fun(int a[][COLS])
    {...}
           
    或者         
void fun(itn (*pArr)[COLS])  /* pArr is a pointer to an array */
    { ...  }
           
c