二維陣列
在幾何的世界里,一維為線,二維為面;而在程式的的世界中,一維為串列,二維為表;
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7TdOG4nN-1613576067441)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210215115526108.png)]](https://img.uj5u.com/2021/02/19/225943190745291.png)
類似于上圖,我們就可以看做是一個表結構,我們可以用行和列來確定其中的元素,那么在solidity中怎么表示呢?
pragma solidity ^0.4.16;
contract TwoArray{
uint[2][3] arr = [[1,2],[23,4],[6,7]];
function getLength() view returns(uint){
return arr.length;
}
}
上面我們演示了二維陣列獲取長度的方式,也就是我們上圖的二維陣列中有3個元素,也就是說,二維陣列中存放的元素是一維陣列,想要獲取具體元素的資訊,我們就可以將二維陣列進行遍歷,得到一維陣列,再進行一次一維陣列遍歷,就可以獲取到我們具體的元素內容了,下面我們來看代碼:
function getContentLegth() view returns(uint){
return arr[0].length;
}
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VJ27LIJJ-1613576067444)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217051234475.png)]](https://img.uj5u.com/2021/02/19/225943190745292.png)
相信有編程基礎的同學不用我在過多解釋了,如果是初學者的話,可以記住這個表示方式,和我們其他編程語言類似,但稍稍會有點差別,可以按照行列運算式的方式去理解他,一行代表一個一維陣列,列的個數代表有多少個一維陣列,
在者,我們看看固定長度二維陣列是否可以改變其長度呢?
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZlYMknUG-1613576067445)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217055241655.png)]
顯然,從名字就可以推斷出是不可以進行修改的,
接下來,我們看一看陣列的內容輸出的結果以及遍歷,
function getContent() view returns(uint[2][3]){
return arr;
}
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-u3NyR9dv-1613576067447)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217051817101.png)]](https://img.uj5u.com/2021/02/19/225943190745293.png)
從上圖可以看出,我們的二維陣列輸出是線性表示的,那么現在假設我們要對二維陣列內所有內容進行累加求和,
就需要對二維陣列進行遍歷,那么上代碼
function add() view returns(uint){
uint sum = 0;
for(uint i = 0;i<arr.length;i++){
for(uint j=0;j<arr[0].length;j++){
sum += arr[i][j];
}
}
return sum;
}
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DRINJoXj-1613576067449)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217053152031.png)]](https://img.uj5u.com/2021/02/19/225943190745294.png)
從上圖中可以看出,結果符合我們的預期,然后再回頭看代碼,值得注意的是j<arr[0].length;因為我們這個是固定長度的二維陣列,二維陣列中每一個元素的個數是相等的,所以可以這么寫,
大家可以看,下面這種增加元素或者減少元素的寫法都是編譯報錯的,
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sks81Edl-1613576067451)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217053846799.png)]](https://img.uj5u.com/2021/02/19/225943190745295.png)
最后,介紹一下我們可以直接修改二維陣列的內容,
function changeContent(){
arr[1][0] = 3;
}
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-79CYHO76-1613576067453)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217054435563.png)]](https://img.uj5u.com/2021/02/19/225943190745296.png)
大家可以發現,我們可以這樣直接地修改陣列,得到我們預期的結果,值得注意的一點是,陣列的下標都是從0開始的,
在這里,我們固定長度的二維陣列也就介紹完啦,下節,我們看看可變長度二維陣列,
可變長度二維陣列
和以前的之前的陣列類似,固定長度二維陣列和可變長度二維陣列也存在一些異同點,下面我們僅僅介紹不一樣的地方,
差異1:可變長度二維陣列不支持直接獲取陣列內容
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LFL2y8JR-1613576067454)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217060918527.png)]
差異2:可變長度二維陣列支持修改其長度
pragma solidity ^0.4.16;
contract DynamicTwoArray{
uint[][] arr = [[1,2],[3,4],[6,7]];
// function getContent() view returns(uint[][]){
// return arr;
// }
function changeLength() {
arr.length = 10;
}
function getLength() view returns(uint) {
return arr.length;
}
function getContntLength() view returns(uint) {
return arr[0].length;
}
}
這里我寫了兩個函式,一個是獲取二維陣列的長度,一個是獲取陣列內容的長度,會發現,我們修改的只是二維陣列的長度,并沒有改變掉二維陣列中一維陣列的長度,
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qho1d1kw-1613576067457)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217062044591.png)]](https://img.uj5u.com/2021/02/19/225943190745297.png)
另外要說明的一點是,可變長二維陣列初始化的時候也是不允許每個一維陣列長度不相同的,
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kItCa4j0-1613576067459)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217062525308.png)]](https://img.uj5u.com/2021/02/19/225943190745298.png)
陣列字面量
前面我們介紹過位元組陣列的字面量,這里也說說陣列字面量,
首先,我們先來看一個例子:
pragma solidity ^0.4.16;
contract ArrayLiterals{
function getArrayLiterals() returns(uint[3]){
return [1,2,3];
}
function getArrayLiterals2() returns(uint[3]){
return [256,2,3];
}
}
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zEjzv5ob-1613576067461)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217064015516.png)]
在這里,我們相當于再復習一下位元組陣列uint型別的知識,我們具體來看看他的報錯資訊,
browser/Math.sol:6:15: TypeError: Return argument type uint8[3] memory is not implicitly convertible to expected type (type of first return variable) uint256[3] memory.
return [1,2,3];
^-----^
browser/Math.sol:10:15: TypeError: Return argument type uint16[3] memory is not implicitly convertible to expected type (type of first return variable) uint256[3] memory.
return [256,2,3];
^-------^
我們查看錯誤資訊會發現,第一個我們回傳的陣列元素1,2,3,都是uint8型別的,因為1,2,3 都只占用1個位元組,也就是8位,而uint[3]相當于uint[256]3,因為uint默認是256位的,第二個我們回傳的陣列元素256,2,3,其中256是16位(因為我們知道255是8位的最大十進制數,所以256占兩個位元組,16位)而剩下的都是uint8型別的,而uint[3]相當于uint[256]3,因為uint默認是256位的,
所以知道了以上規則后,你們覺得怎么修改好呢~?
顯然,修改回傳值字面量是不現實的,那么我們就可以在回傳值定義引數上下功夫,例如第二個,我們可以這么改,
pragma solidity ^0.4.16;
contract ArrayLiterals{
// function getArrayLiterals() returns(uint[3]){
// return [1,2,3];
// }
function getArrayLiterals2() view returns(uint16[3]){
return [256,2,3];
}
}
對,將回傳值引數中的型別改為陣列元素中最大值的型別即可,
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bYyIvaMV-1613576067463)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217073541665.png)]](https://img.uj5u.com/2021/02/19/225943190745299.png)
當然 上面的第一個例子也可以將函式回傳引數的型別改為uint8[3]嗎?不過還有一種方式可以,下面請看
function getArrayLiteterrals5() view returns(uint[3]){
return [uint(1),2,3];
}
是的,我們可以通過這種強轉的方式也可以達到我們的目的,
那么我們清楚了陣列字面量有什么用呢?因為在實際的應用當中,我們的合約大多數形式就是通過陣列來傳參的,例如我們要對一個資料進行就和,我們可以這么做,
function getArrrayLiteralalss6(uint[3] arr) view returns(uint){
uint sum = 0;
for(uint i= 0;i<arr.length;i++){
sum += arr[i];
}
return sum;
}
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zTe071k9-1613576067464)(C:\Users\49178\AppData\Roaming\Typora\typora-user-images\image-20210217195236924.png)]](https://img.uj5u.com/2021/02/19/2259431907452910.png)
而我們實際的入參就是我們的陣列字面量啦,如是[100,200,300];
好了,到這里,我們關于陣列的內容,就介紹完畢啦,我們簡單做一個回顧,我們介紹了位元組陣列、陣列、二維陣列,而圍繞陣列的內容主要是關于陣列的初始化、獲取長度及其內容,修改長度及其內容,還有型別轉化,只要大家跟著碼上一遍,相信也能夠很快地掌握這些內容,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/261017.html
標籤:區塊鏈
下一篇:挖礦是什么?挖礦怎么挖?
