一次设置后,二维数组中的值出现两次

时间:2020-10-12 09:19:16

标签: arrays c multidimensional-array

我有一个包含chars的2D数组,但是当我更改其中一个值时,它会在数组中两个不同点上变化。

我当前的代码是:

#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;
}

运行此代码将为我带来帮助:

....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
..................................................@.................................................
@...................................................................................................
但是它的末尾包含两个@,它应该只有一个。

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

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

您正在混淆尺寸。始终首先处理高度,然后处理宽度。两次出现“ @”的原因是编译器将定义arr[ROWS][COLUMNS]声明为包含ROWS元素的数组。这些元素中的每个元素都是长度为COLUMNS的一维数组。因此,使用arr[r][c]访问单个元素将找到第r个一维数组(第一个,即左[]运算),然后从该数组中选择第c个元素

您的数组定义是

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中包含的1-D数组元素的一半。相应地,x比每个一维子数组中的元素超出2倍。现在,我们还可以看到为什么两次获得@的原因。

让我们考虑从disp开始的线性存储器。如我们所说,赋值disp[49][0] = 4;将元素1-D子数组中索引0的值设置为索引49。每个1-D子数组的大小SUB_LEN为50。第50个子数组因此,数组从偏移量INDEX*SUB_LEN开始,即49*50(第一个数组从偏移量0*50开始,即0)。由于我们在该子数组的索引0处寻址单个字符,因此它正好位于线性偏移量(数组中的第一个元素始终与数组具有相同的地址):49*50 = 2450.这就是典型的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。请注意,SECOND_INDEX为50是无效的,因为它比上一个允许的索引大子数组的大小,即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 ""
        -----------------

因此,只要您有面向“列/行”的内容,就可以使用第一个索引处理行,第二个索引处理列。