以太坊智能合约语言Solidity - 3 数组

3. 数组

1字节(Byte) = 8位 (bit), bytes32 = 256位,bytes1 实质上就等于 int8

3.1 固定长度的字节数组

固定长度的数组一旦被定义就无法再更改,并且长度在一开始就会被显式定义

我们再来创建一个新的文件用来编写代码

pragma solidity ^0.4.0;

contract BytesArray {
    bytes2 num = 125;


    //如下返回值为2
    function getLength() view public returns(uint)
    {
        return num.length;
    }
}

字节数组无法进行基本运算,但是可以比较

    bytes1 public a = 0x7a; //0111 1010 218
    bytes1 public b = 0x68; //0110 1000 184

    //false
    function compare() returns(bool) {
        return a==b;
    }

    //true
    function compare2() returns(bool) {
        return a!=b;
    }

    //true
    function compare3() returns(bool) {
        return a>b;
    }

字节数组还支持其他一些逻辑运算,具体计算结果如下,读者也可以自行运算比较

    bytes1 public a = 0x7a; //0111 1010 218
    bytes1 public b = 0x68; //0110 1000 184

  	--
		//0x68
    function weiyu() view public returns(bytes1) {
        return a & b;
    }
    //0x7a
    function weihuo() view public returns(bytes1) {
        return a | b;
    }
    //0x85
    function weifan() view public returns(bytes1) {
        return ~a;
    }
    //0x12
    function weiyihuo() view public returns(bytes1) {
        return a ^ b;
    }
    //0xf4
    function zuoyi() view public returns(bytes1) {
        return a << 1;
    }
    //0x3d
    function youyi() view public returns(bytes1) {
        return a >> 1;
    }

3.2 动态字节数组

动态数组的具体操作如下,读者可手动编译尝试体验

pragma solidity ^0.4.0;

contract Dynamicbytes {

    //定义一个空数组 :0x0000
    bytes public name = new bytes(2);


    //给空数组中填充变量 :0x7a68
    function InitName() {
        name[0] = 0x7a;
        name[1] = 0x68;
    }
    //获取数组的长度 :2
    function getLength() view returns(uint)
    {
        return name.length;
    }
    //改变数组的长度 :0x7a68000000
    function changeLength() {
        name.length = 5;
    }
    //改变数组中的内容 :0x8868000000
    function changeName() {
        name[0] = 0x88;
    }
    //往数组中增加内容:0x886800000099
    function pushTest() {
        name.push(0x99);
    }
}

3.3 字符串

字符串无法获取长度,但是可以通过转换为动态字节数组获取。也无法通过索引直接获取片段内容,但是也可以通过将其转换为动态字节数组获取。总之,大多数我们想实现的操作都得先进行强转

具体案例请参考如下:

pragma solidity ^0.4.0;

contract DynamicString {
    
    string name = "zhengjianxun";

    //获取string长度,先得强转 :12
    function getLength() view returns(uint)
    {
        return bytes(name).length;
    }
    //获取部分内容,也得先强转 :0x68
    function changeName() returns(bytes1){

        return bytes(name)[1];
    }

    //获取状态变量 :0x7a68656e676a69616e78756e
    function getName() view returns(bytes)
    {
        return bytes(name);
    }
    //改变部分内容:0x4c68656e676a69616e78756e
    function changeName2() {
        bytes(name)[0] = "L";
    }
}

3.4 String处理中文与特殊字符

其他字符或者中文字符也可以通过上述方法获取

​ string name2 = “*(&&(%”;
​ string name3 = “郑建勋”;

​ //获取string长度,先得强转 :6
​ function getLength2() view returns(uint)
​ {
​ return bytes(name2).length;
​ }

​ //获取string长度,先得强转 :9
​ function getLength3() view returns(uint)
​ {
​ return bytes(name3).length;
​ }

3.5 固定长度的字节数组转换

同上,我们可以将固定长度的数组转换为不痛长度的数组

pragma solidity ^0.4.0;

contract changgeFixBytes{
    bytes12 name = 0x7a68656e676a69616e78756e;

    //0x7a
    function changeBytes1() view returns(bytes1) {
        return bytes1(name);
    }

    //0x7a68
    function changeBytes2() view returns(bytes2) {
        return bytes2(name);
    }

    //0x7a68656e676a69616e78756e00000000
    function changeBytes16() view returns(bytes16) {
        return bytes16(name);
    }
}

3.6 将bytes转化为string

pragma solidity ^0.4.0;

contract BytesToString {

    //创建一个空数组
    bytes name = new bytes(2);

    //初始化空数组
    function Init() {
        name[0] = 0x7a;
        name[1] = 0x68;
    }

    //使用string将数组强转为string :zh
    function bytesToString() view returns(string) {
        return string(name);
    }
}

3.7 For循环

我们可以使用For循环将固定长度的bytes转化为string

pragma solidity ^0.4.0;

contract Bytes32ToString {
    //定义一个长为两字节的数组
    bytes32 name = 0x7a68000000000000000000000000000000000000000000000000000000000000;

    // function changeIt() returns(string) {
    //     //return string(name)
    // }

    //无法直接强转
    function bytes32ToString() view returns(string)
    {
        return string(name);
    }

    //可以先通过for循环遍历再强转(需要一个初始化的过程)
    //输入0x7a68000000000000000000000000000000000000000000000000000000000000;得到:zh
    function bytes32ToString2(bytes32 _newname) view returns(string) {
        //定义一个空数组
        bytes memory newname = new bytes(_newname.length);
        
        for (uint i = 0; i < _newname.length; i++) {
            //遍历输入的字节数组长度,然后赋值给前面的空数组
            newname[i] = _newname[i];
        }
        //使用string强转返回这个数组
        return string(newname);
    }
}

3.8 固定uint数组

pragma solidity ^0.4.0;

contract FixArray{

    //定义一个元素为uint类型的数组
    uint[5] arr = [1,2,3,4,5];
    //修改数组中部分元素的值
    function Init(){
        arr[0] = 100;
        arr[1] = 200;
    }
    //100,200,3,4,5
    function getArrayContent() view returns(uint[5]){
        return arr;
    }
    //对数组元素进行求和 :312
    function getGrade() view returns(uint){
        uint grade = 0;

        for (uint i = 0; i < 5; i++) {
            grade += arr[i];
        }

        return grade;
    }
}

但是固定数组不能修改长度和增加元素

3.9 动态uint数组

pragma solidity ^0.4.0;

contract DynamicArray{
    uint[] grade = [1,2,3,4,5];

    // 5
    function getLength() returns(uint){
        return grade.length;
    }
    // 1,2,3,4,5
    function getArrayContent() view returns(uint[]){
        return grade;
    }
    // 15
    function add() view returns(uint) {
        uint sum = 0;

        for( uint i = 0;i<grade.length;i++){
            sum += grade[i];
        }

        return sum;
    }
    // 1
    function changelength() returns(uint){
        grade.length = 1;
    }
    // 10
    function changelength2() returns(uint){
        grade.length = 10;
    }
    //增加元素: 1,0,0,0,0,0,0,0,0,0,11
    function changeContent() returns(uint[]){
        grade.push(11);
        return grade;
    }
}

动态uint可以修改长度和增加元素

3.10 固定长度二维数组

pragma solidity ^0.4.0;

contract twoArray {

    //定义一个二维数组
    uint[2][3] grade = [[1,2],[3,4],[5,6]];

    // 3 
    function getOneLength() returns(uint)
    {
        return grade.length;
    }
    // 2
    function getTwoLength() returns(uint)
    {
        return grade[0].length;
    }
    // 1,2,3,4,5,6
    function getContent() view returns(uint[2][3]){
        return grade;
    }
    // 21
    function add() view returns(uint){
        uint sum = 0;

        for(uint i = 0;i < grade.length;i++){
            for(uint j = 0; j < grade[0].length;j++){
                // 注意,定义和获取时i和j的意义并不相同
                sum += grade[i][j];
            }
        }
        return sum;
    }   
}

3.11 动态二维数组

pragma solidity ^0.4.0;

contract FixTwoArray {
 
    //定义一个二维数组
    uint[][] grade = [[1,2],[3,4],[5,6]];

    // 3 
    function getOneLength() returns(uint)
    {
        return grade.length;
    }
    // 2
    function getTwoLength() returns(uint)
    {
        return grade[0].length;
    } 
    // 10
    function changelength() returns(uint){
        return grade.length = 10;
    } 
    // 5
    function changelength2() returns(uint){
        return grade[0].length = 5;
    } 

    function changeContent() {
        grade[0][0] = 100;
    }
    // 100
    function getContent() view returns(uint){
        return grade[0][0];
    }
}

事实上动态二维数组和其它类型的扩展规则大体类似,读者可以自行编写并测试上述代码

3.12 数组字面量

pragma solidity ^0.4.0;

contract ArrayLiterals {
    // solidity语言中,字面量按最小类型推断
    function getArrayLiterals() returns(uint8[3]) {
        return [1,2,3];
    }
    // 虽然按照最小类型推断,但是可以通过显式指定绕过此规则
    function getArrayLiterals2() returns(uint16[3]) {
        return [uint16(1),2,3];
    }
    // 作为函数的参数
    function getArrayLitrals3(uint[3] grade) view returns(uint){
        uint sum = 0;

        for(uint i = 0; i < grade.length;i++) {
            sum += grade[i];
        }
        return sum;
    }
}

关于数组的内容我们就先告一段落了

猜你喜欢

转载自blog.csdn.net/weixin_51487151/article/details/123461353