用 C 构建 Pascal 编译器时的指针问题
我的编译器在词法分析方面遇到一些问题 我声明了以下指针
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: '=' : 左操作数必须是左值 关于 (line message='words';) : 错误 C2015:字符过多 持续的 关于 (line message='words';) : 错误 C2106: '=' : 左操作数必须 为左值
我不能那样使用指针吗? 你有什么建议吗?
I'm facing some problems on the lexical analysis of my compiler
I had declared the following pointer
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];
and then I tried to use it in a function
for (handle = 0; (&words[handle] != NULL); handle++)
{
message = &words[handle];
if (!strcmp(token, message))
message = 'words';
}
But I'm receiving the following errors when trying to execute:
regarding (line message = &words[handle];) : warning C4047: '=' : 'char [30]' differs in levels of indirection from 'char ** ' regarding (line message = &words[handle];) : error C2106: '=' : left operand must be l-value regarding (line message='words';) : error C2015: too many characters in constant regarding (line message='words';) : error C2106: '=' : left operand must be l-value
can't I work with pointers that way?
Do you have any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
三件事:
与号 (
&
) 是无关的。words[handle]
的类型是char *
,即字符串,因此您就拥有了所需的内容。 您不需要获取该char *
的地址。您不能使用
=
直接分配给message
,因为它是一个数组。 C 并不是一门非常奇特的语言。 您可以将message
更改为char *message
,因此它是一个指针而不是数组; 或者您可以使用strcpy(dst, src)
函数复制到其中,如下所示:strcpy(message, "words")
。您的
for
循环在words
数组中查找NULL
指针,以便它知道何时停止 - 但您没有数组中的NULL
! 您需要在末尾添加NULL
。 正如所写,只有常规字符串,因此循环永远不会找到它正在寻找的空指针,并且会进入未知的内存区域。希望有帮助!
Three things:
The ampersands (
&
) are extraneous. The type ofwords[handle]
ischar *
, i.e. a string, so right there you have what you need. You don't need to take the address of thatchar *
.You cannot directly assign to
message
with=
as it is an array. C is not a very fancy language. You can either changemessage
tochar *message
, so it is a pointer rather than an array; or you can use thestrcpy(dst, src)
function to copy to it, like so:strcpy(message, "words")
.Your
for
loop looks for aNULL
pointer in thewords
array so it knows when to stop--but you don't haveNULL
in the array! You need to addNULL
to the end. As written there are only regular strings so the loop will never find the null pointer it is looking for and will go charging off into uncharted zones of memory.Hope that helps!
你有很多错误:
words[handle]
You have a number of errors there:
words[handle]
您的代码存在很多问题。 首先,您应该将关键字数组声明为
const char *words[]
。 将字符串常量声明为char *
而不使用const
是一种不好的做法; 仅允许旧代码仍然可以编译。您不应在声明中指定数组大小 29,因为它很脆弱。 您应该只使用空括号并让编译器计算出数组大小。 您可以通过执行
sizeof(words)/sizeof(words[0])
来获取数组的大小,即使您从words
。接下来,您的 for 循环永远不会终止(尽管它几乎肯定会在某个时刻出现段错误)。 获取值的地址永远不会产生空指针,因此
&words[handle] != NULL
将始终为 true。 迭代循环的正确方法是仅计算条目数:message
被声明为字符数组。 数组不可分配,即它们不是左值。 如果要分配给数组,则必须使用诸如strcpy()
之类的方法将数据显式复制到其中(不推荐,除非在某些情况下,因为可能存在缓冲区溢出)、strncpy ()
、memcpy()
或strncpy_s()
(仅在 Windows 上可用)。但在这种情况下,您根本不需要数组——您只想分配一个指针。 将
message
声明为const char *
。 正确声明message
后,您可以这样做:在最后的语句中,您应该在
words
周围使用双引号,使其成为字符串常量。 单引号用于单字符常量(例如'A'
)。 尽管从技术上讲它们可以包含多个字符,但生成的整数常量的字节序是实现定义的,在这种情况下它们不是您想要的。我也不太确定你想用
message = "words";
行做什么。 如果您尝试使用words
变量执行一些巧妙的操作,请立即停止,它不会起作用。 C 没有任何类型的反射。You have a number of problems with your code. First of all, you should declare your array of keywords as
const char *words[]
. It's bad practice to declare string constants aschar *
, without theconst
; it's only allowed so that legacy code still compiles.You shouldn't specify the array size of 29 in the declaration, since it's fragile. You should just use empty brackets and let the compiler figure out the array size. You can get the size of the array by doing
sizeof(words)/sizeof(words[0])
, which will still be correct even if you add or delete elements fromwords
.Next, your
for
loop is never going to terminate (although it will almost assuredly segfault at some point). Taking the address of a value will never yield the null pointer, so&words[handle] != NULL
will always be true. The proper way to iterate through the loop is to just count the number of entries:message
is declared as an array of characters. Arrays aren't assignable, i.e. they are not lvalues. If you want to assign to an array, you have to explicitly copy data into it with something such asstrcpy()
(not recommended except in select cases, due to potential buffer overflows),strncpy()
,memcpy()
, orstrncpy_s()
(available only on Windows).In this case, though, you don't want an array at all -- you just want to assign a pointer. Declare
message
as aconst char *
instead. Withmessage
declared properly, you would do:In the final statement there, you should use double quotes around
words
to make it a string constant. Single quotes are for single character constants (e.g.'A'
). Although they technically can contain more than one character, the endianness of the resulting integer constant is implementation-defined, and they're not what you want in this case.I'm also not quite sure what you're trying to do with the
message = "words";
line. If you're trying to do some clever trick with thewords
variable, stop right now, it's not going to work. C doesn't have any sort of reflection.