最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++數(shù)組和數(shù)組名問題(指針、解引用)

 更新時間:2021年09月18日 12:06:49   作者:IE貓  
這篇文章主要介紹了詳解C++數(shù)組和數(shù)組名問題(指針、解引用),指針的實質(zhì)就是個變量,它跟普通變量沒有任何本質(zhì)區(qū)別,指針本身是一個對象,同時指針無需在定義的時候賦值,具體內(nèi)容詳情跟隨小編一起看看吧

一、指針

 1.1 指針變量和普通變量的區(qū)別

指針:指針的實質(zhì)就是個變量,它跟普通變量沒有任何本質(zhì)區(qū)別。指針完整的應(yīng)該叫指針變量,簡稱為指針。 是指向的意思。指針本身是一個對象,同時指針無需在定義的時候賦值。

1.2 為什么需要指針

指針的出現(xiàn)是為了實現(xiàn)間接訪問。在匯編中都有間接訪問,其實就是CPU的尋址方式中的間接上。

間接訪問(CPU的間接尋 址)是CPU設(shè)計時決定的,這個決定了匯編語言必須能夠?qū)崿F(xiàn)問接尋又決定了匯編之上的C語言也必須實現(xiàn)簡介尋址。

1.3 指針使用三部曲

三部曲:定義指針變量、關(guān)聯(lián)指針變量、解引用

(1)當我們int *p定義一個指針變量p時,因為p是局部變量,所以也道循C語言局部變量的一般規(guī)律(定義局部變量并且未初始化,則值是隨機的),所以此時p變量中存儲的是一個隨機的數(shù)字。

(2)此時如果我們解引用p,則相當于我們訪問了這個隨機數(shù)字為地址的內(nèi)存空間。那這個空間到底能不能訪問不知道(也許行也許不行),所以如果直接定義指針變量未綁定有效地址就去解引用幾平必死無疑。

(3)定義一個指針變量,不經(jīng)綁定有效地址就去解引用,就好象拿一個上了鏜的槍隨意轉(zhuǎn)了幾圈然后開了槍。

(4)指針綁定的意義就在于讓指針指向一個可以訪問、應(yīng)該訪問的地方(就好象拿著槍瞄準且標的過程一樣),指針的解引用是為了間接訪問目標變量(就好象開槍是為了打中目標一樣)

int val = 43;
int * p = &val;   // &在右值為取值符
cout << *p << endl;

//輸出
43

二、整形、浮點型數(shù)組

 前言

  • 在很多用到數(shù)組名字的地方,編譯器都會自動地將其替換為一個指向該數(shù)組首元素的指針。
  • 所以,在大多數(shù)表達式中,使用數(shù)組名其實是在使用一個指向該數(shù)組首元素的指針。

2.1 數(shù)組名其實是特殊的指針

int main()
{
	int a[] = { 0,1,2,3,4 };
	printf("%x\n", a);
	printf("%x\n", &a);
	printf("%x\n", &a[0]);
}

在這里插入圖片描述

  • 從局部變量表可以看出,數(shù)組a和指針p的構(gòu)成是很相似的。它們實際存的都是一個地址,都會指向一個對象(或多個對象的第一個對象)。所以說數(shù)組名其實是種特殊的指針。
  • 為什么說是特殊呢?

一維數(shù)組

 int a[] = { 0,1,2,3,4 };
    int * p1 = a;
    int *p = &a[0];
    //指針p是 int * 的,而首元素是有地址的,所以取址,是允許的
    
	//int * p1 = &a;    //錯誤
	//理解:int (*p1)[5] = &a;  //正確
	/*
	但它倆自身又有不同:
	指針 p1 本身是一個對象,在內(nèi)存中是為其分配了空間的;
	數(shù)組名 a 在內(nèi)存空間中沒有分配到空間(這將導致&a操作的效果可能和預想的不大一樣)。
	可以理解為a指向一個含有5個整數(shù)的數(shù)組的指針,故 &a的類型為int(*)[5],不能用來初始化int */	

整理:

指針 類型
a int *
&a int (*) [5]

二維數(shù)組

int ia[3][4];
       int (*p)[4] = ia;      //ia 的類型就是 int(*)[4]
       int (*p)[3][4] = &ia;  //&ia的類型就是 int(*)[3][4]

整理:

指針 類型iaint (*) [4]&1aint (*) [3] [4]

2.2 理解復雜的數(shù)組的聲明

上述提到數(shù)組名是指向一個數(shù)組的指針,因此解釋一下一些復雜的數(shù)組聲明。加深理解

 int * ptr[10];             //ptr是含有10個  整形指針  的數(shù)組
   int & ref[10]  = /* ? */   //錯誤,不存在引用的數(shù)組
   int (*parray) [5] = &a;   //parray指向一個含有5個整數(shù)的數(shù)組
   /*
   同時也是上述數(shù)組名的解釋
   *parray意味著parray是一個指針;
   右邊是[5]表明是指向大小為10的數(shù)組;
   左邊int表明數(shù)組中元素為int.
   */
   
   int (&array)[5] = a;      //array引用一個含有5個整數(shù)的數(shù)組

   int * (&array) [10]  = ptrs;
   //array是數(shù)組的引用, 該數(shù)組是含有10個指針的數(shù)組

2.3 數(shù)組名a、數(shù)組名取地址&a、數(shù)組首元素地址&a[0]、指向數(shù)組首元素的指針*p

int main()
{
	int a[] = { 0,1,2,3,4 };
	printf("%x\n", a);
	printf("%x\n", &a);
	printf("%x\n", &a[0]);

	int *p = &a[0];
	
	decltype(a) t;
	decltype(&a) tt;

	cout << p << endl;
	printf("%x,%x\n", a + 1, p + 1);
	printf("%x\n", &a + 1);

	cout << sizeof(a) << " " << sizeof(&a) << endl;
}

輸出

在這里插入圖片描述

  • a既然是種特殊的指針,那么其打印時就會是存的地址。
  • &a的類型是int(*)[5](讀法從小括號里往外,首先是指針,然后是大小為5的數(shù)組,然后數(shù)組元素類型是int),從局部變量中看到其類型也可寫成int[5] *:即指向大小為5的int數(shù)組的指針。由于數(shù)組名沒有內(nèi)存分配空間
  • &a[0]就是取一個int對象的地址,這個int對象是數(shù)組首元素。綜上所述,就造成了a &a &a[0]三者打印出來的地址是一樣的。
  • p,指向數(shù)組首元素的指針。
  • a + 1,p + 1都是按照元素大小的字節(jié)數(shù)(4字節(jié)),增加4。
  • &a + 1,前面說了 &a的類型是指向大小為5的int數(shù)組的指針,大小為5的int數(shù)組所占字節(jié)數(shù)為20,所以&a + 1就應(yīng)該增加20。
  • sizeof(a)為20,因為數(shù)組總的字節(jié)大小為20。
  • sizeof(&a)為4,因為&a是一種指針,指針在32位系統(tǒng)中占4字節(jié)。

2.4 對數(shù)組名以及取值符&的理解

數(shù)組中每個元素都是對象,即占有特定類型的內(nèi)存空間。(對象,占有一塊數(shù)組類型的內(nèi)存空間。因為對象是指一塊能存儲數(shù)據(jù)并且具有某種類型的內(nèi)存空間。)

數(shù)組名可以轉(zhuǎn)化為這個數(shù)組對象的首個元素的地址。

這里我們不去討論一維數(shù)組,直接從二維說起。所謂二維數(shù)組也是數(shù)組,只不過它的元素也是一個數(shù)組。

首先我們寫一個二維數(shù)組留作使用

#include<iostream>
using namespace std;
int a[][10]={
    {1,2,3,4,5,5,6,7,8,8},
    {10,12,32,42,51,15,16,71,121,18}
};

簡單說明一下數(shù)組:數(shù)組a 是包含2個元素的數(shù)組,每個元素是一個包含10個 int 的數(shù)組。
既然說到數(shù)組名是其首個對象的地址那么來驗證一下,測試數(shù)組名,以及對數(shù)組名求地址:

void test01(){
    cout << (long long)a << endl;         // 140273290059808
    cout << (long long)(a+1) << endl;     // 140273290059848
    // 相差40個字節(jié)
   }

(用long long 型一眼就能看出是40個字節(jié))

aa + 1 正好相差40個字節(jié),說明:

(1)數(shù)組名a 是(首元素{1,2,3,4,5,5,6,7,8,8})這一整行對象的地址,即首元素地址;

(2)所以在a+1偏移了一個元素大小——40字節(jié)。

void test01(){
    cout << (long long)&a << endl;        // 140273290059808
    cout << (long long)(&a+1) << endl;    // 140273290059888
    // 相差80個字節(jié)
   }

&a&a + 1 正好相差80個字節(jié),說明:

(1)取址符取得是整個對象的地址,&a 是對二維數(shù)組求址,針對的是整個對象;

(2) &a+1 偏移一位就變成了整個二維數(shù)組的尾地址,c++中的尾地址是對象所在地址的下一位。&a+1 正好比 a 多了 80 個字節(jié)。

在上面也提到數(shù)組名會自動轉(zhuǎn)換成一個特殊指針(兩個表格當中的總結(jié)),接下來將理解這個指針到底是什么?

從指針解引用方面理解:

void test03(){
    cout << *a << endl;     // 0x7f051ce02020
    //為了驗證,我們偏移一下
    cout << *(a + 1) << endl; // 0x7f051ce02048
    // 正好相差40個字節(jié)
}

*a 把數(shù)組名解引用之后是首元素(因為數(shù)組名是指向首元素的特殊指針),而首元素也是一個有10個元素的數(shù)組,現(xiàn)在 *a 是代表這個對象,輸出它就是此數(shù)組的首元素——1 的地址.。

cout << *(*a) << endl; //1    **a 即可	

第二層解掉:*(*a) 自然就是第一個 int 型的元素。

cout << *a[0] << endl; //   1

因為指針指向數(shù)組對象時,可以用下標訪問下一個位置,又 a 是指針指向了數(shù)組,下一個偏移為 0,即 * a = * (a + 0)

// cout << (a[0])[0] << endl; 
 cout << a[0][0] << endl;//   1

基于上述, *a 也就是a[0],也會自動轉(zhuǎn)化為指向自己的首個對象(10個元素的第一個元素的位置)的指針。所以 a[0] 可以用下標訪問數(shù)組對象(10個元素)內(nèi)其他元素:a[0][0] == 1

我們多搞幾個案例:

 // 要是訪問當前行的下一個元素呢?將這個首地址
    cout << *(*a + 1) << endl;// 2 即 *((*a) + 1) 
    // 請注意這里的指針是 (*a),
    cout << (*a)[1] << endl; //    2
    // 同理(*a)相當于*(a + 0) 即a[0] 
    cout << a[0][1] << endl; //2
    
    // 如果訪問下一行呢?
    cout << **(a+1) << endl;
    cout << *a[1] << endl; 
    cout << a[1][0] << endl; // *(a[1] + 0)
    
    // 第二行第二個元素呢?
    cout << *(*(a+1) +1 ) << endl;
    cout << *(a[1] +1) << endl;
    cout << a[1][1] << endl;

查看數(shù)組名類型理解

cout << typeid(*a).name()<< endl;  // A10_i
cout << typeid(&a[0]).name()<< endl; // PA10_i

A10_i :是由10個 int 組成數(shù)組
PA10_i :是一個指針類型, 指向一個數(shù)組對象,這個數(shù)組對象有10個int型的對象。編譯器會識別為int(*)[10]

cout << typeid(a).name()<< endl; // A2_A10_i
cout << typeid(&a).name()<< endl; // PA2_A10_i	

A2_A10_i:由多維數(shù)組是數(shù)組的數(shù)組。A表示這個是數(shù)組類型,2表示是兩個對象組成的數(shù)組,每個對象(A10_i)是由有10個對象的數(shù)組,這10個對象是int型的。

PA2_A10_i:是一個指針類型, 指向一個數(shù)組對象,這個數(shù)組對象有2個數(shù)組型的對象。編譯器會識別為int(*)[2][10]

三、字符數(shù)組數(shù)組名

c++對待字符數(shù)組名不會輸出其地址,會直接輸出字符

#include <iostream>
using namespace std;
 
int main()
{
	//int a[5]={1,2,34,4,5};   //如果不是char型,cout<<"a="<<a<<endl;
	// 輸出的為int數(shù)組首地址。不會輸出數(shù)組中的值。
	char a[5]="aaaa";         //cout重載了char[],可以輸出整個字符串數(shù)組
	cout<<"a="<<a<<endl;
	return 0;
}

詳細參考這篇博客

到此這篇關(guān)于詳解C++數(shù)組和數(shù)組名問題(指針、解引用)的文章就介紹到這了,更多相關(guān)C++數(shù)組和數(shù)組名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中前綴和數(shù)組(算法)基本介紹

    C++中前綴和數(shù)組(算法)基本介紹

    前綴和(Prefix Sum)是指數(shù)組中某個位置之前的所有元素的和,本文將介紹C++中前綴和數(shù)組(算法)基本概念,感興趣的朋友一起看看吧
    2024-12-12
  • c++中的static修飾符示例詳解

    c++中的static修飾符示例詳解

    在c++中,靜態(tài)成員是屬于整個類而不是某個對象,靜態(tài)成員變量只存儲一份供所有對象共用,下面這篇文章主要給大家介紹了關(guān)于c++中static修飾符的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-10-10
  • C++鏈表節(jié)點的添加和刪除介紹

    C++鏈表節(jié)點的添加和刪除介紹

    大家好,本篇文章主要講的是C++鏈表節(jié)點的添加和刪除介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C++超詳細講解auto與nullptr的使用

    C++超詳細講解auto與nullptr的使用

    C++11提供了nullptr用來取代0或者NULL。在C++11之前,使用NULL為空指針賦初值,但NULL其實就是0,這時會把NULL當成0來用;在C++11中,我們在聲明一個變量或?qū)ο?,指定它的類型時,可以不使用變量本身的類型而使用auto替代
    2022-05-05
  • 用C語言實現(xiàn)通訊錄

    用C語言實現(xiàn)通訊錄

    這篇文章主要為大家詳細介紹了用C語言實現(xiàn)通訊錄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 深入解析C++編程中的靜態(tài)成員函數(shù)

    深入解析C++編程中的靜態(tài)成員函數(shù)

    這篇文章主要介紹了深入解析C++編程中的靜態(tài)成員函數(shù),是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C/C++ break和continue區(qū)別及使用方法

    C/C++ break和continue區(qū)別及使用方法

    這篇文章主要介紹了C/C++ break和continue區(qū)別及使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • C++未定義行為(undefined behavior)

    C++未定義行為(undefined behavior)

    對于未定義行為,C++標準沒有明確規(guī)定編譯器們應(yīng)該怎么做,那么執(zhí)行的結(jié)果就是不可預料的。下面我們來詳細探討下
    2017-02-02
  • C++堆排序算法實例詳解

    C++堆排序算法實例詳解

    這篇文章主要介紹了C++堆排序算法,簡單分析了堆排序算法的原理并結(jié)合實例形式分析了C++實現(xiàn)堆排序的具體操作技巧,需要的朋友可以參考下
    2017-08-08
  • C++實現(xiàn)商店倉庫管理系統(tǒng)

    C++實現(xiàn)商店倉庫管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)商店倉庫管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論

胶南市| 永年县| 屏东市| 海晏县| 沙洋县| 峨眉山市| 西吉县| 濮阳县| 巧家县| 黑山县| 武平县| 崇明县| 舟山市| 麻阳| 鄂尔多斯市| 曲靖市| 南丹县| 金山区| 康马县| 绩溪县| 涿州市| 诸城市| 东城区| 邵东县| 怀集县| 黄浦区| 西林县| 榆树市| 西平县| 江安县| 克山县| 潜山县| 高台县| 新巴尔虎右旗| 平陆县| 安乡县| 罗平县| 山丹县| 家居| 潮安县| 西城区|