【问题标题】:Reading a long from a struct on 32 bit system(C)从 32 位系统上的结构中读取 long (C)
【发布时间】:2017-04-03 14:02:57
【问题描述】:

在 C 中,我有一个带有成员“frequency”的结构,它是一个 long unsigned int。运行此代码的硬件是 32 位。

结构的值在实例化时设置。

struct config_list configuration = {
    ...
    .frequency = (long unsigned int)5250000000u,
    ...
}

在我的代码中,我通过指针将此结构传递给子例程。在这个子程序中,我似乎无法获得正确的值,所以为了检查,我输入了这个:

printf("Config frequency: %lu\n", ptr->frequency);
printf("Derefernced: %lu\n", (*ptr).frequency);

因为这是我相信您可以从指针访问结构数据的两种方式。

但是,在这两种情况下,我看到的输出都是 955,032,704。我认为这只是我设置的频率的前 32 位。我的问题是,为什么我的 long unsigned int 被削减为 32 位? “long”不是应该将范围扩展到 64 位吗?

【问题讨论】:

  • 5250000000 的值超出了 32 位无符号整数的范围。你从哪里得到代码?它似乎不是为 32 位系统设计的。
  • 使用long long"%llu" 而不是long。或者为了避免任何歧义,包括stdint.h 并将frequency 定义为uint64_t
  • ptr->frequency 是写(*ptr).frequency 的常用方式。这两种表示法是严格等价的。
  • 也许你可以包含 stdint.h 并从那里使用 64 位类型
  • 与 C 中几乎所有的整数一样,long 的大小取决于编译器。 GCC 通常在 64 位系统上将其设置为 64 位,但在 32 位系统上设置为 32 位。 Microsoft Visual C(++) 编译器在 32 位和 64 位系统上都有 long 为 32 位。如果您想要更大的类型,请使用long long,它保证至少为 64 位。请参阅例如this type reference 了解更多信息。

标签: c struct long-integer


【解决方案1】:

52500000000x1 38EC A480...它只是窥视第 33 位。

我建议您使用以下内容:

#include <stdio.h>
#include <stdint.h>    /* gives us uint64_t and UINT64_C() */
#include <inttypes.h>  /* gives us PRIu64 */

int main(void) {
    uint64_t d = UINT64_C(5250000000);

    printf("%"PRIu64"\n", d);

    return 0;
}
  • uint64_t 保证在任何系统上都是 64 位无符号的。
  • UINT64_C 将附加正确的后缀(通常为 ULULL)。
  • PRIu64 将为 64 位无符号指定正确的格式字符串。

在我的 64 位系统上,经过预处理器 (gcc -E) 后看起来像这样:

int main(void) {
     uint64_t d = 5250000000UL;

      printf("%""l" "u""\n", d);

       return 0;
}

对于 32 位版本,它看起来像这样 (gcc -E -m32):

int main(void) {
     uint64_t d = 5250000000ULL;

      printf("%""ll" "u""\n", d);

       return 0;
}

【讨论】:

  • 或者学究式,你可以写uint64_t d = UINT64_C(5250000000);
  • 这行得通。我的错误是假设“long”自动表示 64 位,而它显然取决于平台。这个 uint64_t 示例和使用“long long”的其他建议都可以提供正确的值。
  • 别忘了您可以随时使用sizeof() 来查看变量的实际位数。
  • @Lundin 您认为uint64_t d = UINT64_C(5250000000);uint64_t d = 5250000000; 相比有什么优势?
  • UINT64_C() 添加适当的后缀(例如:ULULL,具体取决于系统)。
猜你喜欢
  • 2018-12-24
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2011-12-18
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多