C语言编程之数据类型

 |   
C  

在众多C语言面试题目里,经常会考察数据类型以查看面试者的基本知识的掌握程度。这里对C语言的基本数据类型和自定义数据类型进行一些试验,并理解自定义构造类型中构造数据类型的字节对齐规则。

基本类型

C语言中基本数据类型就6(6=3+2+1)个,其中3个整型,2个浮点型,还有1个字符型。

  1. 代码片段

    1// 整型
    2printf("sizeof(short) is %ld byte.\n",sizeof(short));
    3printf("sizeof(int) is %ld byte.\n",sizeof(int));
    4printf("sizeof(long) is %ld byte.\n",sizeof(long));
    5// 浮点型
    6printf("sizeof(float) is %ld byte.\n",sizeof(float));
    7printf("sizeof(double) is %ld byte.\n",sizeof(double));
    8// 字符型
    9printf("sizeof(char) is %ld byte.\n",sizeof(char));
    
  2. 解析
    因为系统是64位的ubuntu,使用的是gcc编译器,所以字符型占1个字节,short型占2个字节,int型占4个字节,long型占8个字节(32位占4个字节),float型占4个字节,double型占8个字节。

自定义类型

自定义数据类型有5个,分别是数组类型,空类型,指针类型,类和构造数据类型。其中构造数据类型又包含结构体,枚举型和共用体三个。

数组类型

其占用的空间是数组元素类型*数组长度。

空类型

  1. 代码片段

    1printf("sizeof(void) is %ld byte.\n",sizeof(void));
    
  2. 解析
    空类型只占用1个字节空间

指针类型

指针类型的大小跟指针所指向的数据类型无关,它都是8个字节。包括空类型指针也是如此。

待定

构造数据类型

  • 字节对齐
    对于构造数据类型所占空间的大小是经常被考察,而出题者想要考察的是面试者对 字节对齐的了解。字节对齐规则有下面三个条件:

    1. 数据成员对齐规则
      结构体或联合体的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的起始位置要从该成员大小或成员的子成员大小(如数组,结构体)的整数倍开始。
    2. 结构体作为成员
      如果一个结构里有某些结构体成员,则结构体成员要从内部最大元素大小的整数倍地址开始存储。
    3. 首尾验证
      结构体的总大小必须是其内部最大成员的整数倍,不足的要补齐。
  • 结构体

    1. 代码片段

       1// struct
       2struct student{
       3    char name[10];
       4    int age;
       5    char sex;
       6    int a;
       7    char b,c;
       8};
       9
      10printf("sizeof(struct student) is %ld byte.\n",sizeof(struct student));
      
    2. 解析
      对于结构体struct student所占的空间是28个字节,如果将int a换成char a,则结构体所占的空间是20个字节。这里涉及到 字节对齐的规则。
      在上面的结构体中,字符数组name虽然占10个字节[0-9]的空间,但由于int占 4个字节,得从4的倍数开始存储,所以age占了offset从12-15的四个字节。而10-11这两个字节由系统补齐。接着下面的char sex后面也会补3个字节,最后的char要补2个字节,所以结构体的总大小为28(28=12+4+4+4+4)个字节。当将int sex改为char sex后,第一个规则将不会让sex后面填充了,所以此时将结构体的总大小为20(20=12+4+1+1+2)个字节。

  • 共用体

    1. 代码片段

      1// union
      2union u{
      3    char ch;
      4    int num;
      5    double dou;
      6    char name[10];
      7};
      8printf("sizeof(union u) is %ld byte.\n",sizeof(union u));
      
    2. 解析
      共用体将会占用16个字节空间,根据条件3很容易得到。虽然char name只占了10个字节,但是由于double类型占8个字符,整个共用体的占用空间必须是8的整数倍,所以占用的空间会是16字节了。

  • 枚举类型

    1. 代码片段

      1// enum
      2enum days{mon,tue,wed,thu,fri,sat,sun};
      3
      4printf("sizeof(enum days) is %ld byte.\n",sizeof(enum days));
      
    2. 解析
      枚举类型的大小恒为4个字节。

试验

  • 验证C语言中数据类型所占空间大小
    • 源码
      结果如下图
      vartype1

      vartype2
    • 解析
      1. 每种数据类型的大小
      2. 变量和变量类型求sizeof后完全一致,不存在类型没有定义变量就占用很少的空间。

参考文献

  1. 深入了解void以及void指针
  2. 字节对齐
  3. 5分钟搞定内存字节对齐
技术茶话会
< 前一篇 后一篇 >