<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      指針詳解2

      運行環境以Dev-C++、Visual Studio 2022、MacOS的命令行和Xcode為主

      1.數組名的實質

      • 數組名就是數組首元素的地址,但是有兩個意外

        • sizeof(數組名)sizeof中單獨存放數組名,此處的數組名表示整個數組,計算的是整個數組的大小,單位為字節

        • &數組名,此處的數組名表示整個數組,取出的是整個數組的地址,該地址與數組首元素的地址有區別,具體參考下文代碼

        // 代碼1:分別打印數組名和數組首元素的地址,結果一樣,數組名就是數組第一個元素的地址
        #include <stdio.h>
        
        int main(int argc, const char * argv[]) {
            int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            printf("&arr[0] = %p\n", &arr[0]);
            printf("arr     = %p\n", arr);
            
            return 0;
        }
        

        image

        // 代碼2:由于sizeof中單獨放數組名,表示的是整個數組,計算數組占用內存的大小,共 40B
        #include <stdio.h>
        
        int main(int argc, const char * argv[]) {
            int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            printf("%zd\n", sizeof(arr));
            
            return 0;
        }
        

        image

        // 代碼3:數組首元素的地址、數組名和數組的地址在數值上一樣
        #include <stdio.h>
        
        int main(int argc, const char * argv[]) {
            int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            printf("&arr[0] = %p\n", &arr[0]);
            printf("arr     = %p\n", arr);
            printf("&arr    = %p\n", &arr);
        
            return 0;
        }
        

        image

        // 代碼4:數組首元素的地址、數組名和數組的地址分別加 1 的區別
        #include <stdio.h>
        int main(int argc, const char * argv[]) {
            int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            
            // 兩者相差4個字節,&arr[0] 是首元素的地址,加 1 就是跳過一個元素
            printf("    &arr[0] = %p\n", &arr[0]);
            printf("&arr[0] + 1 = %p\n", &arr[0] + 1);
            
            // 兩者相差4個字節,arr 也是數組首元素的地址,加 1 就是跳過一個元素
            printf("        arr = %p\n", arr);
            printf("    arr + 1 = %p\n", arr + 1);
        
            // 兩者相差40個字節,因為 &arr 是數組的地址,加 1 操作是跳過整個數組
            // 十進制40的十六進制為28,16fdf280 + 00000028 = 16fdf2a8
            printf("       &arr = %p\n", &arr);
            printf("   &arr + 1 = %p\n", &arr + 1);
            
            return 0;
        }
        

        image

      2.利用指針訪問數組

      • 在積累了前面的知識后,結合數組的特點,可以很方便地使用指針訪問數組

      • 編譯器在處理數組元素訪問的時候,通過首元素的地址加偏移量求得元素的地址,然后解引用來訪問

      #include <stdio.h>
      
      int main(int argc, const char * argv[]) {
          int arr[10] = {0};
          int sz = sizeof(arr) / sizeof(arr[0]);
          
          int i = 0;
          int *p = &arr[0];
          // int *p = arr;    // 這里的數組名就是數組首元素的地址,兩者等價
      
          // 輸入
          for (i = 0; i < sz; i++) {
              scanf("%d", p + i);
              // scanf("%d", arr + i);
          }
          
          // 輸出
          for (i = 0; i < sz; i++) {
              printf("%d ", *(p + i));
              // printf("%d", p[i]);    // p[i] 本質上等價于 *(p + i)。類似地,arr[i] 等價于 *(arr + i)
              // printf("%d", *(arr + i));
              // printf("%d", arr[i]);
              // printf("%d", i[arr]);    // [] 作為運算符,i 和 arr 是它兩邊的運算數,類比加法運算,[] 滿足交換律
          }
          printf("\n");
          
          return 0;
      }
      

      3.一維數組傳參的實質

      • 3.1 數組名作為函數參數

        • 之前的代碼通常在自定義函數外部求數組元素的個數。如果將數組傳給一個自定義函數,理論上在函數內部也能求出數組的元素個數。參考以下代碼
        #include <stdio.h>
        
        void test1(int arr[]) {
            int sz1 = sizeof(arr) / sizeof(arr[0]);
            printf("sz1 = %zd\n", sz1);
        }
        
        void test2(int arr[10]) {
            int sz2 = sizeof(arr) / sizeof(arr[0]);
            printf("sz2 = %zd\n", sz2);
        }
        
        int main(int argc, const char * argv[]) {
            int arr[10] = {0};
            int sz = sizeof(arr) / sizeof(arr[0]);
            
            printf("sz = %zd\n", sz);
            test1(arr);
            test2(arr);
            
            return 0;
        }
        
        //
        

        image

        • 觀察運行結果發現在函數內部并沒有獲得正確的數組元素個數

        • 數組名是數組首元素的地址,那么在數組傳參時傳遞的是數組名,數組傳參在本質上傳遞的是數組首元素的地址

        • 理論上,函數形參的部分應使用指針變量來接收首元素的地址,函數內部的sizeof(arr)計算的是一個地址的大小(單位是字節)而不是數組的大小(單位是字節)

        • 正是因為函數的參數部分本質是指針,所以在函數內部無法求得數組元素的個數

      • 3.2 指針作為函數參數

        • 一維數組傳參,形參的部分可以寫成數組的形式,也可以寫成指針的形式
        #include <stdio.h>
        
        void test1(int arr[]) {
            printf("%zd\n", sizeof(arr));
        }
        
        void test2(int *arr) {
            printf("%zd\n", sizeof(arr));
        }
        
        int main(int argc, const char * argv[]) {
              int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
              test1(arr);
              test2(arr);
              
              return 0;
        }
        

        image

      4.冒泡排序

      • 核心思想:升序排序時,兩兩相鄰的元素進行比較,如果前面的比后面的大,那就交換這兩個數。詳細的過程可參考排序專題

      • 代碼實現

      // 方法1
      #include <stdio.h>
      
      void bubble_sort(int arr[], int sz) {
          int i = 0;
       
          for (i = 0; i < sz - 1; i++) {
              int j = 0;
              for (j = 0; j < sz - i - 1; j++) {
                  if (arr[j] > arr[j + 1]) {
                      int temp = arr[j];
                      arr[j] = arr[j + 1];
                      arr[j + 1] = temp;
                  }
              }
          }
      }
      
      int main(int argc, const char * argv[]) {
          int arr[] = {3, 1, 7, 5, 8, 9, 0, 2, 4, 6};
          int sz = sizeof(arr) / sizeof(arr[0]);
      
          bubble_sort(arr, sz);
          int i = 0;
          for (i = 0; i < sz; i++) {
              printf("%d ", arr[i]);
          }
          return 0;
      }
      
      // 方法2
      #include <stdio.h>
      
      int count = 0;    // 計數變量,統計相鄰兩個數比較的次數
      void input(int *arr, int sz) {
          int i = 0;
          for (i = 0; i < sz; i++) {
              scanf("%d", arr + i);
          }
      }
      
      void print_arr(int *arr, int sz) {
          int i = 0;
          for (i = 0; i < sz; i++) {
              printf("%d ", *(arr + i));
          }
          printf("\n");
      }
      
      void bubble_sort(int *arr, int sz) {
          int i = 0;
          int j = 0;
          int temp = 0;
      
          for (i = 0; i < sz - 1; i++) {
              int flag = 1;    // 假設這一趟數已經有序了
              for (j = 0; j < sz - i - 1; j++) {
                  count++;
                  if (arr[j] > arr[j + 1]) {
                      flag = 0;  // 發生交換就說明此時數組無序
                      temp = arr[j];
                      arr[j] = arr[j + 1];
                      arr[j + 1] = temp;
                  }
              }
              if (flag == 1) {    // 一趟過后沒有交換說明已經有序,后續無需在排列
                  break;
              }
          }
      }
      
      int main(int argc, const char * argv[]) {
          int arr[10] = {0};
          int sz = sizeof(arr) / sizeof(arr[0]);
      
          input(arr, sz);
          bubble_sort(arr, sz);
          print_arr(arr, sz);
          printf("count = %d\n", count);
          return 0;
      }
      

      5.二級指針

      • 5.1 定義和指向原理

        • C語言中的普通變量都有地址。類似地,指針變量是一種特殊的變量,它也應當有地址

        • 指針變量的地址存放在二級指針中

        #include <stdio.h>
        
        int main(int argc, const char * argv[]) {
            int a = 10;
            int *pa = &a;
            int **ppa = &pa;
        
            printf("&a   = %p\n", &a);
            printf("&pa  = %p\n", &pa);
            printf("&ppa = %p\n", &ppa);
        
            return 0;
        }
        

        image

        image

      • 5.2 二級指針的運算

        • *ppa通過解引用ppa中的地址,找到了pa*ppa訪問的其實就是pa
        int a = 20;
        *ppa = &a;    // 等價于 pa = &a;
        
        • **ppa先通過*ppa找到pa,然后對pa進行解引用操作,即*pa找到了a
        **ppa = 30;
        // 等價于 *pa = 30;
        // 等價于 a = 30;
        

      6.指針數組

      • 6.1 定義和指向原理

        • 整型數組是存放整型數據的數組,字符數組是存放字符型數據的數組

        • 類似地,指針數組應該是存放指針類型數據的數組

        image

      • 6.2 指針數組模擬二維數組

        • parr[i]是訪問parr數組的元素,parr[i]找到的數組元素指向了整型一維數組,parr[i][j]就是整型一維數組中的元素
        • 代碼模擬出二維數組的效果,實際上并非完全是二維數組,因為每一行不是連續的
        #include <stdio.h>
        
        int main(int argc, const char * argv[]) {
            int arr1[] = {1, 2, 3, 4, 5};
            int arr2[] = {2, 3, 4, 5, 6};
            int arr3[] = {3, 4, 5, 6, 7};
            
            // 數組名是數組首元素的地址,類型是int *的,就可以存放在parr數組中
            int *parr[] = {arr1, arr2, arr3};
            int i = 0, j = 0;
            for (i = 0; i < 3; i++) {
                for (j = 0; j < 5; j++) {
                    printf("%d ", parr[i][j]);
                    // printf("%d ", *(*(parr + i) + j));
                }
                printf("\n");
            }
            
            return 0;
        }
        

        image

      posted @ 2025-08-14 10:13  pycoder_666  閱讀(14)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 午夜成人性爽爽免费视频| 蜜臀av日韩精品一区二区| 欧美精品在线观看视频| 中文字幕日韩精品人妻| 亚洲日韩VA无码中文字幕| 一本一本久久a久久综合精品| 国产日韩av二区三区| 日韩精品一区二区亚洲专区| 四虎国产精品久久免费精品 | 国产又色又爽又黄的网站免费| 柳江县| 亚洲AV无码不卡在线播放| 99在线国内在线视频22| 老司机午夜精品视频资源| 国产精品啪| 洱源县| 国产精品成人网址在线观看| 又黄又爽又色的少妇毛片| 麻豆精品一区二区综合av| 欧美日韩在线第一页免费观看| 午夜家庭影院| 久久综合激情网| 国产玖玖视频| 国产成人a在线观看视频免费| 欧美性xxxxx极品| 日韩国产精品中文字幕| 老熟妇老熟女老女人天堂| 国产成人久久精品一区二区| 欧美熟妇性XXXX欧美熟人多毛| 欧美性猛交xxxx乱大交极品| 国产国产午夜福利视频| 国产无遮挡又黄又大又爽| 国产成人精品久久性色av| 熟妇人妻无码中文字幕老熟妇| 日本三级香港三级人妇99| 久久er99热精品一区二区| 国产成人女人在线观看| 在线精品视频一区二区| 在线视频中文字幕二区| 女人腿张开让男人桶爽| 日韩av综合免费在线|