【问题标题】:Accessing the last element on a row in a 2D array that is in a structure访问结构中二维数组中一行的最后一个元素
【发布时间】:2021-03-04 19:06:40
【问题描述】:

我正在尝试访问结构内二维数组每一行的最后一个元素。我正在尝试确定特定字符是否在该位置,但我不知道如何访问该特定元素。

我的未完成代码:

typedef struct node {
   char grid[MAXGRIDHW][MAXGRIDHW];
   int height;
   int width;
   int parent;
} Node;

bool emptyEnd (Node *b)
{
   int x, y;
   char lastEle = ;

   for (y = 0; y <= b->height; y++) {
      for (x = 0; x <= b->width; x++) {
         if (lastEle == '-') {
            return true;
         } else {
            return false;
         }
      }
   }
}

【问题讨论】:

  • C 循环运行 for (y = 0; y &lt; b-&gt;height; y++),使用 &lt; 而不是 &lt;=。 99% 的情况下,使用 &lt;= 而不是 &lt; 是一个错误。
  • 这个char lastEle = ;应该报错了,你编译了吗?
  • 另请注意,在外循环的第一次迭代中,您在内循环的第一次迭代中无条件地从函数返回——使循环完全没有必要。您可能希望保留return true; 并完全删除else 子句,在循环体后添加return false;
  • 如果我需要循环运行直到它等于数组的高度怎么办?
  • 数组中有效元素的索引为 0, 1, ... MAXGRIDHW-1;访问索引 MAXGRIDHW 正在越界访问数组,导致未定义的行为。这就是为什么&lt;= 是错误的。

标签: arrays c structure


【解决方案1】:

如 cmets 中所述:

  • 在 C 中,for 循环通常运行 for (int i = 0; i &lt; limit; i++),因此可以访问数组的所有 limit 元素,而无需超出数组的边界(这会导致未定义的行为)。

  • 请记住,如果您有一个数组 SomeType array[10];,则有效索引的值为 0..9; array[10] 不是您可以合法访问的元素(尽管您可以形成地址 &amp;array[10] 并与之进行比较)。

  • lastEle 的代码是无效的 C。

  • 鉴于“如果最后一列值与指定的字符匹配,函数应返回 true”的要求,您的双循环是不必要的。您只需要检查每一行中的一个字符,因此迭代行数就足够了。

  • 在外部循环的第一次迭代中,原始代码在内部循环的第一次迭代中无条件地从函数返回——使得循环完全没有必要。您需要保留return true; 并完全删除else 子句,在循环体之后添加return false;

  • 原始代码中的内部循环是不必要的。每一行只有一个最后一个字符,因此不需要为行中的每个字符位置检查该行中的最后一个字符是否与固定值匹配。

这是有效的代码。它不假定网格由字符串组成——字节 (char) 数组不一定以空值结尾。它不假定网格最大程度地满了(heightwidth 或两者都可以小于MAXGRIDHW)。搜索功能由要搜索的字符参数化,以便可以测试代码搜索不同的字符。我保留了结构的parent 元素,即使它在代码中没有任何用处。我使用了 C99 指定的初始化程序和 C99 风格的 for 循环,其中循环变量在循环控制中定义。我包含了print_grid() 函数,因为我希望能够看到搜索是正确的。

#include <stdbool.h>
#include <stdio.h>

enum { MAXGRIDHW = 6 };

typedef struct node
{
    char grid[MAXGRIDHW][MAXGRIDHW];
    int height;
    int width;
    int parent;
} Node;

static bool emptyEnd(Node *b, char c)
{
    for (int y = 0; y < b->height; y++)
    {
        if (b->grid[y][b->width - 1] == c)
            return true;
    }
    return false;
}

static void print_grid(const char *tag, const Node *np)
{
    printf("%s: P = %d, H = %d, W = %d\n", tag, np->parent, np->height, np->width);
    for (int r = 0; r < np->height; r++)
    {
        for (int c = 0; c < np->width; c++)
            putchar(np->grid[r][c]);
        putchar('\n');
    }
}

int main(void)
{
    Node n =
    {
        .parent = 0, .width = 5, .height = 4,
        .grid =
        {
            { 'a', 'b', 'c', 'd', 'e' },
            { 'b', 'c', 'd', 'x', 'z' },
            { 'p', 'p', '*', '*', '-' },
            { '@', '@', '@', '!', '-' },
        },
    };
    char test[] = "-eA";

    print_grid("Test Grid", &n);

    for (int i = 0; test[i] != '\0'; i++)
    {
        if (emptyEnd(&n, test[i]))
            printf("At least one last character is '%c'\n", test[i]);
        else
            printf("Not even one last character is '%c'\n", test[i]);
    }
    return 0;
}

程序的输出是:

Test Grid: P = 0, H = 4, W = 5
abcde
bcdxz
pp**-
@@@!-
At least one last character is '-'
At least one last character is 'e'
Not even one last character is 'A'

【讨论】:

  • 谢谢您,我采用了您的 emptyEnd 函数版本,但在函数内部定义了我要查找的字符并在其上完成了此测试 assert(emptyEndOfShelf(&shelf1[1]) ==真的);使用包含在结构中的网格(我使用 memcpy 将数组复制到结构中),但是断言失败,尽管最后一列中有空格。您的代码和我的代码之间的唯一区别是 char 是硬连线到函数中的: char testArr1[3][4] = {{"..."}, {"..."}, {"..." }};
  • 我需要查看您的代码才能有机会对其进行调试。如果需要,您可以给我发电子邮件 - 请查看我的个人资料,并在主题行中包含“Stack Overflow”,并在正文中包含问题 URL。
【解决方案2】:

试试这个:

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXGRIDHW 4

typedef struct node {
   char grid[MAXGRIDHW][MAXGRIDHW];
   int height;
   int width;
   int parent;
} Node;

_Bool emptyEnd (Node *b)
{
   int x, y;
   char lastEle = b->grid[MAXGRIDHW-1][MAXGRIDHW-1];
   printf("%c\n", lastEle);  //====> 'p'
   return (lastEle == '-');  
}

int main() {
    struct node n = { .height = 100, .width  = 100 };
    char grid[MAXGRIDHW][MAXGRIDHW] = {{'a', 'b', 'c', 'd'},
                                      {'e', 'f', 'g', 'h'},
                                      {'i', 'j', 'k', 'l'},
                                      {'m', 'n', 'o', 'p'}};
    memcpy(n.grid, grid, sizeof(char) * MAXGRIDHW * MAXGRIDHW);
    printf("%d\n", emptyEnd(&n)); //===> false
}

【讨论】:

    【解决方案3】:

    struct 中是否存在二维数组真的很重要吗?

    如果稍加修改,您可以使下面的程序工作。

    不要传递结构变量,而是在结构内部传递一个数组。

    希望以下内容能满足您的要求。

    #define MAX_NUM_OF_LINES 3
    #define MAX_NUM_OF_CHARS_PER_LINE 15
    
    bool getTheLastChar(char *str);
    
    int main()
    {
        char Arr[MAX_NUM_OF_LINES][MAX_NUM_OF_CHARS_PER_LINE] = {"ABC-","DEFG","HIJ-"};
        int i;
        for(i = 0; i<MAX_NUM_OF_LINES; i++)
        {
            if(true == getTheLastChar(Arr[i]))
                printf("there is a - at last in %s\n", Arr[i]);
        }
       return 0;
    }
    
    bool getTheLastChar(char *str)
    {
        bool retVal = false;
         
        if( str[strlen(str)-1] == '-')
           retVal = true;
         
        return retVal;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多