【问题标题】:can someone explain this short segment of C++ code, I can't make heads or tails of it有人能解释一下这段 C++ 代码吗,我无法理解它的正面或反面
【发布时间】:2013-10-13 14:51:37
【问题描述】:
#include <opcodes.h>
const char *getOpcodeName(
    uint8_t op
)
{
    #define OPCODE(x, y) if((0x##y)==op) return "OP_" #x;
        OPCODES
    #undef OPCODE
    return "OP_UNKNOWN";
}

此处代码链接:https://github.com/znort987/blockparser/blob/master/opcodes.cpp

这里是包含的opcodes.h的链接

我知道这只是一个格式奇怪的函数,但是,我想知道函数名称开头的 * 到底是什么意思。我认为它与指针有关?

另外,#undef#define 语句的有效性如何?任何一个后面都没有分号,其中一个似乎被定义为单行函数。 (0x##y) 是什么意思? return "OP_" #x 是什么意思?我以前从未遇到过这样的语法。

我想更认真地学习 C++,但是在查看代码时很难知道到底发生了什么。如何最有效地学习语法和规则?

【问题讨论】:

  • 函数返回一个字符串。这就是const char* 的意思。在这种情况下,它们是字符串文字。
  • 查看 C 或 C++ 中的 是什么。
  • 我认为字符串连接需要+ 符号? return "OP_" #x;如何返回字符串?
  • 这是给std::string的。在这种情况下,# 用于预处理器。所以OPCODE("foo", 1234)变成if((0x1234==op) return "OP_foo"
  • @bvpx String literals 如果它们紧随其后,则将它们连接起来 - "abc_" "def" 在编译期间变为 "abc_def"

标签: c++ function pointers syntax


【解决方案1】:

通过C++ preprocessor 运行您的代码,例如使用g++ -Wall -C -E opcodes.cpp &gt; opcodes.i 然后查看生成的opcodes.i 内部

#define 不是声明,而是preprocessor directive

OPCODES 被扩展为一些大块,特别是包含 OPCODE( NOP, 61) ,它会扩展为类似

if ((0x61)==op) return "OP_" "NOP";

两个字符串字面量合并为一个,"OP_NOP" 这里。

GCC 在其cpp preprocessor 上有很好的文档。阅读关于stringification(与OPCODE 宏的结尾#x; 一样的单#)和关于concatenation(与OPCODE 宏的## 一样的双##)。

【讨论】:

  • 这本质上是一种编写函数的高级方法,否则将有 100 个 if 语句?
  • 是的,但我不会称之为“高级方式”
  • 那你会怎么称呼它:)?顺便说一句,我还是不明白0x##y到底是什么意思。
  • 我刚刚在 GCC cpp 文档中添加了两章参考。
【解决方案2】:

简答:此函数将操作码转换为字符串。

* 与指针有关!事实上,这个函数返回一个const char * 类型。这是一个用于指向C-String 的字符缓冲区(在本例中)的指针。每个 C-String 实际上是一个带有“可读字符”(字母数字、一些重音符号、基本符号 + 一些东西)的缓冲区,后跟一个值为 0 的字节(或'\0')来指示字符串的结尾!

此函数将操作码(汇编指令)转换为可读字符串。所以程序员的意图是改造:

  • 0x01 -> OP_CODE1
  • 0x02 -> OP_CODE2
  • 0x03 -> OP_CODE3

代码的扩展版本是这样的:

const char *getOpcodeName( uint8_t op )
{
    if((0x01)==op) return "OP_X";
    if((0x02)==op) return "OP_Y";
    if((0x03)==op) return "OP_Z";
    ...
    if((0x??)==op) return "OP_?";
    return "OP_UNKNOWN";
}

编写了数百个 IF ......程序员决定创建宏

#define OPCODE(x, y) if((0x##y)==op) return "OP_" #x;

因此可以像这样轻松编写 OPCODES 表:

#define OPCODES \
OPCODE( 01, "X" ) \
OPCODE( 02, "Y" ) \
OPCODE( 03, "Z" ) \
...
OPCODE( ??, "?" )

操作码是识别处理器指令(汇编指令)的代码。真实指令示例(对于某些Intel processor)是:

  inc eax      ; opcode = 0x40
  pusha        ; opcode = 0x60
  nop          ; opcode = 0x90

所以你的桌子可能是:

#define OPCODES \
OPCODE( 40, "INCEAX" ) \
OPCODE( 60, "PUSHA" ) \
OPCODE( 90, "NOP" )

【讨论】:

    猜你喜欢
    • 2021-07-11
    • 2019-02-01
    • 1970-01-01
    • 2016-09-28
    • 2017-10-04
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多