【问题标题】:Updating a 2D array inside function更新函数内部的二维数组
【发布时间】:2020-12-31 05:52:08
【问题描述】:

我一直在尝试通过将二维数组作为参数传递给函数来更新它,但我似乎不明白它是如何工作的,我在下面展示了一个示例,它可以正常工作,它会更新值。

void substitution_sbox(uint8_t a[4][4]) {
      int index1, index2;
      for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
          index1 = a[i][j] >> 4;
          index2 = a[i][j] & 0x0f;
          printf("index[1]: %x and index[2]: %x\n", index1, index2);
          a[i][j] = g_aes_sbox[index2 + (16 * index1)];
          // g_aes_sbox[] is a globally defined array.
        }
      } 
  }

uint8_t plain_text[4][4] = { {0x32, 0x43, 0xF6, 0xA8}, {0x88, 0x5A, 0x30, 0x8D}, {0x31, 0x31, 0x98, 0xA2}, {0xE0, 0x37, 0x07, 0x34} };
//after calling substitution from here..
// SUBSTITUTION.
    printf("calling substitution\n");
    substitution_sbox(plain_text);
    // this function when printing, updates the array correctly.

现在,如果我尝试在另一个函数中调用相同的数组,它不会像我想的那样更新 -

void row_shift(uint8_t a[4][4]) {
   for(int i=1;i<4;i++){
      for(int j=0;j<4;j++){
        // rotate this row by i positions, to the left.
        
        // m = no. of rotations.
        for(int m=0;m<i;m++) {
            // rotate by one.
            uint8_t temp = a[i][0];
            for(int n=0;n<4;n++) {
                a[i][n] = a[i][n+1];
            }
            a[i][3] = temp;
            
            // rotate by one
        }   
        

        for(int g=0;g<4;g++) printf("%04x ",a[i][g]); 
        printf("\n");
     }
   }
}

这个函数不会改变数组,数组保持不变,有人可以帮我理解更新在这两种情况下是如何工作的吗? 谢谢。

【问题讨论】:

    标签: arrays c multidimensional-array


    【解决方案1】:

    在这两种情况下更新如何工作?

    关于 substitution_sbox 无法帮助您,因为对于 g_aes_sbox

    一切都是未知的

    你为什么要做这么复杂的事情

      index1 = a[i][j] >> 4;
      index2 = a[i][j] & 0x0f;
      ...
      a[i][j] = g_aes_sbox[index2 + (16 * index1)];
    

    而不是

    a[i][j] = g_aes_sbox[a[i][j]];
    

    因为auint8_t 的数组,所以index2 + (16 * index1) 的值为a[i][j] &amp; 0x0f + (16 * (a[i][j] &gt;&gt; 4))a[i][j]


    这个函数不改变数组,数组保持不变

    首先你有一个未定义的行为:

    for(int n=0;n<4;n++) {
        a[i][n] = a[i][n+1];
    }
    

    in 值为 3 时,您将 a[3][3] 分配给数组外的 a[3][4],行为未定义。

    碰巧未定义的行为可能没有明显的效果,并且您在a[i][3] = temp;之后取消了错误的分配

    正确的方法是测试n&lt;3而不是n&lt;4

    除此之外,您的函数对数组没有明显影响,原因很简单,您将具有 4 个值的每一行旋转 4 次。

    如果一行包含 1 2 3 4,在第一次旋转之后,你有 2 3 4 1,在第二次 3 4 1 2 之后,在第三次 4 1 2 3 之后,在第四次 1 2 3 4 之后,这显然是初始内容

    【讨论】:

    • 好的,我明白了,先生,这是我第一次使用 uint8_t 数据类型。我试图将每一行向左旋转一些值,即第一行 0 个位置,第二行 1 个等等。我搞砸了我猜的逻辑。 g_aes_sbox[] 是一个 1D uint8_t 数组,包含 256 个值。
    • for(int n=0;n
    【解决方案2】:

    数组实际上在函数row_shift()中被改变了,只是每一行被旋转了4次倍数。因为每一行的长度为 4,净效果是该行看起来没有变化,即

    • 第 0 行未旋转。
    • 第 1 行旋转了 4 次 (4*1)。
    • 第 2 行旋转 8 次 (4*2)。
    • 第 3 行旋转了 12 次 (3*4)。

    第一个嵌套循环

    for(int j=0;j<4;j++){
        ....
    }
    

    是我认为的问题。删除它,您应该会发现行分别旋转了 0、1、2 和 3 次。

    除此之外,还有@bruno 标识的错误,在该错误中存在对数组的越界访问。你也必须解决这个问题。

    【讨论】:

    • 非常感谢,我现在明白了。
    猜你喜欢
    • 2019-05-14
    • 2017-01-19
    • 2021-10-31
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    相关资源
    最近更新 更多