1. 程式人生 > >C++中int *p[4]和 int (*q)[4]的區別 (指標陣列和陣列指標)

C++中int *p[4]和 int (*q)[4]的區別 (指標陣列和陣列指標)

int *p[4];  //定義一個指標陣列,該陣列中每個元素是一個指標,每個指標指向哪裡就需要程式中後續再定義了。
int (*p)[4]; //定義一個數組指標,該指標指向含4個元素的一維陣列(陣列中每個元素是int型)。

區分int *p[n]; 和int (*p)[n]; 就要看運算子的優先順序了。
int *p[n]; 中,運算子[ ]優先順序高,先與p結合成為一個數組,再由int*說明這是一個整型指標陣列。
int (*p)[n]; 中( )優先順序高,首先說明p是一個指標,指向一個整型的一維陣列。

這倆兄弟長得實在太像,以至於經常讓人混淆。然而細心領會和甄別就會發現它們大有不同。

前者是指標陣列,後者是指向陣列的指標。更詳細地說。

前: 指標陣列;是一個元素全為指標的陣列.
後: 陣列指標;可以直接理解是指標,只是這個指標型別不是int也不是char而是 int [4]型別的陣列.(可以結合函式指標一併看看......)

int*p[4]------p是一個指標陣列,每一個指向一個int型的
int (*q)[4]---------q是一個指標,指向int[4]的陣列。

兩者在定義的時候如下:

int k;
cin>>k;

char *p[2];
p[0]=new char[k];
p[1]=new char[k];

char (*b)[2];
b=new char[k][2];


這樣空說是不是依舊小白?舉個例子

  1. #include <iostream> 
  2. usingnamespace std;   
  3. int main()   
  4. {   
  5.     int *p[4]; //p是一個指標陣列,每一個指標都指向一個int型資料 
  6.     int a=1,b=2,c=3,d=4;  
  7.     int i;  
  8.     p[0]=&a;  
  9.     p[1]=&b;  
  10.     p[2]=&c;  
  11.     p[3]=&d;  
  12.     int (*q)[4];//q是一個指標,指向int[4]陣列 
  13.     //q[0]=&a;//error   q是指向int[4]陣列的指標,而&a是一個int型指標,所以不能賦值 
  14.     int aa[4]={5,6,7,8};  
  15.     q=&aa;  
  16.     cout << "p的值:" << p << endl; //注意,p不等於p[0] 
  17.     cout << "p[0]的值:" << p[0] << "  a的地址:" << &a << endl;  
  18.     cout << "p[0]地址儲存的值:" << *(p[0]) << "  a的值:" << a << endl;  
  19.     cout << "p[1]地址儲存的值:" << *(p[1]) << "  b的值:" << b << endl;  
  20.     cout << "p[2]地址儲存的值:" << *(p[2]) << "  c的值:" << c << endl;  
  21.     cout << "p[3]地址儲存的值:" << *(p[3]) << "  d的值:" << d << endl;  
  22.     cout << "q的值:" << q << "  aa的地址:" << &aa << endl;  
  23.     cout << "q[i]的地址:" << endl;  
  24.     for(i = 0; i < 4; ++i)  
  25.     cout << q[i] << endl;//q[0] 與 q的值相同 
  26.     cout << "q指向int[4]的所有值:" << endl;  
  27.     for(i = 0; i < 4; i++)  
  28.     cout << q[0][i] << ' ';  
  29.     cout << endl;  
  30.     //cout<<*(p[0])<<*(q[0])<<endl;
  31.     return 0;   
  32. }   



 執行結果:

p的值:0x22ff60
p[0]的值:0x22ff5c  a的地址:0x22ff5c
p[0]地址儲存的值:1  a的值:1
p[1]地址儲存的值:2  b的值:2
p[2]地址儲存的值:3  c的值:3
p[3]地址儲存的值:4  d的值:4
q的值:0x22ff30  aa的地址:0x22ff30
q[i]的地址:
0x22ff30
0x22ff40
0x22ff50
0x22ff60
q指向int[4]的所有值:
5 6 7 8

以下為網友的解釋,可能闡述得更為細緻。

定義涉及兩個運算子:“*”(間接引用)、“[]”(下標),“[]”的優先級別大於“*”的優先級別。

  首先看int *p[4],“[]”的優先級別高,所以它首先是個大小為4的陣列,即p[4];剩下的“int *”作為補充說明,即說明該陣列的每一個元素為指向一個整型型別的指標。int *p[4]的儲存結構如下:(儲存方格橫向排列或豎向排列沒區別,只要按記憶體地址順序排列就行,此處只是為畫圖方便)



    再看int (*q)[4]。它首先是個指標,即*q,剩下的“int [4]”作為補充說明,即說明指標q指向一個長度為4的陣列。int (*q)[4]的儲存結構如下:

請看以下定義:

int a[2][4]={{2,5,6,8},{22,55,66,88}};

int c[4]={5,8,9,4};

int d[3]={23,12,443};

int *p[4],(*q)[4];

q=a;

*p=c;

*(p+1)=d;

則int *p[4]和int (*q)[4]的儲存資料為:

驗證:

#include <stdio.h>

int main(void)

{

    int a[2][4]={{2,5,6,8},{22,55,66,88}};

    int c[4]={5,8,9,4};

    int d[3]={23,12,443};

    int *p[4],(*q)[4];

    q=a;

    *p=c;

    *(p+1)=d;

    int i,j;

    for(i=0;i<2;i++)

        for(j=0;j<4;j++)

       {

           if((i==1)&&(j==3)) break;

           printf("*(*(p+%d)+%d)=%d\n",i,j,*(*(p+i)+j));

       }

    puts("===============");

    for(i=0;i<2;i++)

       for(j=0;j<4;j++)

           printf("*(*(q+%d)+%d)=%d\n",i,j,*(*(q+i)+j));

   return 0;

}

輸出結果為:

*(*(p+0)+0)=5

*(*(p+0)+1)=8

*(*(p+0)+2)=9

*(*(p+0)+3)=4

*(*(p+1)+0)=23

*(*(p+1)+1)=12

*(*(p+1)+2)=443

===============

*(*(q+0)+0)=2

*(*(q+0)+1)=5

*(*(q+0)+2)=6

*(*(q+0)+3)=8

*(*(q+1)+0)=22

*(*(q+1)+1)=55

*(*(q+1)+2)=66

*(*(q+1)+3)=88

相關推薦

C++ 拷貝建構函式與賦值函式的區別很嚴謹全面)

這裡我們用類String 來介紹這兩個函式: 拷貝建構函式是一種特殊建構函式,具有單個形參,該形參(常用const修飾)是對該類型別的引用。當定義一個新物件並用一個同類型的物件對它進行初始化時,將顯式使用拷貝建構函式。為啥形參必須是對該型別的引用呢?試

UNION UNION ALL 的區別合併表檢視)

Union用法及說明: Union是使用者合併多個select結果集的操作符,需要注意的是:select語句需要有相同的列數,類似的資料型別,且列的順序相同,另外,UNION 結果集中的列名總是等於

左值右值的區別以a++++a為例)

左值(lvalue)和右值(rvalue)最先來源於編譯。在C語言中表示位於賦值運算子兩側的兩個值,左邊的就叫左值,右邊的就叫右值。 定義: 左值指的是如果一個表示式可以引用到某一個物件,並且這個物件是一塊記憶體空間且可以被檢查和儲存,那麼這個表示式就可以作為一個左值。 右值指的是引用了一個儲存在某個記憶

C#如何向資料庫一個Int欄位新增空值?

 例如員工表:         欄位名   資料型別         姓名           nvarchar     性別           int         其中“性別”是允許為空的,當新員工在註冊自己資訊時沒有在textBox這些控制元件中填這項的時候,如何往

C#的方法傳參與switch、if結構4

判斷 1.2 菱形 條件表達式 執行 代碼 輸出 分類 簡易 一、方法傳參的2種方式    1、按值傳遞       傳遞的是值的副本,值會更改但未保留,值最終並未更改     2、按引用傳遞(形參用ref關鍵字修飾)【P86頁】 傳遞的是地址,值會更改且保留,值最終更改

C#Post請求的兩種方式發送參數鏈Body的

連接 png ets return div 參數 try 發現 create POST請求 有兩種方式 一種是組裝key=value這種參數對的方式 一種是直接把一個字符串發送過去 作為body的方式 我們在postman中可以看到 sfdsafd sdfsdfds

C++heap棧(stack)的區別面試被問到的題目)

說起會了解這個東西,還是比較尷尬的,在學校裡面老師一般不會講解C++的堆和棧,大多數人瞭解的堆和棧是資料結構裡面的概念,而這裡一般面試官想問的是C++的記憶體分割槽管理方式。 首先說明,在C++中,記憶體分為5個區:堆、佔、自由儲存區、全域性/靜態儲存區、常量儲存區 棧:

C++換行符‘\n’控制符‘endl’的區別coutprintf區別

1.顯示字串時,在字串中包含換行符,而不是在末尾加上endl,可以減少輸入量 2.如果生成一個空行,則兩種方法的輸入量相同,但對大多數人而言輸入endl更為方便 3.顯示引號括起來的字串通常使用換行符

C#自定義控制元件隱藏基類成員屬性、方法事件)的方法

       編寫自定義控制元件時,總是繼承C#中提供的Control類,而Control類是C#中所有窗體控制元件的基類,裡面定義了大量的屬性、方法和事件,而很多基類成員在自定義控制元件中可能不需要,因為編寫者會希望在自定義控制元件中隱藏這些成員,避免使用者呼叫這些成員。

c++棧的的區別stack vs heap

 堆和棧的區別一、預備知識—程式的記憶體分配一個由c/C++編譯的程式佔用的記憶體分為以下幾個部分1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2、堆區(heap) — 一般由程式設計師分配釋放, 

C# ,ListView的自定義顯示,可用於顯示不同的顏色字型等

VS2010下的ListView控制元件,想用它來顯示不同的顏色單元格,在網上找了listView1.Items[i].UseItemStyleForSubItems = false;的方法,但是不知道為何不起作用, 所以又搜尋了OwnDraw的方法,本來以為很複雜,但後來

C++類內成員的定義,宣告總結靜態非靜態成員)

近學習到C++ primer中關於類中靜態變數的部分,有一道課後題非常有意思。 題目是關於靜態變數在類中的初始化。 class example{ public: //static double rate=6.5; static const int size

hibernate懶加載急加載的區別,get方法load方的區別

() session 執行 語句 style 開啟 異常 方式 速度 懶加載是hibernate中的關聯關系對象的默認方式,懶加載也會先去查詢對象然後獲取對象的id, 當正真要對數據進行使用時才會正真寫sql語句。 懶加載的有效加載期是在session打開的時候,所以在我們

轉:VMwareCentOS配置靜態IP進行網絡訪問NAT方式橋接模式)

name nat模式 定義 終端 star static state alt 相關 傳送門:http://blog.csdn.net/zhangatle/article/details/77417310 其實這個博主的博客最是適合新手學習,踩過的坑讓我再踩一踩,印象深刻

jqueryappend、prepend, beforeafter方法的區別一)

mod serve com oos 兄弟節點 sha pos 插入 5% 原文:http://blog.csdn.net/woosido123/article/details/64439490 在 jquery中append() 與 prepend()是在元素內插

資料結構演算法題/將陣列元素奇數排在前面偶數在後面前面奇數後面的偶數分別有序)

一個無序整數陣列,對它排序,使其前半部分都為奇數有序,後半部分為偶數有序。 (1)方案1 O(n^2) 基本想法:利用插入排序演算法,對奇偶子序列分別插入排序。用兩個變數把整個陣列分割為三個部分,第一個部分為奇數有序子序列,第二部分為偶數有序子序列,第三部分為未排序子序列。使用兩個變數進行分

資料結構演算法題/將陣列元素奇數排在前面偶數在後面前面奇數後面的偶數不需要有序)

  處理策略是定義兩個指標pHead,pTail並令其初始指向陣列頭節點和尾節點。pHead從前往後找應該放在尾部的偶數節點,pTail從後往前找應該放在頭部的奇數節點,若pHead位於pTail之前則交換二者內容,否則結束處理過程。 處理流程如下圖所示。從圖中可以看出時間複

C++遍歷資料夾下所有的wav檔案支援windowsLinux)

直接上程式碼: #include <iostream> #include <string> #include <vector> #include <fstream> #include <string.h> #includ

java的URLConnectionHttpURLConnection有什麼區別因為我自己搜到別人寫的區別看下來都沒有什麼區別

  今天看了一下公司同事的程式碼,如下 1 URLConnection connection = openConnection(localURL); 2 HttpURLConnection httpURLConnection = (HttpURLConnection)c

ajax post 請求 get 請求的區別二)

get 請求 1、傳遞資料方式: 資料直接在post 的 url 中傳遞,直接拼接在 url ? 後面,多個數據用 & 符號拼接 xhr.open('get ‘, 2.get.php?username = Tom & age = 30&’)