【问题标题】:Why does this code only work for specific numbers?为什么此代码仅适用于特定数字?
【发布时间】:2020-11-09 17:56:24
【问题描述】:

我目前正在尝试解决 Hackerrank 上的一个问题,但我不太明白为什么我的解决方案不起作用。任务是打印'#' 的右对齐阶梯。我试过这个 C 代码:

void staircase(int n) {
    char stair[n];
    memset(stair, ' ', n *(sizeof(char)));

    for(int i = n-1; i>= 0; i--)
    {
        stair[i] = '#';
        printf("%s\n", stair);
    }
}

如果 n = 8 或更低,它可以正常工作,但如果 n = 9 或更高,它仍然会打印楼梯,但在每行的末尾都有一些垃圾符号。我只是不太明白为什么这适用于某些数字而不适用于其他数字。字符串在 C 中的工作方式是否有问题?我知道我对这个问题的解决方案通常可能不是最有效的,但对我来说,这是为了理解为什么这段特定的代码不能正常工作。

【问题讨论】:

  • 请包含输出
  • 顺便说一句,sizeof(char) 根据定义始终为 1。
  • sizeof(char) 的定义是 1。你应该删除它或者写一个更有用的sizeof(stair[0])。更好的是,您应该使用 sizeof(stair) 一次获得整个数组的大小。
  • 可变大小的数组在 C 中被认为是不好的做法,您应该使用以下内容动态分配内存:char *stair = (char*) malloc((n+1)*sizeof(char)) 在其中为您的 n 个字符和字符串结尾的字符分配内存 \0。你应该在退出函数之前释放内存free(stair)

标签: c loops for-loop char c-strings


【解决方案1】:

这个数组

char stair[n];

不包含字符串,因为它被初始化为

memset(stair, ' ', n *(sizeof(char)));

所以函数调用了未定义的行为。

要么你需要像这样定义数组

char stair[n+1];

然后写

memset(stair, ' ', n *(sizeof(char)));
stair[n] = '\0';

或者只是改变printf的调用方式如下

printf("%.*s\n", n, stair);

注意您使用的声明字符数组的方法效率不高。您可以不使用数组来完成相同的任务。

【讨论】:

    【解决方案2】:

    当你使用

    memset(stair, ' ', n *(sizeof(char)));
    

    空白字符' ' 不等于空字符'\0'(您可能认为它是)。这反过来意味着stair 的数组元素未设置为0(这将确定字符串结束)。

    它们都被初始化为包含空格,但实际上数组内部根本没有指示符,它决定了字符串在哪里结束,当数组被字符串操作函数寻址时。

    此类操作首先遇到特定数量的 '#' 主题标签,然后仅遇到空格字符,但没有空字符。

    打印字符串

    printf("%s\n", stair);
    

    然后是undefined behavior,因为没有分隔符来确定字符串的结尾。

    使用

    memset(stair, '\0', sizeof(char) * n);
    

    memset(stair, 0, sizeof(char) * n);
    

    改为。

    作为旁注,分配数组可能不是最有效的方法。最好使用一种算法,该算法对'#' 使用单个字符常量,并且打印会增加每次迭代在输出中显示的它的数量。


    回答您的疑虑:

    如果 n = 8 或更低,它可以正常工作,但如果 n = 9 或更高,它仍然会打印楼梯,但在每行的末尾都有一些垃圾符号。我只是不太明白为什么这适用于某些数字而不适用于其他数字。

    它与n 的值无关。未定义的行为不需要提供错误的结果。事实上,所有您的执行都受到未定义行为的影响,无论它是否显示了预期的输出。


    此外,可变长度数组 (VLA),如stair,并非所有实现都支持,仅对符合 C99 的实现强制。它们仅在符合其他标准时由非标准编译器扩展提供。可以改用malloc() 以使您的程序更便携。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-02
      • 2015-07-18
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多