【问题标题】:Errors compiling C code with sizeof from command line从命令行使用 sizeof 编译 C 代码时出错
【发布时间】:2017-10-16 06:45:43
【问题描述】:

我从 Linux 命令行在 Nano 中编写了以下代码,以在编译时出错:

我想知道我需要对代码进行哪些更改才能使其正确编译。我正在尝试获取列出的每种数据类型中的位数以打印在一行上。

#include<stdio.h>

int main(void){
    char A;
    unsigned char B;
    int a;
    unsigned int b;
    long c;
    unsigned long d;
    float e;
    double f;
    long double g;

    printf(
        "%c %c %i %u %li %lu %f %lf %Lf\n",
         sizeof(char), sizeof(unsigned char),
         sizeof(int), sizeof(unsigned int),
         sizeof(long), sizeof(unsigned long),
         sizeof(float), sizeof(double), sizeof(long double)
    );

    return 0;
}

【问题讨论】:

  • printf 中使用%zu 而不是%whatever。它的参数不是它们各自的类型,而是size_t,因为sizeof 返回的是size_t 类型。
  • @zbw 这将是一个很好的答案,带有一些链接和相关代码的固定版本。
  • 寻找类似的问题,我发现this one 有一个很好的解释。我无法给出更好的答案,所以我只提供链接。
  • 另外,sizeof 返回字节数,这通常比位数更有用。乘以 8 得到位数
  • @zbw: 8 几乎肯定会起作用,但CHAR_BIT 更清晰。 (假设您在程序中有一些其他值恰好是8,并且您想将其更改为16。如果您没有太多不相关的@987654336 出现,那么进行更改会容易得多@. 最好避免使用幻数。

标签: c linux command sizeof nano


【解决方案1】:

sizeof 运算符返回 size_t 类型的整数,因此您应该使用适当的 printf 格式说明符 ("%zu")(假设 C99):

printf(
    "%zu %zu %zu %zu %zu %zu %zu %zu %zu\n",
     sizeof(char), sizeof(unsigned char),
     sizeof(int), sizeof(unsigned int),
     sizeof(long), sizeof(unsigned long),
     sizeof(float), sizeof(double), sizeof(long double)
);

但是,这会打印每种类型的 字节数。如果您想要每种类型的 数,请包含 &lt;limits.h&gt; 并将每个结果乘以 CHAR_BIT 以获得:

#include <limits.h>

/* ... */

printf(
    "%zu %zu %zu %zu %zu %zu %zu %zu %zu\n",
     sizeof(char) * CHAR_BIT, sizeof(unsigned char) * CHAR_BIT,
     sizeof(int) * CHAR_BIT, sizeof(unsigned int) * CHAR_BIT,
     sizeof(long) * CHAR_BIT, sizeof(unsigned long) * CHAR_BIT,
     sizeof(float) * CHAR_BIT, sizeof(double) * CHAR_BIT, sizeof(long double) * CHAR_BIT
);

IMO,如果您标记要打印的内容并将每个值打印在单独的行上,它看起来会更清晰,如下所示:

printf("Number of bits in char = %zu\n", sizeof(char) * CHAR_BIT);
printf("Number of bits in unsigned char = %zu\n", sizeof(unsigned char) * CHAR_BIT);
printf("Number of bits in int = %zu\n", sizeof(int) * CHAR_BIT);
printf("Number of bits in unsigned int = %zu\n", sizeof(unsigned int) * CHAR_BIT);
printf("Number of bits in long = %zu\n", sizeof(long) * CHAR_BIT);
printf("Number of bits in unsigned long = %zu\n", sizeof(unsigned long) * CHAR_BIT);
printf("Number of bits in float = %zu\n", sizeof(float) * CHAR_BIT);
printf("Number of bits in double = %zu\n", sizeof(double) * CHAR_BIT);
printf("Number of bits in long double = %zu\n", sizeof(long double) * CHAR_BIT);

可以用宏来减少(虽然宏不是最好的,但它们对于重复代码很有用):

#define PRINT_BITS_IN_TYPE(type) \
    printf("Number of bits in " #type " = %zu\n", sizeof(type) * CHAR_BIT)

PRINT_BITS_IN_TYPE(char);
PRINT_BITS_IN_TYPE(unsigned char);
PRINT_BITS_IN_TYPE(int);
PRINT_BITS_IN_TYPE(unsigned int);
PRINT_BITS_IN_TYPE(long);
PRINT_BITS_IN_TYPE(unsigned long);
PRINT_BITS_IN_TYPE(float);
PRINT_BITS_IN_TYPE(double);
PRINT_BITS_IN_TYPE(long double);

【讨论】:

  • 谢谢 InternetAussie。我还没有达到使用宏的水平,所以当我到达那里时,我会回顾一下。但是,我也发现我可以使用 %lu 而不是 %zu。我从网上得到了这个,“%lu 格式说明符,它打印一个无符号长整数类型。我选择这种格式是因为在我的 64 位机器上 sizeof 输出一个无符号长整数(存储大小只能是正数)。如果你使用如果是 32 位操作系统,您可能需要使用“%u”而不是“%lu”。如果格式错误,编译器会报错。”
  • @NickAdoyot "如果格式错误,编译器会抱怨" --> 编译器不需要抱怨。最好的方法是使用"%zu"。使用"%lu",需要维护你的代码的人会胡思乱想。
  • @InternetAussie 再次感谢您的帮助。
【解决方案2】:

这是因为 unsigned char 被提升为 int(在正常的 C 实现中),因此将 int 传递给 printf 的说明符 %c。但是,%c 需要一个 unsigned int,因此类型不匹配,并且 C 标准没有定义行为。 您可以执行以下方法: 1)尝试使用C11(标准版)。 2) 尝试使用 %zu。

【讨论】:

  • "但是,%c 需要一个无符号整数," --> 不完全是。 "%c" 需要 int。该值被转换为unsigned char 并打印相应的字符。行为已定义。
猜你喜欢
  • 1970-01-01
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 2011-01-22
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多