在C中构建Pascal编译器时指针的问题

时间:2009-06-24 01:29:02

标签: compiler-construction pascal lexical

我在编译器的词法分析方面遇到了一些问题 我已经宣布了以下指针

char *words[29]={
        "program",
        "label",
        "integer",
        "word",
        "char",
        "byte",
        "shortint",
        "logint",
        "real",
        "single",
        "double",
        "string",
        "boolean",
        "var",
        "procedure",
        "function",
        "begin",
        "end",
        "if",
        "then",
        "else",
        "or",
        "and",
        "div",
        "not",
        "do",
        "while",
        "mod"
};
char message[30];

然后我尝试在函数中使用它

            for(handle=0;(&words[handle] != NULL);handle++)
            {
                message = &words[handle];
                if(!strcmp(token,message))
                    message='words';
            }

但是我在尝试执行时遇到以下错误:

  

关于(行消息=   & words [handle];):警告C4047:'='   :'char [30]'的等级不同   间接来自'char **'

     

关于(行消息=   & words [handle];):错误C2106:'=':   左操作数必须是l值

     

关于(line message ='words';):   错误C2015:中的字符太多了   恒定

     

关于(line message ='words';):   错误C2106:'=':左操作数必须   是l值

我不能用指针那样工作吗? 你有什么建议吗?

3 个答案:

答案 0 :(得分:3)

三件事:

  1. &符号(&)是无关紧要的。 words[handle]的类型是char *,即一个字符串,所以就在那里你有你需要的东西。您无需使用char *

  2. 的地址
  3. 您无法使用message直接分配给=,因为它是一个数组。 C不是一种非常奇特的语言。您可以将message更改为char *message,因此它是指针而不是数组;或者你可以使用strcpy(dst, src)功能复制到它,如下所示:strcpy(message, "words")

  4. 您的for循环在NULL数组中查找words指针,以便它知道何时停止 - 但您没有NULL阵列!您需要将NULL添加到最后。如上所述,只有常规字符串,因此循环永远不会找到它正在寻找的空指针,并将充电到未知的内存区域。

  5. 希望有所帮助!

答案 1 :(得分:3)

你有很多错误:

  • 代替& words [句柄],使用 字[手柄]
  • 你想通过message ='words'做什么?这里至少有3个错误:字符串使用双引号,而不是单引号;消息是一个常数,你无法改变它;要复制字符串,您需要使用strcpy(),而不仅仅是= operator
  • 如果字符串相等,
  • strcmp()返回0;你需要扭转你的逻辑
  • 您忘记在数组末尾包含NULL

答案 2 :(得分:2)

您的代码存在许多问题。首先,您应该将关键字数组声明为const char *words[]。将字符串常量声明为char *而不使用const是不好的做法;它只允许遗留代码编译。

您不应在声明中指定数组大小29,因为它很脆弱。你应该只使用空括号,让编译器找出数组大小。您可以通过sizeof(words)/sizeof(words[0])获取数组的大小,即使您添加或删除words中的元素,这仍然是正确的。

接下来,你的for循环永远不会终止(虽然它在某些时候几乎肯定会出现段错误)。获取值的地址永远不会产生空指针,因此&words[handle] != NULL将始终为true。迭代循环的正确方法是只计算条目数:

for(handle = 0; handle < sizeof(words)/sizeof(words[0]); handle++)

message被声明为一个字符数组。数组不可分配,即它们不是左值。如果要分配给数组,则必须使用诸如strcpy()之类的内容将数据显式复制到其中(不建议除非在特定情况下,由于潜在的缓冲区溢出),strncpy(),{{1 },或memcpy()(仅适用于Windows)。

在这种情况下,您根本不需要数组 - 您只想分配指针。将strncpy_s()声明为message。正确声明const char *后,您可以执行以下操作:

message

在那里的最后声明中,你应该在const char *message; ... message = words[handle]; if(!strcmp(token, message)) message = "words"; 周围使用双引号使它成为一个字符串常量。单引号用于单个字符常量(例如words)。虽然它们在技术上可以包含多个字符,但结果整数常量的字节顺序是实现定义的,在这种情况下它们不是您想要的。

我也不太清楚你要对'A'行做些什么。如果你试图用message = "words";变量做一些聪明的技巧,现在就停止,它不会起作用。 C没有任何反思。