这里有一个正式的语法脑筋急转弯(可能:P)
我很确定在有效的C程序中没有出现字符序列=>的上下文(显然在字符串中除外)。然而,我无法向自己证明这一点。你能不能:
描述一种方法,我可以使用它来确定一个有效的C程序(字符串/注释之外)中是否可能使用任意字符序列。更好的解决方案需要更少的直觉。
指出一个能做到这一点的程序。我有一种微弱的直觉,这是不可判定的,但如果我错了,那就太好了。
为了让你的思想发挥作用,我一直在考虑的其他组合:
:-(b?1:-1),!?不要这样想,?!(b?!x:y),<<<不要这样想。
如果有人关心:我很感兴趣,因为我正在创建一个小的自定义C预处理器,以供个人使用,并希望不必为它解析任何C。最后,我可能会让我的代币以$开头,或者可能是一个反引号,但我仍然觉得这个问题很有趣,可以发布。
编辑:有人很快指出,头名称几乎没有限制,所以让我修改一下,我对非预处理器代码特别感兴趣,或者,我们可以将<>#include <...>中的字符视为字符串文字。
重新编辑:我想宏/预处理器指令比这个问题好,不管我怎么问:P,但是如果有人能回答纯(读:非宏)C代码的问题,我认为这是一个有趣的问题。

最佳答案

除了所有其他的问题外,还有很多涉及宏的情况。
宏扩展的参数不需要在语法上正确,尽管在扩展的上下文中它们当然需要在语法上正确。但是,它们可能永远不会扩展:

#include <errno.h>

#define S_(a) #a
#define _(a,cosmetic,c) [a]=#a" - "S_(c)
const char* err_names[] = {
  _(EAGAIN,  =>,Resource temporarily unavailable),
  _(EINTR,   =>,Interrupted system call),
  _(ENOENT,  =>,No such file or directory),
  _(ENOTDIR, =>,Not a directory),
  _(EPERM,   =>,Operation not permitted),
  _(ESRCH,   =>,No such process),
};
#undef _

const int nerr = sizeof(err_names)/sizeof(err_names[0]);

或者,它们可以使用,但形式是丝状的:
#define _(a,b,c) [a]=#a" "S_(b)" "S_(c)

注:为什么#aS_(c)?因为EAGAIN和friends是宏,而不是常量,在这种情况下,我们不希望它们在序列化之前被扩展。

关于c - C语法:在任何上下文中均有效的字符组合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25648066/

10-11 22:54
查看更多