如果我使用大索引启动 bash 数组会发生什么?

如果我使用大索引启动 bash 数组会发生什么?

我试图创建一个 bash“多维”数组,我看到了使用关联数组的想法,但我认为最简单的方法如下:

for i in 0 1 2
do 
    for j in 0 1 2
    do
        a[$i$j]="something"
    done
done

设置和获取值很容易,但是如果 bash 为从索引 00 到 22 的元素顺序分配空间(我的意思是分配位置 {0,1,2,3, 4,...,21,22}),而不仅仅是实际设置的元素:{00,01,02,10,11,...,21,22}。

这让我想知道,当我们以索引“n”启动 bash 数组时会发生什么?它是否为索引 0 到 n 分配足够的空间,或者是否单独分配第 n 个元素类别?

答案1

bash 中的数组索引与 ksh 中的数组索引(复制了 bash 的数组设计)可以是任何算术表达式。

在 中a[$i$j]="something"$i$j变量被扩展,因此i=0 j=1,变成a[01]="something"01作为算术表达式,在 bash 中表示八进制数 1。有了i=0 j=10,那就a[010]="something"和 一样了a[8]="something"。你会得到a[110]="something"x=11 y=0x=1 y=10

现在应该很明显这不是您想要的。

相反,您可以像在 C 中那样处理二维数组(矩阵):

matrix_size=3
for (( i = 0; i < matrix_size; i++ )) {
  for (( j = 0; j < matrix_size; j++ )) { 
    a[i * matrix_size + j]="something"
  }
}

for (( ...; ...; ...))从 ksh93 复制的类似 C 的构造)。

或者切换到支持多维数组的 ksh93:

for (( i = 0; i < 3; i++ )) {
  for (( j = 0; j < 3; j++ )) { 
    a[i][j]="something"
  }
}

使用键只是字符串的关联数组也可以实现多维数组:

typeset -A a
for (( i = 0; i < 3; i++ )) {
  for (( j = 0; j < 3; j++ )) { 
    a[$i,$j]="something"
  }
}

根据报告,您在所有三个中得到的结果变量typeset -p

  1. declare -a a=([0]="something" [1]="something" [2]="something" [3]="something" [4]="something" [5]="something" [6]="something" [7]="something" [8]="something")
    
  2. typeset -a a=((something something something) (something something something) (something something something) )
    
  3. declare -A a=([0,2]="something" [0,1]="something" [0,0]="something" [2,1]="something" [2,0]="something" [2,2]="something" [1,2]="something" [1,0]="something" [1,1]="something" )
    

现在回答主题中的问题,在 bash 中,就像在 ksh 中一样,普通数组是稀疏的,这意味着您可以a[n]定义而不a[0]a[n-1]定义,所以从这个意义上说,它们不像 C 或大多数其他语言的数组或贝壳。

最初在 ksh 中,数组索引限制为 4095,因此您最多可以拥有 64x64 大的矩阵,此后该限制已提高到 4,194,303。在 ksh93 中,我看到这样做a[4194303]=1确实分配了超过 32MiB 的内存,我猜想保存 4194304 64 位指针和一些开销,而这似乎不会发生在bash,其中数组索引可以高达 9223372036854775807 (至少在 GNU/Linux amd64 上) ),而不分配比存储实际设置的元素所需更多的内存。

在所有其他支持数组的 shell 中((t)csh、zsh、rc、es、fish...),数组索引从 1 而不是 0 开始,并且数组是普通的非稀疏数组,您不能在没有设置的情况下进行a[2]设置a[1]即使设置为空字符串。

与大多数编程语言一样,bash 中的关联数组被实现为哈希表,没有顺序或等级的概念(您会注意到typeset -p上面以看似随机的顺序显示它们)。

有关不同 shell 中阵列设计的更多详细信息,请参阅这个答案测试 shell 对数组的支持

相关内容