共用体、大端小端的判断、枚举


1、联合体(共用体)

union U
{
    char s[9];
    int n;
    double d; 
};

    联合体和结构体的定义和使用是一样的,就不详细的赘述。必须要记住:联合体所有的成员变量都是共享同一块内存的,从相同的起始地址进行赋值。也就是给联合体的一个成员变量赋值的时候,就会改变其他成员变量的值。

联合体的大小:

    对于计算一个联合体的大小(共用体)来说,不同的编译器计算的结果是不同的。

VS2013:

union U
{
    char s[9];
    int n;
    double d;
};
int main(int argc, char *argv[])
{
    
    union U aa;
    printf(" sizeof(union U) = %d\n", sizeof(aa));
    while (1);
}

    打印的结果是:16。分析:联合体的大小满足两个条件:(1)max(成员变量),所以分配的最大的空间是 9  个字节;(2)联合体的大小必须是成员变量类型大小的整数倍;所以,结合上下的两个条件,联合体的大小就是 16。

GCC :

    gcc 计算的结果等于 12 个字节。经过多次的测试,gcc 对于内存的对齐的要求是 4 个字节。

结构体和联合区的区别:

    (1)结构体和联合体都是由多个不同的类型成员组成的。但是,在同一个时候,联合体只存放了一个被选中的成员(所有的联合体公用一块地址空间),结构体的所有的成员则是都存在(不同的成员存在的地址都不相同)

    (2)对于联合体的不同成员赋值,那么其他的成员将会被重写,原来的成员的值将不存在,而对于结构体来说不同的成员的赋值是互不影响的。

2、大端小端的定义

    对于多字节的数据的存储来说,有16位,32位等,对于多字节的存储就必然寸在对字节安排存储的问题,这个就是大小端区别的存在。

    大端模式:数据的高字节序存储在低地址中,而数据的低字节序存储在高地址中。

    小端模式:数据的高字节序存储在高地址中,而数据的低字节序存储在低地址中。

                                                     e4b70847-0bf4-4de4-8e91-bfe08d3d9d40

3、代码

#include <iostream>
using namespace std;
union ud
{
    int a;
    char b;
};
bool ceshi()
{
    ud c;
    c.a = 1;
    return (c.b == 1);
}
int main(int argc, char **argv)
{
    
    if (ceshi())
    {
        cout << "is 小端" << endl;
    }
    else
    {
        cout << "is 大端" << endl;
    }
    while (1);
    
    return 0;
}

    代码分析: 借助了联合体的帮助,联合体的特性存储的数据从低地址开始存储。而数据的读取也是从低地址开始读值。

分析:
    a 是四个字,a = 1,也就是a = 0x00 00 00 01;当系统是大端的时候,高字节序存储在低地址,低字节序存储在高地址,那么是这么存储的

地址: 0    1    2    3
a  : 00   00   00   01

 

 

   b 是一个字节,当系统是是小端的时候,高字节序存储在高地址,低字节序存储在低地址,那么是这么存储的:

 

地址   : 0    1    2    3
a存储  : 01   00   00   00

 

那么b 取数值的时候,那么 b 是一个字节,这个时候,b 的值就是1

    借助了联合体的帮助,当取得数值是 1 的时候,那么就是小端了。

B、使用地址的转换实现

 

#include<stdio.h>
int main()
{
    int test = 1;
    if(*(char *)&test)
        printf("Little endian byte order!\n");
    else
        printf("Big endian byte order!\n");
    return 0;
}

    分析,是因为 对于test 来说:

高字节序             低字节序
00     00     00     01

    那么对 test进行强制char 类型转换,转换之后,char 是读取最低字节的内存数据,也就是说,当读取到 01 的时候,那么 01 的位置就是最低的地址,也就是 低地址保存低字节序,高地址保存高字节序,所以这个时候,就是小端了,

    相反,当  char 类型读取到的数据是 00 的时候,也就是说,00这个位置是低地址,那么这个时候,低地址保存高字节序,高地址保存的是低字节序,所以,这个时候就是大端。

 

4、枚举

在程序的设计中,有时候会用到将有限个元素组成的集合,比如是星期一到星期天组成的集合,或者有RGB组成的集合,等等。

enum <枚举类型的名字>
{x1,x2,x3,,,,};

    比如:

enum weekdays
{mon,tue,wed,thu,fri,sat,sun};

    也就是定义了weekdays的枚举类型,它包含了七个元素。在编译器进行编译的时候,会给每个类型中的每一个元素都指定对应的整型的常量值,也称之为序号值。如果没有给指定的元素一个整型的常量值的话,那么整型的常量值是从零开始进行递增的。当将枚举类型中的除了第一个元素指定了一个常量值的话,那么前面的常量值是从零开始进行分配的,而被指定常量值的后面的部分,则是根据指定的一次递增。比如:

enum string

{x1,x2,x3=10,x4,x5,x6,x7};

    那么,显然x3 已经是指定了一个常量值,则x1 = 0,x2 =1,x4 = 11, x5 = 12, x6 = 13, x7 = 14,

posted @ 2015-11-04 21:21  qxj511  阅读(1721)  评论(0编辑  收藏  举报