一、string如何存盤中文字符
二、固長陣列
三、動態陣列
四、二維陣列
五、動態二維陣列
一、string如何存盤中文字符
先看一段代碼:
pragma solidity >=0.4.22 <0.6.0;
contract Test {
string name = "張三";
function getLength() public view returns(uint256){
return bytes(name).length;
}
}
- 我們知道,普通字符在占據的記憶體是一個位元組,那么像中文這種特殊字符應該怎么存盤呢?我們執行上面的代碼:

- 可以看到,一個中文字符是3個位元組,總共是6個,
- 事實上,在string中,特殊字符是用UTF-8存盤的,
- 關于UTF-8:UTF-8介紹
- 介紹兩個關鍵字:
memory:臨時變數,定義在函式內的變數默認為memory,一些版本的編譯器要求定義在函式內的臨時變數必須加上memory關鍵字,
storage:永久寫入區塊鏈的變數,就是定義在函式之外的狀態變數,
- 把位元組陣列轉化為動態位元組陣列,代碼:
pragma solidity ^0.7.0;
contract Test {
bytes6 name = 0x112233445566;
function toNe() view public returns(bytes memory) {
bytes memory newName = new bytes(name.length);
for(uint i = 0;i < name.length;i++){
newName[i] = name[i];
}
return newName;
}
}
- 有編程基礎的人應該不難看出代碼邏輯,這里直接給出結果:

- 動態位元組陣列轉字串可以通過強制轉換實作,但是普通的位元組陣列想要轉字串就比較麻煩了,修改以上代碼:
pragma solidity ^0.7.0;
contract Test {
bytes6 name = 0x112233445566;
bytes2 name2 = 0x7a68;
function toNe() view public returns(bytes memory) {
bytes memory newName = new bytes(name.length);
for(uint i = 0;i < name.length;i++){
newName[i] = name[i];
}
return newName;
}
function BytestoString() view public returns(string memory){
bytes memory newName = new bytes(name2.length);
for(uint i = 0;i < name2.length;i++){
newName[i] = name2[i];
}
return string(newName);
}
}
- 第二個函式的目的是吧name2位元組陣列型別轉化為string型別,有編程基礎的看這個代碼邏輯也不難,在這里不過于解釋,運行結果:

- 但是這也引發了一個問題,當bytes的空間大于我輸入的資料的時候,比如bytes6 = 0x112233,那么后面三位就會自動賦值為0,若這樣的資料也被轉換成string那就很浪費空間,解決方式就是先把bytes型別轉換為動態bytes,再強轉為string,
二、固長陣列
- 關于陣列這個概念大家肯定都不陌生,先看代碼:
pragma solidity ^0.4.0;
contract TestArray {
uint[5] arr;
function getArrayContent() view public returns(uint[5]){
return arr;
}
}
- 運行getArrayContent()函式,得到結果:

- 說明uint陣列在默認情況下,初始值為0
- 通過方法來修改陣列中的值,在合約中加入以下代碼:
function Init() public {
arr[0] = 100;
arr[1] = 200;
}
- 先運行Init(),再運行getArrayContent(),運行結果:

- 可以看到,arr陣列的第一個元素和第二個元素已經被修改了,
- 在定義的時候也可以初始化值,修改代碼:
pragma solidity ^0.4.0;
contract TestArray {
uint[5] arr = [1,2,3,4,5];
function Init() public {
arr[0] = 100;
arr[1] = 200;
}
function getArrayContent() view public returns(uint[5]){
return arr;
}
}
- 先運行getArrayContent()方法查看陣列中的值:

- 初始化成功,
- 在運行Init()方法后再運行getArrayContent()方法:

- 可以看到,陣列中的前兩個值也被修改了,
- 我們可以用這個陣列進行一些簡單的演算法,比如求陣列中所有元素的和,給出代碼:
function getGrades() view public returns(uint) {
uint totall = 0;
for(uint i = 0;i < arr.length;i++){
totall = totall + arr[i];
}
return totall;
}
- 我們先運行Init()方法初始化后,再運行getGrades進行求和操作,預期結果應該是100+200+3+4+5 = 312,運行結果:

- 運行結果與預期的相符,
- 陣列是有length屬性的,但是不能對length屬性進行修改,固定陣列也沒有push方法,不能向固定陣列中增加元素,
三、動態陣列
先看代碼:
pragma solidity ^0.4.0;
contract TestArray {
uint[] arr;// 定義一個可變長度的陣列
function getContent() view public returns(uint[]){
return arr;
}
function getLength() view public returns(uint){
return arr.length;
}
}
- arr就是一個動態陣列,因為它沒有被定義長度,
- 運行getContent()查看arr的默認值,再運行getLength()查看arr的默認大小

- 可以看到,arr里面沒有值,大小也是0,
- 修改代碼:
pragma solidity ^0.4.0;
contract TestArray {
uint[] arr = [1,2,3,4,5];// 定義一個可變長度的陣列
function getContent() view public returns(uint[]){
return arr;
}
function getLength() view public returns(uint){
return arr.length;
}
function setArr() public{
arr[0] = 100;
arr[1] = 200;
}
function push() public{
arr.push(6);
arr.push(7);
arr.push(8);
}
}
- 首先直接運行getContent()和getLength(),獲取初始化后arr里的值和arr的大小:

- 運行setArr方法修改其中的值,再運行下面兩個get方法:

- 運行push()方法向陣列后面增加三個數,再運行下面兩個get方法:

- 既然是動態陣列,那長度也是可以改變的,我們寫一個函式驗證一下,
function changeLength(uint length) public{
arr.length = length;
}
- 這個函式的邏輯很簡單,在這里就不細說了,
- 運行changeLength方法春如引數為10,之后在運行兩個get方法,運行結果:

可以看到,之后添加的空間上都補上了0
- 相同的方法,吧引數改為1,運行結果:

超過給定大小之后的值全部都被抹去了,
四、二維陣列
在java中的二維陣列,例如int[3][2] arr;表示arr有3個元素,每個元素都是一個長度為2的陣列,
但是在solidity里,完全相反,例如uint[3][2] arr;表示arr有2個元素,每個元素都是一個長為3的陣列,
給出二維陣列有關代碼:
pragma solidity ^0.4.0;
contract TestArray {
uint[2][3] arr = [[1,2],[3,4],[5,6]];
function getLength() view public returns(uint){// 獲取陣列的長度
return arr.length;
}
function getLength2() view public returns(uint){// 獲取二維陣列的長度
return arr[0].length;
}
function getContent() view public returns(uint[2][3]){// 獲取二維陣列中所有數的值
return arr;
}
function add() view public returns(uint){// 將二維陣列中所有數相加
uint count = 0;
for(uint i = 0;i < getLength2();i++){
for(uint j = 0;j < getLength();j++){
count += arr[j][i];
}
}
return count;
}
}
- 每個函式的功能都在代碼中標出,邏輯都很簡單,可以自己回去寫一下,運行結果:

- 結果正確,
- 也可以通過方法修改二維陣列的元素值,在這里就不給出代碼了,
五、動態二維陣列
先給出代碼:
pragma solidity ^0.4.0;
contract TestArray {
uint[][] arr = [[1,2],[3,4],[5,6]];
function setLength(uint length) public{
arr.length = length;
}
function getLength() view public returns(uint){
return arr.length;
}
}
-
運行getLength()獲取長度:

-
運行setLength()更改長度之和,再運行getLength()獲取更改后的長度,這里我們給出兩個結果,第一個輸入2,第二個輸入6


-
可以看到,可變二維陣列的大小增加和減少都是沒有問題的,
- 二維可變陣列沒有push()方法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/247224.html
標籤:區塊鏈
上一篇:無網路和顯示幕開啟樹莓派Zero的WiFi和SSH服務
下一篇:區塊鏈入門-1
