日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

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

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

文章目錄

    • 1 數(shù)組的訪問方式
      • 1.1 數(shù)組的訪問方式代碼分析
    • 2 數(shù)組和指針不同
    • 3 a 和 &a 的區(qū)別
      • 3.1 指針運(yùn)算的經(jīng)典代碼案例分析
    • 4 數(shù)組作為函數(shù)的參數(shù)
      • 4.1 數(shù)組作為函數(shù)參數(shù)的代碼案例分析
    • 5 總結(jié)

開題問:數(shù)組名可以當(dāng)做常量指針使用。那么指針是否可以當(dāng)做數(shù)組來使用?

1 數(shù)組的訪問方式

  • 以下標(biāo)的形式訪問數(shù)組中的元素:
  • 以指針的形式訪問數(shù)組中的元素
  • 下標(biāo)形式與指針形式的轉(zhuǎn)換:

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

    1.1 數(shù)組的訪問方式代碼分析

    數(shù)組下標(biāo)形式的訪問,我們很常見,下面看一看不是很常見的訪問形式;

    • 代碼 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; }
    • 編譯運(yùn)行結(jié)果為:

    可以看出:

    • 指針確實(shí)可以當(dāng)做數(shù)組來使用
    • 訪問數(shù)組可以通過下標(biāo)形式與指針形式,具體見上圖中的轉(zhuǎn)換公式。

    2 數(shù)組和指針不同

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

    3 a 和 &a 的區(qū)別

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

    3.1 指針運(yùn)算的經(jīng)典代碼案例分析

    • 代碼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; }

    上述代碼編譯運(yùn)行的結(jié)果為:

    5, 33554432, 3

    我們暫且不看p2[0]的結(jié)果。

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

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

    可以看下圖的數(shù)組的內(nèi)存圖(Linux 系統(tǒng)下的小端模型):

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

    4 數(shù)組作為函數(shù)的參數(shù)

    • 數(shù)組作為函數(shù)的參數(shù)的時候,編譯器會將其編譯為對應(yīng)的指針。

    注意:所以,數(shù)組作為函數(shù)參數(shù)的時候,必須將數(shù)組的個數(shù)也作為參數(shù)傳進(jìn)去,否則在函數(shù)內(nèi)無法計(jì)算數(shù)組的大小。

    4.1 數(shù)組作為函數(shù)參數(shù)的代碼案例分析

    • 代碼:29-4.c
    #include <stdio.h>void func1(char a[5]){printf("In func1 sizeof(a)=%d\n",sizeof(a));*a = 'a';a = NULL; //可以作為左值,但是數(shù)組就不行 }void func2(char b[]){printf("In func2 sizeof(b)=%d\n",sizeof(b));*b = 'b';b = NULL; //可以作為左值,但是數(shù)組就不行 } 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; }
    • 編譯運(yùn)行結(jié)果如下:

    分析:

    • 由上述代碼看出當(dāng)數(shù)組作為函數(shù)參數(shù)時,在函數(shù)體內(nèi),它的大小永遠(yuǎn)是4,是因?yàn)樗诰幾g的過程中退化為指針。在32系統(tǒng)中,指針的大小總是4字節(jié)。
    • 并且可以看出,數(shù)組作為函數(shù)參數(shù)的時候,可以作為左值。但是數(shù)組就不可以作為左值,這也充分說明數(shù)組作為函數(shù)參數(shù)的時候,最終退化為指針,指針是可以作為左值的。

    5 總結(jié)

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

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。