代码之家  ›  专栏  ›  技术社区  ›  pistacchio

c中二维数组的“方向”

  •  2
  • pistacchio  · 技术社区  · 16 年前

    作为一个C新手,我对二维数组有点困惑。

    如果我想表示3行5列的矩阵,我想正确的声明是:

    char a[3][5];
    

    那么,这是一个指向5个字符数组的3个指针的数组还是什么?

    为什么每当我试着像下面这样循环一遍,它似乎读错了结果?

    int x, y;
    for( x=0; x<3; x++ ){
        for( y=0; y<3; y++ ){
            printf( "%c", a[x][y] );
        }
    }
    

    以下是初始化它的等价和正确的方法吗?

    char a[3][5] = {
                   {1,0,0,0,1},
                   {1,0,0,0,1},
                   {1,0,0,0,1},
                   };
    
    char a[3][5] = {1,0,0,0,1,
                    1,0,0,0,1,
                    1,0,0,0,1};
    

    谢谢你最后的解释。


    编辑

    对不起,代码没有被复制。顺便说一下,我一直让他们像垂直阅读一样阅读,而不是水平阅读。

    同样在本教程的示例中 http://www.cplusplus.com/doc/tutorial/arrays/ 它读取数组的方式对我来说并不重要,因为它似乎在5x3的高度上工作。 宽度,Y X,科尔斯 行结构而不是3x5,宽度 高度,X Y.行 第一列:

    #define WIDTH 5
    #define HEIGHT 3
    
    int jimmy [HEIGHT][WIDTH];
    int n,m;
    
    int main ()
    {
      for (n=0;n<HEIGHT;n++)
        for (m=0;m<WIDTH;m++)
        {
          jimmy[n][m]=(n+1)*(m+1);
        }
      return 0;
    }
    
    8 回复  |  直到 16 年前
        1
  •  4
  •   Johannes Schaub - litb    16 年前

    只是为了它是什么和不是什么。

    char a[3][5];
    

    不涉及指针。像这样的多维数组是…数组的数组。等等。在您的例子中,您有一个3个5个字符的数组。当你用typedefs时,它会变得更清晰。

    typedef char T[5];
    T a[3];
    

    不涉及任何指针。如果要访问这三个数组中的第一个数组,可以执行以下操作:

    a[0]; 
    

    它会给你一个 char[5] 是的。通常,您不会注意到这一点,因为通常您会索引所有维度。所以返回的数组 a[0] 是下一个索引的下标,例如 a[0][1] 是的。这个 [1] 将应用于 A[0] ,正如我们之前发现的 字符[5] 是的。

    那么,这是一个指向5个字符数组的3个指针的数组还是什么?

    让我们创建这个类型,看看它与上面的不同。创建它很简单,一旦获得基本的声明器:

    • 创建指针: *D
    • 创建数组: D[N]

    D只是一个现有的另一个声明器。现在我们继续。你先说 array of 3 pointers to 5 arrays of chars... 是的。我想你是说 array of 3 pointers to arrays of 5 chars 是的。第一, array of 5 被创造成

    D1[5]
    

    现在,让我们用一个 pointer to 声明人:

    (*D2)[5]
    

    我们必须插入括号,因为下标运算符 [N] 绑定比解引用运算符更好 * ,否则将被解读为 *(D2[5]) 这不是我们想要的。现在我们有了 pointer to array of 5 是的。

    现在让我们做 array of 3 是的。更换 D2 通过 D3[3] 产生以下结果:

    (*D3[3])[5]
    

    很好,现在我们有了 array of 3 pointer to array of 5 是的。只需将声明器所属的基类型放入以生成完整声明:

    char (*D3[3])[5];
    

    当然,这是完全不同的:)您可以使用它来存储指向另一个数组的指针,该数组的类型是 array of 3 arrays of 5 char 是的。让我们存储一个指向 a 进入之内 D3[0] . 我们早就知道了 A[0] 具有类型 字符[5] 是的。我们可以将指向该数组的指针存储到 D3[0] ,因为 D3 是指向 字符[5] ,真是巧合!

    D3[0] = &a[0]; // works!
    

    我希望这个小练习向您展示了指针和数组之间的一些关系。干杯!

        2
  •  2
  •   poundifdef    16 年前

    我看到你的代码有几个问题。首先(从上面复制):

    int x, y;
    for( x=0; x<3; x++ ){
        for( x=0; x<3; x++ ){
            printf( a[x][y] );
        }
    }
    

    在你的内部循环中,它看起来像你想要使用 y 而不是 x ,你想要 是的 从0…5开始。当前,您正在重复变量x。另外,printf()语句有问题。下面是一些正确的代码:

    int x, y;
    for( x=0; x<3; x++ ){
        for( y=0; y<5; y++ ){
            printf("%d\n", a[x][y] );
        }
    }
    

    其次,当初始化数组时,代码是 几乎 对的。下面是正确的版本:

    char a[3][5] = {
                   {1,0,0,0,1},
                   {1,0,0,0,1},
                   {1,0,0,0,1}
                   };
    

    (我删除了 , 在最后一行数据之后——这是一个语法错误。)

    您发布的第二个语法不正确(没有大括号的语法)。

        3
  •  2
  •   Michael Myers KitsuneYMG    16 年前

    因为你在使用 x 两次(看起来像复制/粘贴错误)。尝试

    int x, y;
    for (x = 0; x < 3; x++) {
        for (y = 0; y < 5; y++) {
            printf("%c", a[x][y]); // Emil H says "%d" might be more useful
        }
    }
    

    编辑: 我不知道那篇教程有什么让人困惑的。它完全等同于您的代码,除了不打印数组,而是将每个元素设置为(row*column)(其中row和column都是一个基,因此是+1)。

        4
  •  1
  •   nivnad    16 年前

    本教程中的图像是数据的一个很好的表示: alt text http://www.cplusplus.com/doc/tutorial/arrays/bidimensional_arrays3.gif

    从示例中,嵌套的 for 循环逐行遍历(左->右)数组,并为每列填充一个值。

        5
  •  1
  •   hept    16 年前

    我谦卑地认为,像在您可能需要%d时使用%c这样的小错误并不是您真正想要得到的答案。您说您对数组有点困惑,还提到您希望将指针视为包含数组的数组的数组元素。你

    数组定义中的最后一个逗号不是语法错误。从C99开始允许。

    真正能澄清问题的是要知道数组不是指针。确实,数组名可以用作常量指针(指向第一个元素),指针可以像数组一样被索引。然而,这并不意味着数组和指针是相同的。他们不是。

    你问你的程序中的符号“A”到底是什么。它是一个数组。内存布局可以可视化为三部分中的一条长线,但仍在一条连续的线上。然后用同样的方法把它们分成五部分。对一个元素寻址时,必须使用两个索引;首先是要对哪个五元素数组进行索引,然后是要对这个元素的哪个五元素数组进行索引。

    内存布局不像行和列的网格。内存由一个标量寻址,所以它是线性的。指针算法可能是下一个你可以研究的问题,看看指针上的增量是如何工作的。

        6
  •  1
  •   Zifre    16 年前
    int x, y;
    for( x=0; x<3; x++ ){
        for( x=0; x<3; x++ ){
            printf( a[x][y] );
        }
    }
    

    您需要将第二个for循环改为引用“y”而不是“x”。

    希望能有所帮助。

        7
  •  0
  •   Emil H    16 年前

    你使用printf的方式不对。尝试:

    printf("%d", a[x][y]);
    

    我不确定您是要使用%c还是%d。如果要打印号码,请使用%d。如果要打印实际字符,请使用%c。

        8
  •  0
  •   Dave Costa    16 年前

    字符A[3][5];

    那么,这是一个由3个指针组成的数组吗 5组字符还是什么?

    是的,就是这样。尽管您也可以将其作为一组连续的15个字符进行操作。

    按照惯例,大多数人会认为它代表了一个有3行5列的矩阵(我认为),但数据结构本身并没有要求这样做。您可以很容易地使用它来表示5行和3列。或者3个集合,每个集合包含5个元素,但彼此之间没有任何有意义的关系。

    执行矩阵操作的特定库对此有一个约定。