【问题标题】:Some parts of this C code doesn't make sense for me这段 C 代码的某些部分对我来说没有意义
【发布时间】:2015-08-27 11:26:21
【问题描述】:

您好,考虑一下这段代码:

uint16_t dest_pid;
uint8_t *p;

pf->dest_pid = p[0] + (p[1] << 8)   //(p[1] << 8) equals 0 right?

此代码是嵌入式操作系统驱动程序的一部分。 一些想法 该声明背后的想法可能是什么?还是我遗漏了一些重要的东西?

【问题讨论】:

  • 取消引用未初始化的指针??不确定那里有什么想法,但肯定不是一个好主意。除非你遗漏了一些代码?
  • (p[1] &lt;&lt; 8) 是(部分)表达式。它有一个类型(无符号),它派生p[1]s 类型:它只“继承”无符号质量,而不是大小。
  • 为什么你认为它是 0?
  • @RadoslawKrasimirow 忘记变量;它们是低等生命形式。 C 语法是关于值和表达式的。变量的存在只是作为这些的基本块。

标签: c


【解决方案1】:

我假设您的 p 已被有意义地初始化(指向某个有效位置)。

然后在p[0] + (p[1] &lt;&lt; 8) 中,p[1] 将在左移&lt;&lt; 8 之前隐式提升为unsigned,因此代码确实有意义(例如,在 ARM 等 32 位处理器上)。非正式地,它生成一个 16 位数字,其低 8 位来自 p[0],高 8 位来自 p[1]

粗略地说,隐含的规则是,在 C 中,算术运算至少在 int 上进行(并且从不在像 shortuint8_tchar 这样的较小数据块上)。但细节更复杂(并且从 C89 到 C99 和 C11 标准略有演变)。

【讨论】:

  • 假设类型为uint8_t,则p[1] 将隐式转换为int(或signed,如果您愿意),因为integer Promotions。在这种情况下没有其他办法。
  • 没错,但是 p[whatever is inside ] 的类型是八位。如果它被明确地转换为“.. + (uint16_t)(p[1]
  • @RadoslawKrasimirow:你错了:(eightbitvar &lt;&lt; 8) 不是 8 位操作数移位,而是 int 移位。所以它并不总是零。
  • 如果您添加对 C 标准的“常用算术转换”语言的引用可能会有所帮助。
  • 术语怪癖:没有像隐式转换这样的东西。演员表总是明确的。这里发生的是促销转化
【解决方案2】:

首先:pf 之后的 dest_pid 是结构的一部分,我认为它是另一个变量,然后是 uint16_t dest_pid;

第二个:p 是指向uint8_t 的指针,当您执行(p[1] &lt;&lt; 8) 时,您会将指针内的内容移动8,例如,如果p[1] = 0xE5 移动后它将是0xE500。请记住,您将结果放在 dest_pid 中,这是一个 2 字节的变量。

最后一行的翻译最有可能将pid的低字节(不重要)加到pid的高字节(移8位)后放入pf-&gt;dest_pid,你可能会想为什么他没有从一开始就发送 2 个字节,原因可能是因为他是从每单位时间(周期)只发送一个字节的总线获取的。

【讨论】:

    猜你喜欢
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 2015-02-14
    • 1970-01-01
    相关资源
    最近更新 更多