C中基本数据类型的大小

时间:2013-02-11 22:03:39

标签: c types

我有一个我从某个网站复制的示例程序。

int main(void)
{
   int answer;
   short x = 1;
   long y = 2;
   float u = 3.0;
   double v = 4.4;
   long double w = 5.54;
   char c = 'p';

   typedef enum
   {
      kAttributeInvalid,
      kBooleanAttributeActive,
      kBooleanAttributeAlarmSignal,
      kBooleanAttributeAlign64,
      kBooleanAttributeAutoNegotiationComplete,
   }codes_t;

  /* __DATE__, __TIME__, __FILE__, __LINE__ are predefined symbols */
  #if 0
  printf("Date : %s\n", __DATE__);
  printf("Time : %s\n", __TIME__);
  printf("File : %s\n", __FILE__);
  printf("Line : %d\n", __LINE__);
  #endif

  /* The size of various types */
  printf("The size of int         %zu\n", sizeof(answer));
  printf("The size of short       %zu\n", sizeof(x));
  printf("The size of long        %zu\n", sizeof(y));
  printf("The size of float       %zu\n", sizeof(u));
  printf("The size of double      %zu\n", sizeof(v));
  printf("The size of long double %zu\n", sizeof(w));
  printf("The size of char        %zu\n", sizeof(c));
  printf("The size of enum        %zu\n", sizeof(codes_t));

  return 0;
}

我运行了这个程序,我得到的输出如下。

The size of int         4
The size of short       2
The size of long        8
The size of float       4
The size of double      8
The size of long double 16
The size of char        1
The size of enum        4

我在运行64位Ubuntu的Linux PC上运行。我的问题是,如果我在32位机器上运行相同的程序,我会看到不同的结果。或者换句话说,它的大小是基本数据类型取决于

  1. 处理器
  2. 操作系统
  3. 其他任何内容

5 个答案:

答案 0 :(得分:7)

  

我的问题是,如果我在32位机器上运行相同的程序,我会看到不同的结果

也许。或许不是。

  

或者换句话说,基本数据类型的大小取决于1)处理器2)操作系统3)其他任何东西

  1. 是,2。是,3。是的,例如,如果您在64位操作系统上以32位兼容模式运行32位应用程序,那么它很可能会使用32位字大小(当然,它是这样编译的)。哦,是的,它可能还取决于编译器。
  2. “你的编译器标志......”(谢谢,凯!)

答案 1 :(得分:4)

如果您关心变量的确切大小,请使用

#include <stdint.h>

然后使用那里定义的固定宽度类型:

uint8_t
uint16_t
uint32_t
uint64_t

或他们签名的堂兄弟

int8_t
int16_t
int32_t
int64_t

不要依赖C中原生类型的大小。不同的编译器有不同的规则。

答案 2 :(得分:4)

如果必须在其32位变体中安装一些库[可能只是glibc],您应该可以使用gcc -m32 myprog.c [或clang -m32 myprog.c]自行尝试。

但是,如果您使用基于gcc的编译器从64位x86 linux系统迁移到32位x86 linux系统,那么列出的项目中唯一会改变的是{{1 }}。注意x86,gcc等的重要资格 - 编译器有很多自由。有人可以编写一个Linux编译器,它在32位系统上使用16位long和64位int,没有太大的难度。使用该编译器编译Linux内核和许多Linux工具可能会失败[很可能包括使用该编译器编译long]。但你不能真正说“在这个体系结构上”或“在这个操作系统中”或“使用这个编译器”...而且还没有限定其他参数是什么。

例证:Microsoft C / C ++编译器的gcc即使在64位系统上也是32位。为什么,我听到你问?因为当Windows是Intel 286/386处理器上的16位操作系统时,大量Windows API函数使用long作为32位值。由于(部分)系统调用在Windows中向后兼容很长,因此为16位系统编写的代码仍可在64位Windows上运行[除非代码使用了一些非常不寻常的系统调用,当然,STYLE看起来有点古老]。将long更改为64位值会破坏某些功能,因此MS的编译人员决定坚持使用long = 32位。如果您想要64位整数,则必须使用longlong long或其他内容,而不是int64_t。当然,这会破坏一些假定为long的代码。希望大多数此类代码已经修复......

答案 3 :(得分:2)

是的,在某些情况下,它取决于硬件,操作系统,编译器甚至语言。

但是在x86 linux上,longs将是32位平台上的4个字节,而不是8个字节。 我认为其他人都保持不变(不确定长双)。

轶事:

我在一个24位系统上工作,其字大小为24位,每个本机类型的大小为1个字。的sizeof(字符)? 1(即:24位)。的sizeof(int)的? 1(即:24位)。等等!有趣!

答案 4 :(得分:2)

编译器在编译时将大小设置为一致,因为编译器必须发出特定于大小的指令,在结构中布置成员,并知道所有必需地址计算的结构大小。

因此,如果您将源代码编译为64位二进制文​​件并在一堆不同的系统上运行,那么如果系统支持二进制文件,则每次运行时类型将具有相同的大小。

如果您随后将源代码编译为32位二进制文​​件或使用不同的编译器开关,那么当您在一堆不同的系统上运行它时,这些数字可能与64位情况不同,但它们将保持一致所有不同的系统。