【问题标题】:C - Signed and Unsigned integerC - 有符号和无符号整数
【发布时间】:2014-02-24 16:06:01
【问题描述】:

我正在研究 C,因为我需要将 ctypes 库导入 python 以允许键盘控制。我正在尝试了解以下代码的工作原理:

import ctypes
import time

SendInput = ctypes.windll.user32.SendInput

# C struct redefinitions 
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
            ("ii", Input_I)]

# Actuals Functions

def PressKey(hexKeyCode):

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0x0002, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))


def AltTab():
    '''
    Press Alt+Tab and hold Alt key for 2 seconds in order to see the overlay
    '''

    PressKey(0x012) #Alt
    PressKey(0x09) #Tab
    ReleaseKey(0x09) #~Tab

    time.sleep(2)       
    ReleaseKey(0x012) #~Alt


if __name__ =="__main__":

    AltTab()

我不理解的部分与有符号和无符号整数有关:

int 的范围是 -32768 - 32767

unsigned int 的范围是 0 - 65535

我读到:“一个 2 字节数字可以显示的数字的总范围是 2^16,因为你有 16 位可以表示一个数字。2^16 与 65536 相同,因为我们计算从 0 开始,与 0 - 65535 相同。这显然与 unsigned int 的值相匹配,因此您可以看到这就是该类型的操作方式。”

这似乎有道理,但有一点我不明白:

1 字节 = 8 位 2 字节 = 16 位

那么为什么将 2 字节数称为 2^16 而不是 2^8?

【问题讨论】:

  • 因为它有 16 位。每个位可以保存 2 个值,因此 2^16 个可能的数字有 2 个字节
  • 啊,当然,谢谢。
  • 注意:对于每个 C,byte 至少 8 位。
  • 你在使用古老的 DOS 编译器吗?或者你正在为一些嵌入式系统编译?现代 CPU 架构有 32 位 int,可以表示 2^32 个不同的值,无符号的范围是 0 到 2^32-1,有符号的 int 的范围是 -2^31 到 2^31-1

标签: python c++ c ctypes unsigned-integer


【解决方案1】:

我不理解的部分与有符号和无符号整数有关:
int 的范围是 -32768 - 32767
unsigned int 的范围是 0 - 65535

仅供参考:int 的大小(以及它可以容纳的值)实际上可能取决于您的环境。确定整数变量类型(至少从 C99 开始)的大小(位宽)的确定方法是使用在 stdint.h 中定义的类型之一,在那里你会发现像 int8_t 和 @987654324 这样的显式类型@。通常不需要,但对于学习 C 来说只是一个有趣的事实。

不管怎样,关于你的问题。那么“为什么将 2 字节数称为 2^16 而不是 2^8”

16 表示位数。在 2 个字节中有 16 位。

2 表示每个位的可能性数量。 (0 或 1)

所以 2 个字节可以表示 2^16th 个数字,从 00000000000000002 到 11111111111111112

【讨论】:

  • stdint.h 不会告诉您有关int 大小的任何信息。你想要limits.h(在极少数情况下你想要使用stdint.h 中的类型——也许在某些嵌入式软件中,但除此之外呢?)
  • @James 请详细说明。 limits.h 为您提供了定义类型中最大值和最小值的宏(例如 INT_MININT_MAX)。然而,确切的宽度(位数)整数类型在stdint.h 中定义;例如 int8_t 保证 8 位有符号类型。我是说int 不能保证在每个平台上都是特定宽度,要获得保证宽度,必须使用stdint.h 中的类型。您是说这些信息不正确吗?
  • 您说stdint.h 是一种了解变量类型大小的方法(例如int)。那是错误的。而且您通常不想在日常代码中使用stdint.h 中的类型;关于您使用它们的唯一情况是与外部事物交互时,即使那样,通常也仅在供应商提供许多其他保证的嵌入式软件中。
  • @James - 抱歉,如果事情是这样的,那不是我想要的。我稍微改写了一下,希望能让我想说的更清楚,以及为什么。
【解决方案2】:

一个 2 字节的数字有 16 位(2 x 8 位)。告诉您可以由给定位数表示的最高无符号数的函数是2^n-1,因此例如 8 位可以表示数字 0 到 255,16 位可以表示数字 0 到 65,535,等等。

原因很简单。考虑第一个 不能 用(比如说)16 位表示的数字。那将是 1 和 16 个零,因为这是具有 17 位数字的最小二进制数。那是2^16。所以可以用这种方式表示的最大数字是2^16-1

另请注意,C 中 int 的大小取决于您的 C 编译器。它可能并不总是 2 个字节长。

【讨论】:

    【解决方案3】:

    2 字节数包含 16 位。它们中的每一个都可以保存 2 个值,因此它可以生成 2^16 个可能的数字,这是您可以通过它编码的不同信息的数量。

    【讨论】:

      猜你喜欢
      • 2015-01-24
      • 2013-10-02
      • 2015-02-17
      • 1970-01-01
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 2013-10-27
      相关资源
      最近更新 更多