【问题标题】:Why does the GCC Compiler allows us to declare zero length strings (directly) and negative length strings (indirectly)?为什么 GCC 编译器允许我们(直接)声明零长度字符串和(间接)负长度字符串?
【发布时间】:2018-08-21 09:50:56
【问题描述】:
/*implementation of strrev i.e. string reverse function*/

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

/*length of the string i.e. cells in the string*/
static const unsigned int MAX_LENGTH = 100;
//static const int MAX_LENGTH = -100;

/*reverses the string*/
void reverseString(char[]);
/*swaps the elements in the cells of a string*/
void swap(char[], int, int);

/*runs the program*/
int main()
{
    char string[MAX_LENGTH];
    //char string[0];  //no error!
    //char string[-1]; //error! 

    gets(string);
    reverseString(string);
    printf("\n%s", string);

    return 0;
}

void reverseString(char string[])
{
    int i;
    for(i = 0; i < (strlen(string) / 2); i++)
    {
        swap(string, i, (strlen(string) - 1 - i));
    }
}

void swap(char string[], int i, int j)
{
    int temp = string[i];
    string[i] = string[j];
    string[j] = temp;
}

看主函数。如果替换第一行“char string[MAX_LENGTH];”使用“char string[-1];”,编译器会显示错误。 (因为负长度的字符串没有意义)。但是,如果将此代码的第 7 行(我声明 const MAX_LENGTH)替换为第 8 行中用 cmets 编写的代码(其中 MAX_LENGTH 分配了 -ve 值),则不会出现编译错误。为什么?

另外,为什么声明零长度字符串没有错误。零长度字符串如何对编译器有意义但对负长度字符串没有意义?

【问题讨论】:

  • 即使你没有得到编译错误,它仍然是未定义的行为。
  • gets 已弃用。
  • @Inrin 你是对的。我从旧书上学到的。
  • 您应该查看 C99 和/或 C11 标准。例如for (int i=0... 就更好了恕我直言。

标签: c string gcc


【解决方案1】:

因为这不是一回事。

  • 在第一种情况下,您要定义一个数组,使用固定的编译时大小
  • 在第二种情况下,您要定义一个可变长度数组或VLA。

编译器在第二种情况下在运行时进行分配(使用这个-100 值不会很好地结束),因为const 在C 中并不是一个真正的常量,它只是告诉编译器你不会改变这个值(并且还允许一些优化)。所以结果是未定义的行为(更多:Declaring an array of negative length

如果您想要相同的行为,请使用 #define

 #define MAX_LENGTH -100    // will raise a compilation error

或者如 cmets 中所建议的,一个枚举常量

enum { MAX_LENGTH = -100 };    // will raise a compilation error

如果您想保护您的声明,请使用assert

assert(MAX_LENGTH > 0);
char string[MAX_LENGTH];

至于零长度元素,无需重复已经回答的内容:What's the need of array with zero elements?(简而言之,在结构的末尾可以有不同的长度很有用)

【讨论】:

  • 您也可以考虑解释二进制补码,以及为什么将-1 分配给unigned 可能无法得到您想要的。
  • true 但 OP 似乎知道:在评论的问题代码中:static const int MAX_LENGTH = -100: unsigned 消失了。否则,该值将是 INT_MAX-100+1 可能对于自动记忆来说太大了!
  • 使用#define 的替代方法是使用枚举常量。
猜你喜欢
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多