VC,C++ Builder和lcc三个编译器 间枚举类型enum长度的情况.
各种C编译器默认的字节对齐数不一致,要写通用的代码,经常就是使用
#pragma pack(1) ...
#pragma pack()
来使编译器以单字节对齐.
今天在bcb5中调用vc6的dll时出现错误,但在VC中调用dll却很正常,说明很有可能是编译器之间的差异造成.仔细debug后发现bcb和vc的枚举类型长度不一样,即便使用了#pragma pack(1)编译开关. 如以下程序: /*---------------------*/ #pragma pack(1) typedef enum {     ENUMITEM1=0,     ENUMITEM2,     ENUMITEM3 } ENUM; #pragma pack() ENUM mENUM; sizeof(mENUM); /*---------------------*/
在VC6和LCC3.3中为四字节,而在BCB中即为1字节.再试以下程序
/*---------------------*/
#pragma pack(4)
typedef enum {
    ENUMITEM1=,
    ENUMITEM2,
    ENUMITEM3
} ENUM;
#pragma pack()
ENUM mENUM;
sizeof(mENUM);

/*---------------------*/
在VC和LCC中依然是4字节,而在BCB中也还是1字节,由于手上暂时没有GCC,所以不能看GCC的情况.
以上说明枚举类型作为C的标准变量类型,其长度是不受编译开关影响的,就如char类型无论如何pack,依然是单字节.

但是,并非所有的编译器都遵循C标准,或许是VC不标准,或许是BCB不标准.
所以建议以后用到的变量尽量使用char或int来替代enum,以免带来不必要的麻烦.
#include <stdio.h>
int main()
{
      enum Color
      {
          GREEN = ,
          RED,
          BLUE,
         GREEN_RED = ,
         GREEN_BLUE,
      }c;
     printf("%d,%d,%d,",GREEN,RED,BLUE);
     printf("%d,%d\n",GREEN_RED,GREEN_BLUE);
     printf("%d\n",sizeof(c));
     ;
}
      看到这里,是不是一开始想用c.GREEN,c.RED,c.BLUE...来表示枚举变量里面的成员?然后这样子表示,编译器是会报错的。为什么不能像结构体那样表示呢?因为结构体里面的成员是变量,而枚举里面的成员是常量啊!(这是我个人的理解)
      枚举变量究竟是多大呢?答案是4,为啥呢?因为,枚举变量的取值为花括号内的任意一个值(有且只能有其中一个值),而这个值是int型的,在X86系统中,int型的数据占内存4个字节。所以sizeof(c) = ,也就是枚举变量的值为4。
一般编译器都有选项的
BCB:
* -b      Make enums integer-sized (-b- makes them short as possible)
GCC:
-fshort-enums Use the narrowest integer type possible for enumeration types
VC Same as int
枚举默认是用int类型来存储的,32位系统下占4个字节。可以存储的最大值是0xffffff。 你可以改变枚举的大小例如enum TypeChar : unsigned char{} 这样可以节省空间, 在嵌入式编程中较为常见。嵌入式编程中,甚至有用位来存储的。
枚举并不放在类的对象里,类A里面没有任何东西,与class A {};相同大小。不包含任何东西的类的大小就是1。cout << sizeof(A) << endl;输出的是1
关于C++和C的区别:
1.区别最大的是struct,C++中的struct几乎和class一样了,可以有成员函数,而C中的struct只能包含成员变量。 enum,union没区别。2.C++要考虑字节对齐。

struct的定义:
struct  结构标签
{
      类型1 标识符1;
      类型2 标识符2;
      类型3 标识符3;
      类型4 标识符4;
      类型5 标识符5;
};
、建议将struct的声明和变量的定义分开写,
、struct内可以放任何类型的变量声明。

struct的内存对齐:
对齐原则:
、数据成员对齐规则。每个数据成员存储的起始位置要从该成员大小的整数倍开始。
、数据成员包含结构体:结构体成员要从其内部最大元素大小的整数倍地址开始存储。
、结构体的总大小:是其内部最大基本成员的整数倍,不足的要补齐。
这个似乎不太重要,没有太大的关系。也就是某些面试或考试题中的难为人的地方了。
union的定义:
union 联合标签
{
      类型1 标识符1;
      类型2 标识符2;
      类型3 标识符3;
      类型4 标识符4;
      类型5 标识符5;
};

联合体与结构体的区别:
、结构体中,每个变量依次存储。
、联合体中,每个变量都是从偏移地址零开始存储,每次只有一个成员存储于该地址。

enum的定义:
, large =,humungous};
、枚举通过简单的操作将一串名字和一串整型值相联系起来。
、缺省情况下,枚举从零开始,如果对列表中的某一个标识符赋值,下一个标识符值比前面一个的值大1.
、#define 定义的值在编译时候消失,但是枚举定义的,则在调试的过程任然是可见的,可以在代码调试中使用它们。
其实 enum可以相对应define来使用。
举个例子:
union a
{
    int b;
    char c;
};
a abc;
abc.b=;
abc.c=;
//或者也可以直接在定义时定义变量
union a
{
    int b;
    char c;
}abc;
abc.b=;
abc.c=;
或者:
typedef union
{
    int b;
    char c;
}a;
a abc;
abc.b=;
abc.c=;
仔细的看看,很重要,老是用的不对,自己给自己找麻烦的。
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
struct的最终大小考虑是最大的那个类型的倍数和每个都要对齐;
enum的大小考虑是最大的那个
enum是枚举,就是某个变量的值是能够列举的,比如,星期的话就每周1到7,月的话就1到12、而struct的话是对于某个变量是有很多数据类型构成一个总体的,比如学生这个变量,他需要学号,姓名,年龄,性别等等,这个时候就需要定义结构体了。而uninon的话呢,其中定义的变量都只占一同块内存。。。
对于结构体:考虑要对齐和占用最大空间的元素所占空间的倍数
对于联合体:考虑是里面所有类型数据占用空间的倍数同时还要比最大的那个还要大的最小数,就是联合体占用的空间,注意数组类型的处理!!!
typedef enum
{
 ANUnknown = ,
 ANShapeFile = ,
 ANSDEDatabase = ,
 ANFileDatabase = ,
 ANRasterFile =
}ANDataType;

======================================================
struct AAA
{
 double d;
 char ss;
 char s;
};
, 则整个为 * = , 因为 ,剩余一个不足8 按 8字节计算。比如:
 struct AAA
{
 double d;
 char s1;
 char s2;
 char s3;
 char s4;
 char s5;
 char s6;
 char s7;
 char s8;
 char s9;
};
按结构体中的变量的长度叠加,则大小为 +(+++++++)+ = ,   <  < , 则结构体的大小为
比如,
 struct AAA
{
 double d;
 char s1;
 int i;
};
按结构体中的变量的长度叠加,则大小为 ++ = ,   <  < , 则结构体的大小为
======================================================
union AAA
{
 double d;
 int i;
};
联合,则以定义中最大的数据类型的长度为准,此联合的 size 为
备注: union 与 struct 的大小与其内部定义的函数无关!!!
typedef struct与struct的区别

. 基本解释

  typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。

  在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。

  至于typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。

  . typedef & 结构的问题

  当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明:

typedef struct tagNode
{
 char *pItem;
 pNode pNext;
} *pNode; 

  答案与分析:

  、typedef的最简单使用

typedef long byte_4;

  给已知数据类型long起个新名字,叫byte_4。

  、 typedef与结构结合使用

typedef struct tagMyStruct
{
 int iNum;
 long lLength;
} MyStruct;

  这语句实际上完成两个操作:

  ) 定义一个新的结构类型

struct tagMyStruct
{
 int iNum;
 long lLength;
};

  分析:tagMyStruct称为“tag”,即“标签”,实际上是一个临时名字,struct 关键字和tagMyStruct一起,构成了这个结构类型,不论是否有typedef,这个结构都存在。

  我们可以用struct tagMyStruct varName来定义变量,但要注意,使用tagMyStruct varName来定义变量是不对的,因为struct 和tagMyStruct合在一起才能表示一个结构类型。

  ) typedef为这个新的结构起了一个名字,叫MyStruct。

typedef struct tagMyStruct MyStruct;

  因此,MyStruct实际上相当于struct tagMyStruct,我们可以使用MyStruct varName来定义变量。

  答案与分析

  C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。

  根据我们上面的阐述可以知道:新结构建立的过程中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识pNode。

  解决这个问题的方法有多种:

  )、

typedef struct tagNode
{
 char *pItem;
 struct tagNode *pNext;
} *pNode;

  )、

typedef struct tagNode *pNode;
struct tagNode
{
 char *pItem;
 pNode pNext;
};

  注意:在这个例子中,你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。

  )、规范做法:

struct tagNode
{
 char *pItem;
 struct tagNode *pNext;
};
typedef struct tagNode *pNode;

enum,struct,union类型使用和长度的更多相关文章

  1. 关于C与C++的struct,union,enum用法差异

    对着代码说话: #include <stdio.h> #include <stdlib.h> struct test { int abc; }; enum _enum {A,B ...

  2. C/C++中struct/union/class内存对齐

    struct/union/class内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储 ...

  3. C++11的enum class & enum struct和enum

    C++11的enum class & enum struct和enum C++标准文档--n2347(学习笔记) 链接:http://www.open-std.org/jtc1/sc22/wg ...

  4. [转]C++11的enum class & enum struct和enum

    1. 旧版enum存在的问题 问题 描述 1 向整形的隐式转换(Implicit conversion to an integer) 2 无法指定底层所使用的数据类型(Inability to spe ...

  5. 【转】C++11的enum class & enum struct和enum

    转自:https://blog.csdn.net/sanoseiichirou/article/details/50180533 C++标准文档——n2347(学习笔记) 链接:http://www. ...

  6. C语言中Union类型的使用方法

    转自:http://blog.csdn.net/feimor/article/details/6858103 使用C语言时,常常使用struct,对于union类型却几乎没有用过,只知道它是联合类型, ...

  7. c# (ENUM)枚举组合类型的谷歌序列化Protobuf

    c# (ENUM)枚举组合类型的谷歌序列化Protobuf,必须在序列化/反序列化时加上下面: RuntimeTypeModel.Default[typeof(Alarm)].EnumPassthru ...

  8. MySql获取表的字段名称、字段注解、字段类型、字段长度

    SELECT  COLUMN_NAME as '列名',COLUMN_COMMENT,DATA_TYPE as '字段类型' ,COLUMN_TYPE as '长度加类型' FROM informat ...

  9. 关于mysql varchar 类型的最大长度限制

    Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This ...

随机推荐

  1. phpcms v9 企业黄页系统发布没有表单出现的解决方案

    第一种解决方案: 第一步:把yp_UTF8压缩文件解压得到:api.caches.phpcms.statics四个文件夹. 第二步:把这四个文件夹分别覆盖已安装好的phpcms系统根目录下的文件夹.这 ...

  2. 在唯一密钥属性“value”设置为“Default.aspx”时,无法添加类型为“add”的重复集合项

    环境:windows server 2012  asp.net 找到网站目录:wwwroot ,打开web.config文件,在 在<files>与</files>之间加入代码 ...

  3. [转载+原创]Emgu CV on C# (六) —— Emgu CV on Canny边缘检测

    Canny边缘检测也是一种边缘检测方法,本文介绍了Canny边缘检测的函数及其使用方法,并利用emgucv方法将轮廓检测解算的结果与原文进行比较. 图像的边缘检测的原理是检测出图像中所有灰度值变化较大 ...

  4. ubuntu下修改ip重启系统ip不变

    今天同学问我ubuntu下ip如何写死,我想起这周在公司我们队长也问过我,我就在这把我实验的方法说一下. 打开终端: sudo vim /etc/network/interfaces 然后按如下修改: ...

  5. MST性质(用于构造最小生成树)

    描述:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集.若(u,v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则必存在一棵包含边(u,v)的最小生成树. 证明: 假设网N的 ...

  6. hadoop历史服务器配置问题

    作者:sdjnzqr 出处:http://www.cnblogs.com/sdjnzqr/ 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同意,必须保留此段声明:必须在文章中给出原文连接 ...

  7. ffmpeg参数解释

    基本选项: -formats 输出所有可用格式 -f fmt 指定格式(音频或视频格式) -i filename 指定输入文件名,在linux下当然也能指定: 0.0(屏幕录制)或摄像头 -y 覆盖已 ...

  8. Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!

    开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...

  9. javascript 在一个函数参数中包含另一个函数的引用

    javascript函数的参数包含另一个函数的情形: <script> //b函数的参数func为另一个函数 function b(a, func) {  alert(a); //调用参数 ...

  10. Python新式类和旧式类的区别

    新式类是为了统一**而在2.2中开始引入的. 代码讲解 上面的例子比较明白的说明了问题. B是定义的新式类.那么输入b的时候,不论是type(b),还是b.__class__都是输出的<clas ...