我在编译器的词法分析方面遇到了一些问题 我已经宣布了以下指针
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值
我不能用指针那样工作吗? 你有什么建议吗?
答案 0 :(得分:3)
三件事:
&符号(&
)是无关紧要的。 words[handle]
的类型是char *
,即一个字符串,所以就在那里你有你需要的东西。您无需使用char *
。
您无法使用message
直接分配给=
,因为它是一个数组。 C不是一种非常奇特的语言。您可以将message
更改为char *message
,因此它是指针而不是数组;或者你可以使用strcpy(dst, src)
功能复制到它,如下所示:strcpy(message, "words")
。
您的for
循环在NULL
数组中查找words
指针,以便它知道何时停止 - 但您没有NULL
阵列!您需要将NULL
添加到最后。如上所述,只有常规字符串,因此循环永远不会找到它正在寻找的空指针,并将充电到未知的内存区域。
希望有所帮助!
答案 1 :(得分:3)
你有很多错误:
答案 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没有任何反思。