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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C/C++和指针】深度解析---指针与数组 【精华】

發布時間:2023/12/18 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C/C++和指针】深度解析---指针与数组 【精华】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一,引例子

二維數組可以使用指向數組的指針代替,而指針數組才可以用指向指針的指針代替。

[html] view plaincopy
  • #include<iostream>??
  • using?namespace?std;??
  • ??
  • void?main()??
  • {??
  • ?????char?*a[]={"Hello","the","World"};?//指針數組??
  • ??
  • ?????char?**pa=a;?//指向指針的指針??
  • ??
  • ?????pa++;???
  • ??
  • ?????cout<<*pa;??
  • }??
  • ?

    類型確定的數組,元素的類型和元素的個數是確定的;數組退化為對應的指針,元素的類型保持一致;

    所謂的二維數組只是數組的數組,因此二維數組不能退化為二級指針,而只能退化為指向一維數組的指針

    例子:

    #include <iostream.h>?
    void main()

    {?

    ??? int a[2][3];??? //二維數組

    ??? int **p=a;????? //二維數組不能退化為指向指針的指針

    }?

    請問為什么是錯誤的??(請不要說數組名是一個指針這個我知道,我想知道為什么不能用二級指針指向二維數組)

    ??

    解析:首先數組和指針的概念你沒分清楚,數組的本質你沒搞清楚。這是導致問題出現的根源。

    ????? int x[5]; 這個定義里面,我們說定義了一個數組x,此數組有5個數組元素,元素的類型為int類型。

    ????? 首先要問的是,x到底為什么東西?x是數組名,x代表了數組第一個元素的首地址。沒錯,x確實是數組的名字,x的值也確實是第一個數組元素的地址值。

    ????? 注意這里我們說x代表的值與數組第一個元素的地址值相等,但類型不一樣

    ????? 那么數組x的類型到底是什么呢? 有人說就是int * 類型。有如下語句可以做證:

    ???????????????????????? int *p=x; //這句話是正確的。

    ????? 數組x的類型真是int *嗎?我們說不是,因為下面的語句是不正確的:

    ???????????????????????? int a=10; x=&a; // int *類型的變量時可以接受值的。

    ????? 所以x不是int*? 那么我們可以猜測x的類型是不是 int *const呢?也就是說x是一個地址值不可以改變的指針。這句話貌似有點正確。但是請大家看看下面的例子:

    ???????????????????????? int x[5]={0}; int a=sizeof(x); // a的值到底是多少?

    ?????實際上這里a的值是5*4=20 這里是整個數組占用的字節數。 我們不是說x的類型是int * const類型的嗎,也就是x應該是一個指針類型,應該是4個字節的啊,為什么sizeof出來時整個數組占用的字節數呢?例如? sizeof(int *)這個的結果就是4。所以有此可以看出,x的類型并不是int*,也不是int * const。? i

    ?????? int x[5];中的x到底是什么呢,我們說x是數組,此數組有5個元素,并且每個元素都是int類型。 我們有一個識別數據類型的規律例如:?

    ?????? int x; //x類型為int

    ?????? int *x;//x類型為int *

    ?????? int **x;//x類型為int **

    ?????? int (*x)[10];//x類型為int(*)[10]實際上是指向數組的指針

    ?????? int (*x)(int ,int);//x的類型為int(*)(int,int)實際上是指向函數的指針?

    ??? 由此可以看出,一個符號是什么數據類型,我們只要在其定義的表達式中去掉符號本身剩下的就是符號的類型了。

    ??? 照此推斷,int x[5];中x的類型應該是 int [5]這個類型,可以看出此類型并不是int *類型。?

    ??? 那么int x[5];中的x可以這樣賦值: int *p=x; 為什么呢?只能說這里面將x的類型隱式轉換為了int *類型。所以這里是可以賦值的,因為進行了類型轉換。

    ?? 再請看下面的例子:?

    ???????? void function(int x[5])

    ?????????{??

    ???????????? cout<<sizeof(x)<<endl; //這里輸出4

    ????????? }? 為什么會輸出4,而不是4*5呢,可以看出上面的函數形參實際上類型是int*,并不是數組類型,

    ?????? 所以我們在定義函數的時候,下面的都是與上面等價的:?

    ?????? void function(int x[])//元素個數是多少可以省略 {?? cout<<sizeof(x)<<endl; //這里輸出4 }

    ???????void function(int *x) //直接寫成指針變量也沒錯 {?? cout<<sizeof(x)<<endl; //這里輸出4 }?

    ??

    ?? 那么我們看一個類似的問題:

    ????????? int x[5]; int **p=&x; //為什么會報錯? 因為類型不匹配。?

    ??????? ?p的類型是int **,而&x的類型卻不是int **。 &x的類型實際上是int(*)[5],因為取的是x的地址,也就是說這個地址是數組的地址,并不是指向數組第一個元素的指針的指針(也就是二維指針),而是整個數組的地址。

    ???????? 所以我們可以改成下面的: int (*p)[5]=&x;//這就對了。

    ?

    二,指向數組的指針,和指向數組元素的指針有什么不同??

    ??? 例如int *p;我們要注意的是,p的類型是int*,p占用的空間4個字節,p指向的數據類型是int。P指向的數據類型占用4個字節。

    ??? 所以對于指針變量,我們要明白指針變量本身是占用空間的,本身是有類型的,其次指針變量所指向的空間是有類型的,是有空間的。?

    ????那么int *p; char *p1; 對于指針變量來說p,p1里面都放的是地址值,說白了就是一個數值,他們都占用4個字節的空間,但是他們的類型不一樣,p里面的地址指向的是int類型的數據,p1指向的是char類型的數據,這主要體現在p++與p1++中他們在內存中移動的字節數是不一樣的,我們假設int占4個字節,char占1個字節。那么對于p來說向前移動了4個字節,p1來說移動了一個字節。這就是他們的類型不同,導致運算過程中的不同。 int x[5];

    ???? int (*p3)[5]; 此時p3指向數組x,那么p3++實際上向前移動了多少呢,可以算出移動了4*5個字節。也就是p3指向的是一個數組,是整個數組,所以p3移動的時候是將一個數組當做一個整體來看待的。所以向前移動了一整個數組的距離。? 再看你的問題之前,我們來看一個類似的問題:?

    ?????int a[2][3]; int? **p=&a; //這里我用&a來賦值行不行呢。是不行的。? 這里為什么是錯誤的,原因就是因為&a的類型不是int**類型。所以類型不兼容,導致不能賦值,同時這兩種類型是不可以相互轉換的。那么&a到底是一個什么樣的類型呢。 我們說&a取的是整個數組的地址,那么&a自然就是指向整個數組的指針了。

    ???? int (*p)[2][3]=&a; 此時這樣賦值才是正確的。如果我們要用a直接賦值,那該定義一個什么樣的變量來接受它呢,首先要明白,數組名代表的地址類型是指向數組的第一個元素的指針,

    ??? 例如:? int a[10]; int *p=a; 實際上這里與 int *p=&a[0];是等價的。因為指向a[0]的指針類型就是int*類型。? 那么&a的是取數組的地址,其類型是指向數組的指針,而不是指向數組第一個元素的指針,整個是要區別的,他們的類型就不一樣。 int(*p)[10]=&a;?

    ???? 所以說這里的a和&a絕對不是同一個東西,雖然本質上他們的地址值是一樣的,但是他們的類型不一樣。就決定他們代表不同的意義。?

    ??? ?那么剛剛說了對于下面的例子:

    ??????????? int a[2][3];

    ??????????? int (*p)[2][3]=&a;

    ???? 我們可以定義這樣的一個變量p來接受&a的值。?

    ???? 那么我們要接受a應該定義一個什么樣的變量呢。a[2][3]是一個二維數組,可以看成是這樣的a是一個數組,具有兩個元素,分別為a[0],a[1]其中這兩個元素的值a[0],a[1]他們的值又是一個具有3個元素的數組。此時我們可以將a[0],a[1]看成是數組名,那么a[0][0]就是數組a[0]的第0個元素了。對應關系如下: a[0] ---->? a[0][0],a[0][1],a[0][2] a[1] ---->? a[1][0],a[1][1],a[1][2]? 那么a到底是什么,其實a數組有兩個元素,a[0],a[1],那么a的值自然就是其第一個元素的地址了,也就是&a[0]了。這是一個什么類型?? 我們知道如果我們將a[0]看成一個整體,例如我們用A來代替a[0],那么A[0],A[1]就相當于a[0][0],a[0][1] 。 此時A就是一個int類型的數組,&A,的類型實際上就是 int(*p)[3]這個類型。? 所以下面的代碼也是正確的:???

    ????? int a[2][3];? int(*p)[3]=a; //所以對于你的問題,可以這樣子


    總結

    以上是生活随笔為你收集整理的【C/C++和指针】深度解析---指针与数组 【精华】的全部內容,希望文章能夠幫你解決所遇到的問題。

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