【问题标题】:C++ function takes ints, but example shows text?C++ 函数采用整数,但示例显示文本?
【发布时间】:2014-06-21 14:03:47
【问题描述】:

这是一个让我感到困惑的 C++ 问题。 (很长一段时间后我正在刷新我的 C++)。我正在阅读这个例子here。有两个部分让我感到困惑:

第一部分:

在代码行中:

void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE )

WINDOW_AUTOSIZE 是一个输入,但据我所知,它不是一个 int。当我对这条线进行编码并运行时,它工作正常。我对该函数的输入字面意思是“WINDOW_AUTOSIZE”。我很困惑为什么会这样。 WINDOW_AUTOSIZE 如何是一个 int?

我的第二个问题是关于最后一行,他们说:

默认情况下,标志 == CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED

我对这究竟是如何/意味着什么感到困惑……我知道 |是按位或,但不清楚这到底是什么意思……

谢谢。

【问题讨论】:

  • 你认为WINDOW_AUTOSIZE 是什么?字符串由引号分隔。
  • @MattMcNabb 我不确定,因为我没有定义它。但它似乎存在于一个头文件中。

标签: c++ function int bit-manipulation


【解决方案1】:

用大写字母写的单词是常量。它们已在代码中的某处或在其他地方使用的标头中定义。常量可以代表数字、字符串等。这段代码中的常量显然属于int

CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED 只是常量所代表的int 值的按位或。这些是空间常量,其中仅设置了 int 的一位(所谓的 flags

假设,CV_WINDOW_AUTOSIZE 是 0x1,CV_WINDOW_KEEPRATIO 是 0x2。所以按位 OR-ing 将导致 0x3。然后被调用的函数可以通过 AND 操作检查设置了哪个标志。

【讨论】:

  • 啊,谢谢!所以你的意思是它们被定义为“#define CV_WINDOW_AUTOSIZE 1”?
  • 是的,通常你会使用十六进制数字,它更容易。 (例如 0x8 是 1000 二进制)
  • @addy2012 不是因为它更容易,而是因为您可以将单个二进制数字组合为掩码。
  • @JosephMansfield 所以结论是肯定的,因为它比十进制更容易(除非知道二的所有幂)
  • 是的,这正是我的意思;)
【解决方案2】:

我对该函数的输入字面意思是“WINDOW_AUTOSIZE”

是的,WINDOW_AUTOSIZE 实际上是一个整数; 只需看看它是int 函数参数的默认参数这一事实。如果不是int

,它将无法编译
// it might have been defined like this
#define WINDOW_AUTOSIZE 23434 // some number just for example
// or like this
const int WINDOW_AUTOSIZE = 34234;

至于第二个问题按位ORing 表示对应的整数值中的所有位都是ORed 在一起的,所以举个例子

CV_WINDOW_AUTOSIZE   = 0x0010 
CV_WINDOW_KEEPRATIO  = 0x0100
CV_GUI_EXPANDED      = 0x1100

然后相应的操作将给出一个整数值,每个位都等于每个位置的OR 的结果

CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED = 

0x0010 
0x0100
0x1100
------
0x1110

关于位标志的使用

考虑以下情况:您有一个带 4 个键的键盘

Ctrl、Alt、Del、Shift

你需要多少个常量来定义这个键盘可以打开的所有状态?那么让我们列举一下状态

  1. 按下所有 4 个键:1 个常量

  2. 按下 3 个键:需要 (4 x 3) 个常量 = 4 个常量

    (4 by 3) = 4! / ( (4-3)! * 3! ) = 4 
    
  3. 按下了 2 个键:(4 x 2)= 6 个常量

  4. 1 个键被按下:4 个常量(键的名称)

  5. 未按下任何键:1 个常量

所以总结一下,你会定义:

1 + 4 + 6 + 4 + 1 = 16 constants

如果我告诉你只需要 4 个不同的常量,每个只有一位 ON 怎么办?

#define CtrlK  0x0001
#define AltK   0x0010
#define DelK   0x0100
#define ShiftK 0x1000

那么键盘的任何状态都可以通过上面的组合来表达:假设你想表达状态Shift键和Del键被按下。然后就是

CtrlK | DelK

你拥有的组合越多,这项技术的回报就越大。

当然(也许您可以在 bitflags 上看到参考)用户代码可以探测一个整数值以查看哪些位被打开。

【讨论】:

  • 谢谢,这很有意义。我想我不明白的最后一件事是为什么他们默认设置了“标志”,是已经定义的三件事的按位或......在这里看不到目的。
  • @Learnaholic Bitflag 机制在此上下文中用于防止组合爆炸。所以你有例如你的初始状态,表示为位标志,任何状态都可以表示为这些(相互排除的)状态的组合。这就像说“键盘的默认配置将是 NUM_LOCK=ON 和 (&) CAPS_LOCK=ON”所以INITIAL_STATE = NUM_LOCK & CAPS_LOCK。这样可以避免您定义另一个状态
  • 我在这里很困惑。例如,在您的示例中,ORing 的结果将是“0x1110”。好的,很好,但是 实际上 对应的是什么状态?你是说这种状态是我可以同时自动调整大小、保持比例和 gui 扩展?
  • @Learnaholic 是的。那讲得通。阅读标志的描述。
  • @Learnaholic 我将在答案中进行编辑,因为它会有点大。给我一分钟
【解决方案3】:

我相信 WINDOW_AUTOSIZE 不是字符串或文本。它将是一个常量或#defined 预处理器常量。所以 int 数据类型可以接受。请检查源代码中 WINDOW_AUTOSIZE 的定义。 另请注意,我们可以将具有“char”、“enum”数据类型的变量传递给接受 int 的函数。到 int 的转换将在内部发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2016-05-22
    • 2021-12-26
    • 2018-08-06
    相关资源
    最近更新 更多