1. 程式人生 > >二維陣列的詳解 :

二維陣列的詳解 :

二維陣列在概念上是二維的,有行和列,但在記憶體中所有的陣列元素都是連續排列的,它們之間沒有“縫隙”。

要用陣列指標來操作二維陣列。int (*p)[4]=a;  //p每移動一次就是移動了一個一維陣列。

   指標陣列:int *p=a[4];

                     int *p([4]);

以下面的二維陣列 a 為例:

int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };

從概念上理解,a 的分佈像一個矩陣:

0   1   2   3
4   5   6   7
8   9  10  11

但在記憶體中,a 的分佈是一維線性的,整個陣列佔用一塊連續的記憶體:

C語言中的二維陣列是按行排列的,也就是先存放 a[0] 行,再存放 a[1] 行,最後存放 a[2] 行;每行中的 4 個元素也是依次存放。陣列 a 為 int 型別,每個元素佔用 4 個位元組,整個陣列共佔用 4×(3×4) = 48 個位元組。

C語言允許把一個二維陣列分解成多個一維陣列來處理。對於陣列 a,它可以分解成三個一維陣列,即 a[0]、a[1]、a[2]。每一個一維陣列又包含了 4 個元素,例如 a[0] 包含 a[0][0]、a[0][1]、a[0][2]、a[0][3]。

假設陣列 a 中第 0 個元素的地址為 1000,那麼每個一維陣列的首地址如下圖所示:

為了更好的理解指標和二維陣列的關係,我們先來定義一個指向 a 的指標變數 p:

int (*p)[4] = a;

括號中的*表明 p 是一個指標,它指向一個數組,陣列的型別為int [4],這正是 a 所包含的每個一維陣列的型別。

[ ]的優先順序高於*,( )是必須要加的,如果赤裸裸地寫作int *p[4],那麼應該理解為int *(p[4]),p 就成了一個指標陣列,而不是二維陣列指標,這在《C語言指標陣列》中已經講到。

對指標進行加法(減法)運算時,它前進(後退)的步長與它指向的資料型別有關,p 指向的資料型別是int [4],那麼p+1就前進 4×4 = 16 個位元組,p-1就後退 16 個位元組,這正好是陣列 a 所包含的每個一維陣列的長度。也就是說,p+1會使得指標指向二維陣列的下一行,p-1會使得指標指向陣列的上一行。

陣列名 a 在表示式中也會被轉換為和 p 等價的指標!

下面我們就來探索一下如何使用指標 p 來訪問二維陣列中的每個元素。按照上面的定義:

1) p指向陣列 a 的開頭,也即第 0 行;p+1前進一行,指向第 1 行。

2) *(p+1)表示取地址上的資料,也就是整個第 1 行資料。注意是一行資料,是多個數據,不是第 1 行中的第 0 個元素,下面的執行結果有力地證明了這一點:

?

1

2

3

4

5

6

7

#include <stdio.h>

int main(){

int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };

int (*p)[4] = a;

printf("%d\n", sizeof(*(p+1)));

return 0;

}

執行結果:

16

3) *(p+1)+1表示第 1 行第 1 個元素的地址。如何理解呢?

*(p+1)單獨使用時表示的是第 1 行資料,放在表示式中會被轉換為第 1 行資料的首地址,也就是第 1 行第 0 個元素的地址,因為使用整行資料沒有實際的含義,編譯器遇到這種情況都會轉換為指向該行第 0 個元素的指標;就像一維陣列的名字,在定義時或者和 sizeof、& 一起使用時才表示整個陣列,出現在表示式中就會被轉換為指向陣列第 0 個元素的指標。

4) *(*(p+1)+1)表示第 1 行第 1 個元素的值。很明顯,增加一個 * 表示取地址上的資料。

根據上面的結論,可以很容易推出以下的等價關係:

a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)

【例項】使用指標遍歷二維陣列。

?

1

2

3

4

5

6

7

8

9

10

11

12

#include <stdio.h>

int main(){

int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};

int(*p)[4];

int i,j;

p=a;

for(i=0; i<3; i++){

for(j=0; j<4; j++) printf("%2d ",*(*(p+i)+j));

printf("\n");

}

return 0;

}

執行結果:

0   1   2   3
 4   5   6   7
 8   9  10  11

指標陣列和二維陣列指標的區別

指標陣列和二維陣列指標在定義時非常相似,只是括號的位置不同:

int *(p1[5]);  //指標陣列,可以去掉括號直接寫作 int *p1[5];
int (*p2)[5];  //二維陣列指標,不能去掉括號

指標陣列和二維陣列指標有著本質上的區別:指標陣列是一個數組,只是每個元素儲存的都是指標,以上面的 p1 為例,在32位環境下它佔用 4×5 = 20 個位元組的記憶體。二維陣列指標是一個指標,它指向一個二維陣列,以上面的 p2 為例,它佔用 4 個位元組的記憶體。

以上就是C語言 指標和二維陣列的資料整理,後續繼續補充相關知識,謝謝大家對本站的支援!

例二:

    二維陣列就是幾個拆開的一維陣列,a[0]是第一個一維陣列,a[2]是第二個一維陣列。

#include <stdio.h>

#define M 2
#define N 10

int main()
{
    char a[M][N];            
    int i; 
    for(i = 0; i < M; i++)
    {
        gets(a[i]);  //a[i]的每一個變數都是一個一維陣列。
    }        
    for(i = 0; i < M; i++)
    {
      puts(a[i]);
    }                    
    return 0;
}
結果:

[email protected]:~/c$ ./a.out
abc    //輸入的第一個一維陣列
def     //輸入的第二個一維陣列
abc   //輸出的第一個一維陣列
def    //輸出的第二個一維陣列
[email protected]:~/c$ ^C
 

相關推薦

二級指標和陣列(轉)

一個函式形如: void f(float **p){ /* 想要在函式體中按二維陣列的方式訪問*/     p[1][1] = 0;//c++用vc編譯ok,執行出錯(非法訪問) } float **p; //其實這裡的p並不是一個二位陣列的指標,只不過是一個指向指標的指標 像你這樣訪問肯定是

“全棧2019”Java第三十一章陣列和多陣列

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第三十一章:二維陣列和多維陣列詳解 下一章 “全棧2019”Java第三十二章:增強for迴

(QR Code)

作者:王子旭 連結:https://zhuanlan.zhihu.com/p/21463650 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。   2016.7.5 更新:長文多圖程式碼預警,電腦食用效果更佳。 完整版程式碼已上傳 GitHub,後

一、二維碼的分類二維碼,從字面上看就是用兩個維度(水平方向和垂直方向)來進行資料的編碼,條形碼只利用了一個維度(水平方向)表示資訊,在另一個維度(垂直方向)沒有意義,所以二維碼比條形碼有著更高的資料儲存容量。從形成方式上,二維碼可以分為兩類,1、堆疊式二維碼:在一維條形碼的基礎上,將多個條形碼堆積在一起進行編

在 Laravel 5 中通過 Simple QrCode 擴充套件包生成

1、簡介 Simple Qrcode 是 Bacon/BaconQrCode 針對 Laravel 框架的封裝版本,用於在 Laravel 中為生成二維碼提供介面。 2、安裝&配置 在專案根目錄下使用如下命令安裝依賴包: composer require

Python實遍歷二維陣列題目一在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。

在準備國網的過程中,仍要刷題,程式設計題。痛並快樂著。喜歡Python語言,所以用Python進行敲磚頭。劍指offer題目一:在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列

動態初始化一陣列

/*動態初始化一維陣列1.動態初始化一維陣列,會在堆記憶體中分配這個陣列並且陣列中每一個元素都採用預設值byte short int long 0float double 0.0boolean falsechar \u0000引用 null2.什麼時候動態初始化,什麼時候靜態

PDF417條碼

    PDF417是美國符號科技(Symbol Technologies, Inc.)發明的二維條碼,發明人是臺灣赴美學人王寅君博士,王博士於1984年畢業於國立交通大學資訊系,獲得紐約州立大學石溪分校(University of New York at Stony Bro

微信小程式canva生成圖片,長按圖片識別小程式

下面這個圖片就是通過圖片和文字等內容合成的一張帶有微信小程式二維碼的圖片,在小程式內部長按可以識別出來: 基本思路是先將內容用canvas排好版,然後把該canvas轉化成圖片;圖片利用wx.previewImage進行展示,才能識別圖片中的微信小程式二維

陣列

二維陣列在概念上是二維的,有行和列,但在記憶體中所有的陣列元素都是連續排列的,它們之間沒有“縫隙”。 要用陣列指標來操作二維陣列。int (*p)[4]=a;  //p每移動一次就是移動了一個一維陣列。    指標陣列:int *p=a[4];            

陣列、指標

二維陣列、指標詳解: 1.研究二維陣列的表示。 首先,用程式碼執行進行測試,驗證的相關結果, // C.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> using namespace std

C/C++陣列(一維和

陣列這東西,說說都懂,但是似乎並沒有完全吃透,導致很多地方有疑惑。所以再梳理一遍。   陣列定義 陣列是存放型別相同的物件的容器,這些物件本身沒有名字,需要通過其所在位置訪問。 從定義中可以看出,陣列存放的是物件且型別相同。所以不存在引用的物件(引用不是物件)

陣列傳參與動態宣告

二維陣列傳參 基本形式 二維陣列在棧上分配,各行地址空間連續 定義的時候,擁有兩種形式 第一種是指明行數和列數 int array[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; 第二種是不指明第一維,而指明第二維 int array[][

C語言中陣列名與陣列地址、首行地址、首行首元素地址關係與區別(初學者必須掌握)

C語言作為很多大學理工科都會學習的語言,作為一種程式設計入門語言。但是相對於其他高階程式語言來說相對是比較難,尤其是指針,不知道有多少莘莘學子都是因為它,從C語言入門到放棄。想當年,筆者在大一學習C語言

c++陣列中指標

二維陣列  a[2][3]={{1,2,3},{4,5,6}};指標p有如下幾種表達形式:    1 方式一:int (*p)[3]=a    (或&a[0]); 一定要加上括號,因為[]的優先順序高於*;意思是定義一個指向3個int型別變數的指標。p代表二維陣列

陣列與指標、指標陣列陣列指標

int* p=a[0];//此時P是指向一維陣列的指標。P++後,p指向 a[0][1]。 int (*p1)[n];p1=a;p1++後,p1指向a[1][0];   int *p=a[0]; 則陣列a的元素a[1][2]對應的指標為:p+1*4+2 元素a[1][2]

PHP迴圈陣列 。php中__autoload()方法

PHP迴圈二維陣列   PHP程式碼: <?php $arr1=array(100,200,300,400); $arr2=array("num"=>100,"name"=>"Liuxy","score"=>98); print_r($arr1); e

陣列與指標,陣列與指標,指標陣列陣列指標的概念、例項解析

概念詳解:指標:指標與“int a”,“float b”一樣,也是一種變數,只是指標變數中儲存的是記憶體單元的地址,這是與“int a”和“float b”的本質區別,C語言的精華就在於指標、結構體和連結串列。一維陣列:定義一維陣列之後,即在記憶體中分配一段連續的地址空間,如

C 語言中陣列指標

C語言中,指標是一個複雜但又靈活多變的知識點,我們知道,在一維陣列中,對於一個數組a[],*a,a,&a,都表示a的首地址,但如果與二維陣列混合使用,就顯得更為複雜了。例如對於一個二維陣列  a[2][4]={{1,2.3},{4,5,6}}  a+i,&a

zabbix_agentd.conf zabbix客戶端配置文件的相關參數的()

Zabbix客戶端 配置文件zabbix_agentd.conf zabbix客戶端配置文件的相關參數的詳解:Aliaskey的別名,例如 Alias=ttlsa.userid:vfs.file.regexp[/etc/passwd,^ttlsa:.:([0-9]+),,,,\1], 或者ttlsa的用戶ID