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;
}
}
关于数组的内容我们就先告一段落了