【问题标题】:Value in 2D array appears twice when set once设置一次时,二维数组中的值出现两次
【发布时间】:2020-10-12 09:19:16
【问题描述】:

我有一个包含字符的二维数组,但是当我更改其中一个值时,它会在数组中的两个不同位置发生变化。

我当前的代码是:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define WIDTH 100
#define HEIGHT 50

#define SHADE " .*#@"

void print_display(char disp[WIDTH][HEIGHT])
{
    system("cls");

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++)
            printf("%c", SHADE[disp[y][x]]);

        printf("\n");
    }
}

int main()
{
    char disp[WIDTH][HEIGHT];
    memset(&disp, 1, WIDTH * HEIGHT);

    disp[49][0] = 4;

    print_display(disp);
    
    return 0;
}

运行此代码会为我生成:

....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
..................................................@.................................................
@...................................................................................................
但在接近尾声时它包含两个 @ 它应该只有一个。

我尝试将数组存储在堆上,但仍然存在同样的问题。 谢谢。

【问题讨论】:

  • 仅供参考,您的循环运行 HEIGHT->WIDTH,而您的数组尺寸为 WIDTH->HEIGHT。是的。从那开始。
  • printf("%c", SHADE[disp[y][x]]); 应该是printf("%c", SHADE[disp[x][y]]);
  • 值得一提,如果您正在对数组进行表格化(而且看起来确实如此),那么“宽度”应该是 inferior 下标,而“高度”应该是上级下标。换句话说,50 行 20 个元素的数组将是:char[50][20]。更改程序中所有 与该口头禅一致的内容(应该有两个关键的地方你会看到是错误的),并且它应该像你想要的那样运行。

标签: arrays c multidimensional-array


【解决方案1】:

FOR 循环中有一个错误。您访问[y,x] 指向错误。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define WIDTH 100
#define HEIGHT 50

#define SHADE " .*#@"

void print_display(char disp[WIDTH][HEIGHT])
{
    system("cls");

    for (int y = 0; y < WIDTH; y++) {
        for (int x = 0; x < HEIGHT; x++)
            printf("%c", SHADE[disp[y][x]]);

        printf("\n");
    }
}

int main()
{
    char disp[WIDTH][HEIGHT];
    memset(&disp, 1, WIDTH * HEIGHT);

    disp[49][0] = 4;

    print_display(disp);
    
    return 0;
}

【讨论】:

    【解决方案2】:

    您正在混淆尺寸。始终首先解决高度,然后是宽度。您得到“@”两次的原因是编译器将定义arr[ROWS][COLUMNS] 用作声明具有ROWS 元素的数组。这些元素中的每一个都是长度为 COLUMNS 的一维数组。因此,使用arr[r][c] 访问单个元素会找到第 r 个一维数组(第一个,即左 [] 操作),然后从中选择第 c 个元素。 p>

    你的数组定义是

    char disp[100][50]; 
    

    您的 disp[49][0] = 4; 设置第 50 个子数组中的第一个元素(即,在二维数组的中间,而不是您想象的接近末尾)。

    然后你用交换的索引索引数组:

    for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++)
                printf("%c", SHADE[disp[y][x]]);
    

    这里,y 只运行到 49,省略了二维数组 disp 中包含的一维数组元素的一半。相应地,x 将每个一维子数组中的元素过冲 2 倍。现在我们还可以看到为什么你会得到两次 @

    让我们考虑从disp 开始的线性内存。正如我们所说,赋值disp[49][0] = 4; 将一维子数组中索引 0 处的元素的值设置为索引 49。每个一维子数组的大小 SUB_LEN 为 50。因此第 50 个子数组从偏移量INDEX*SUB_LEN 开始,即49*50(第一个从偏移量0*50 开始,即0)。由于我们在该子数组的索引 0 处寻址单个字符,因此它正好位于该线性偏移处(数组中的第一个元素始终与数组具有相同的地址):<strong>49*50 = 2450.</strong> 这是典型的 C 编译器生成的为了计算一个元素在n维数组中的内存位置。

    但是,您正在索引disp 的各个子数组超出其末尾,访问属于下一个子数组的内存。这就是为什么你在线性偏移 2450 处遇到元素两次:在SHADE[49][0],正如预期的那样;但也在SHADE[48][50] — 因为 FIRST_INDEX*SUB_LEN + SECOND_INDEX = 2450 也是,FIRST_INDEX 为 48,SECOND_INDEX 为 50,SUB_LEN 为 50。请注意,50 的 SECOND_INDEX 是无效的,因为它超出了最后一个允许的索引子数组,即 49(对于 50 个元素,从 0 开始的索引)。使用该索引是因为第二个索引的 x 循环运行到 99。

    建议:

    • 严格按照从左到右的顺序排列索引。将声明和循环与实际索引对齐。
    • C 中的 n 维数组实际上是一维数组,其元素又是 (n-1) 维数组。 C 中 2 维矩阵的直观心智模型是一维数组的垂直堆栈,顶部索引为 0,其中每个子数组从左到右扩展:
    arr[3][4]:
    
            _________________
    arr[0]: |0,1|0,2|0,3|0,4|    <-- sub-array at index 0 with 4 elements
            -----------------
            _________________
    arr[1]: |1,1|1,2|1,3|1,4|    <-- ""        at index 1 ""
            -----------------
            _________________
    arr[2]: |2,1|2,2|2,3|2,4|    <-- ""        at index 2 ""
            -----------------
    

    因此,只要您有面向“列/行”的内容,请使用第一个索引来寻址行,使用第二个索引来寻址列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2022-01-07
      • 2023-04-02
      • 2011-05-07
      • 2021-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多