我正在阅读source code of the Lua最近学习编程语言,发现一些约定不清楚或令人困惑。例如this file中的str_reverse函数。它被认为是干净的代码和可理解的 C 代码吗?
static int str_reverse (lua_State *L) {
size_t l, i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
char *p = luaL_buffinitsize(L, &b, l);
for (i = 0; i < l; i++)
p[i] = s[l - i - 1];
luaL_pushresultsize(&b, l);
return 1;
}
在这些行中:
char *p = luaL_buffinitsize(L, &b, l);
for (i = 0; i < l; i++)
p[i] = s[l - i - 1];
*p 用于存储字符串反转后的值。之后,我没有看到它在其他地方使用。然后查看char *p = luaL_buffinitsize(L, &b, l);
,它表明 *p 是 luaL_Buffer b;
的属性,现在可以理解为什么不再使用 *p 了,因为在下一行中,b
正在使用中
此外,在这一行 const char *s = luaL_checklstring(L, 1, &l);
,这个luaL_checklstring
函数返回*s
,而且还将字符串的长度(从 L 获得)分配给 size_t l
多变的。所以这个函数不仅返回 1 个变量,而且还改变 1 个变量。
最佳答案
当你不知道某件事是如何工作的时,一个合理的结论是它可能写得不好。不过,上面的代码是可读的。我对 lua 一无所知,对 C 也不太了解,但我能够解读发生了什么。
可能对您有帮助的第一件事是了解如何调用 str_reverse
,启动解释器:
> str = "foo" /* create a string in a lua state */
> string.reverse(str) /* indirectly invokes str_reverse */
oof /* result */
str_reverse
所做的第一件事是调用 luaL_checklstring
,这是 lua_tolstring
周围的包装函数这增加了错误检查。在对话框中:
str_reverse
对 luaL_checklstring
说:
“嘿,我需要一个字符串 - 给我地址(将其存储在 s
中),我还需要长度(将其存储在 l
中)。”
luaL_checklstring
说:“是的,一切都很好 - 开始吧!”
你看,C 语言需要知道所有内容的大小,以便它可以分配适当的内存量。由于 str_reverse
需要为反转的字符串分配内存(更准确地说,luaL_Buffer b
如果它不够大以容纳字符串,则需要调整大小),它告诉 luaL_checklstring
也给出长度。如果 str_reverse
不关心长度,则将传递 NULL
而不是 l
。这就是 Lua API 的设计方式 - 对我来说似乎是可读的。
p
不存储字符串的值 - 反转的字符串作为成员存储在 b
中。 p
基本上是一个快捷方式,请考虑以下事项:
/* disregard the pointer returned by buffinitsize */
luaL_buffinitsize(L, &b, l);
for (i = 0; i < l; i++)
b->b[i] = s[l - i - 1];
上面的代码应该工作相同。但现在,luaL_Buffer
的血腥细节被暴露了……不太好。
您需要阅读指针。如果你不懂指针,你就永远无法完全理解 C,就像没有脚走路一样。
无论如何,你被否决了这么多,这很糟糕,这可能是你为你的问题选择的标题 - 听起来你在抨击 Lua。除此之外,你的问题似乎是真实的 - 祝你好运,并在阅读他人代码的冒险中享受乐趣!
关于c - Lua源代码是用干净的代码编写的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53512380/