日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【C语言进阶深度学习记录】二十五 指针与数组的本质分析二

發布時間:2023/12/10 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C语言进阶深度学习记录】二十五 指针与数组的本质分析二 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 數組的訪問方式
      • 1.1 數組的訪問方式代碼分析
    • 2 數組和指針不同
    • 3 a 和 &a 的區別
      • 3.1 指針運算的經典代碼案例分析
    • 4 數組作為函數的參數
      • 4.1 數組作為函數參數的代碼案例分析
    • 5 總結

開題問:數組名可以當做常量指針使用。那么指針是否可以當做數組來使用?

1 數組的訪問方式

  • 以下標的形式訪問數組中的元素:
  • 以指針的形式訪問數組中的元素
  • 下標形式與指針形式的轉換:

    對于上面的轉換方式,不要覺得奇怪。這是很正確的轉換。

    1.1 數組的訪問方式代碼分析

    數組下標形式的訪問,我們很常見,下面看一看不是很常見的訪問形式;

    • 代碼 29-1.c
    #include <stdio.h>int main(){int a[5] = {0};int* p = a;int i =0;for(i=0; i<5; i++){p[i] = i+1;}for(i=0; i<5; i++){printf("a[%d] = %d\n", i,*(a+i));}printf("\n");for(i=0; i<5; i++){i[a] = i+10;}for(i=0; i<5; i++){printf("a[%d] = %d\n",i, p[i]);}return 0; }
    • 編譯運行結果為:

    可以看出:

    • 指針確實可以當做數組來使用
    • 訪問數組可以通過下標形式與指針形式,具體見上圖中的轉換公式。

    2 數組和指針不同

    雖然上面說了數組與指針都可以進行訪問數組,它們很相似,但是數組與指針是不同的。在之前的文章中已經有過分析,這里不再贅述,直接看以前的文章:【軟件開發底層知識修煉】二十七 C/C++中的指針與數組是不同的

    3 a 和 &a 的區別

    • a為數組首元素的地址
    • &a 為整個數組的地址
    • a 和 &a 雖然在數值上是相等的。但是它們的意義不同。在指針運算中存在差別:

    3.1 指針運算的經典代碼案例分析

    • 代碼29-3.c
    #include <stdio.h>int main() {int a[5] = {1, 2, 3, 4, 5};int* p1 = (int*)(&a + 1); int* p2 = (int*)((int)a + 1);int* p3 = (int*)(a + 1);printf("%d, %d, %d\n", p1[-1], p2[0], p3[1]);return 0; }

    上述代碼編譯運行的結果為:

    5, 33554432, 3

    我們暫且不看p2[0]的結果。

    • p1[-1] 表示當前指針指向的元素的前一的元素。因為 &a + 1 后是直接跨過可整個數組到了數組最后一個元素的下一個元素的位置。所以 p[-1] = 5
    • p3[1] = 3很好理解。(*(p3 + 1) = 3)

    那么p2[0]到底是怎么回事?

    可以看下圖的數組的內存圖(Linux 系統下的小端模型):

    • 上圖就是數組a的內存模型,在Linux系統的小端模式下。如果這個不懂那就沒法往后看。
    • a是數組首元素的地址,a+1 是第二個元素的地址,這也很好理解
    • (int)a 是將a這個常量指針轉換為int型變量(加入為tmp),那么(int)a + 1 就直接相當于這個tmp變量加1,然后就到了如上圖中的位置。
    • 然后(int*)((int)a + 1) 又將其轉換為指針。所以*p2 = p2[0] = 0x02000000
    • 0x02000000轉換為十進制的值是:33554432 。
    • 到這里,就應該沒有什么疑問了

    4 數組作為函數的參數

    • 數組作為函數的參數的時候,編譯器會將其編譯為對應的指針。

    注意:所以,數組作為函數參數的時候,必須將數組的個數也作為參數傳進去,否則在函數內無法計算數組的大小。

    4.1 數組作為函數參數的代碼案例分析

    • 代碼:29-4.c
    #include <stdio.h>void func1(char a[5]){printf("In func1 sizeof(a)=%d\n",sizeof(a));*a = 'a';a = NULL; //可以作為左值,但是數組就不行 }void func2(char b[]){printf("In func2 sizeof(b)=%d\n",sizeof(b));*b = 'b';b = NULL; //可以作為左值,但是數組就不行 } int main(){char array[10] = {0};func1(array);printf("In func1 array[0]=%c\n", array[0]);func2(array);printf("In func2 array[0]=%c\n", array[0]);return 0; }
    • 編譯運行結果如下:

    分析:

    • 由上述代碼看出當數組作為函數參數時,在函數體內,它的大小永遠是4,是因為它在編譯的過程中退化為指針。在32系統中,指針的大小總是4字節。
    • 并且可以看出,數組作為函數參數的時候,可以作為左值。但是數組就不可以作為左值,這也充分說明數組作為函數參數的時候,最終退化為指針,指針是可以作為左值的。

    5 總結

    • 數組名和指針僅僅是使用方式相同。數組與指針的本質是不同的。
    • 數組名不是整個數組的地址,它是數組首元素的地址
    • 數組作為函數參數的時候,會被編譯器編譯為指針。

    總結

    以上是生活随笔為你收集整理的【C语言进阶深度学习记录】二十五 指针与数组的本质分析二的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。