天天看點

10W+字C語言硬核總結(九),值得閱讀收藏!

2.2.3 指針數組(元素為指針)

2.2.3.1 棧區指針數組

//數組做函數函數,退化為指針
void array_sort(char** arr,int len){
 for (int i = 0; i < len; i++){
  for (int j = len - 1; j > i; j --){
   //比較兩個字元串
   if (strcmp(arr[j-1],arr[j]) > 0){
    char* temp = arr[j - 1];
    arr[j - 1] = arr[j];
    arr[j] = temp;
   }
  }
 }
}
//列印數組
void array_print(char** arr,int len){
 for (int i = 0; i < len;i++){
  printf("%s\n",arr[i]);
 }
 printf("----------------------\n");
}
void test(){
 //主調函數配置設定記憶體
 //指針數組
 char* p[] = { "bbb", "aaa", "ccc", "eee", "ddd"};
 //char** p = { "aaa", "bbb", "ccc", "ddd", "eee" }; //錯誤
 int len = sizeof(p) / sizeof(char*);
 //列印數組
 array_print(p, len);
 //對字元串進行排序
 array_sort(p, len);
 //列印數組
 array_print(p, len);
}      

2.2.3.2 堆區指針數組

//配置設定記憶體
char** allocate_memory(int n){
 if (n < 0 ){
  return NULL;
 }
 char** temp = (char**)malloc(sizeof(char*) * n);
 if (temp == NULL){
  return NULL;
 }
 //分别給每一個指針malloc配置設定記憶體
 for (int i = 0; i < n; i ++){
  temp[i] = malloc(sizeof(char)* 30);
  sprintf(temp[i], "%2d_hello world!", i + 1);
 }
 return temp;
}
//列印數組
void array_print(char** arr,int len){
 for (int i = 0; i < len;i++){
  printf("%s\n",arr[i]);
 }
 printf("----------------------\n");
}
//釋放記憶體
void free_memory(char** buf,int len){
 if (buf == NULL){
  return;
 }
 for (int i = 0; i < len; i ++){
  free(buf[i]);
  buf[i] = NULL;
 }
 free(buf);
}
void test(){
 int n = 10;
 char** p = allocate_memory(n);
 //列印數組
 array_print(p, n);
 //釋放記憶體
 free_memory(p, n);
}      

2.2.4二維數組三種參數形式

2.2.4.1 二維數組的線性存儲特性

void PrintArray(int* arr, int len){
 for (int i = 0; i < len; i++){
  printf("%d ", arr[i]);
 }
 printf("\n");
}
//二維數組的線性存儲
void test(){
 int arr[][3] = {
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
 };
 int arr2[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 int len = sizeof(arr2) / sizeof(int);
 //如何證明二維數組是線性的?
 //通過将數組首位址指針轉成Int*類型,那麼步長就變成了4,就可以周遊整個數組
 int* p = (int*)arr;
 for (int i = 0; i < len; i++){
  printf("%d ", p[i]);
 }
 printf("\n");
 PrintArray((int*)arr, len);
 PrintArray((int*)arr2, len);
}      

2.2.4.2 二維數組的3種形式參數

//二維數組的第一種形式
void PrintArray01(int arr[3][3]){
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j++){
   printf("arr[%d][%d]:%d\n", i, j, arr[i][j]);
  }
 }
}
//二維數組的第二種形式
void PrintArray02(int arr[][3]){
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j++){
   printf("arr[%d][%d]:%d\n", i, j, arr[i][j]);
  }
 }
}
//二維數組的第二種形式
void PrintArray03(int(*arr)[3]){
 for (int i = 0; i < 3; i++){
  for (int j = 0; j < 3; j++){
   printf("arr[%d][%d]:%d\n", i, j, arr[i][j]);
  }
 }
}
void test(){
 int arr[][3] = { 
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
 };
 PrintArray01(arr);
 PrintArray02(arr);
 PrintArray03(arr);
}      

2.3總結

2.3.1 程式設計提示

源代碼的可讀性幾乎總是比程式的運作時效率更為重要

隻要有可能,函數的指針形參都應該聲明為 const。

在多元數組的初始值清單中使用完整的多層花括号提高可讀性

2.3.2 内容總結

在絕大多數表達式中,數組名的值是指向數組第 1 個元素的指針。這個規則隻有兩個例外,sizeof 和對數組名&。

指針和數組并不相等。當我們聲明一個數組的時候,同時也配置設定了記憶體。但是聲明指針的時候,隻配置設定容納指針本身的空間。

當數組名作為函數參數時,實際傳遞給函數的是一個指向數組第 1 個元素的指針。

我們不單可以建立指向普通變量的指針,也可建立指向數組的指針。

繼續閱讀