在C语言中各种数据类型各占多少位 C语言 中结构体的位域(位段)

80 篇文章 5 订阅
73 篇文章 1 订阅
(一)32位平台: 
分为有符号型与无符号型。 
有符号型: 
short 在内存中占两个字节,范围为-2^15~(2^15-1) 
int 在内存中占四个字节,范围为-2^31~(2^31-1) 
long在内存中占四个字节,范围为-2^31~2^31-1 
无符号型:最高位不表示符号位 
unsigned short 在内存中占两个字节,范围为0~2^16-1 
unsigned int 在内存中占四个字节,范围为0~2^32-1 
unsigned long在内存中占四个字节,范围为0~2^32-1 
实型变量: 
分单精度 float 和双精度 double 两种形式: 
float:占四个字节,提供7~8位有效数字。 
double: 占八个字节,提供15~16位有效数字。 

(二)16位平台: 
1)整型(基本型):类型说明符为int,在内存中占2个字节。 
2)短整型:类型说明符为short int或short。所占字节和取值范围均与整型(基本型)相同。 
3)长整型:类型说明符为long int或long,在内存中占4个字节。 
无符号型:类型说明符为unsigned。 
无符号型又可与上述三种类型匹配而构成: 
各种无符号类型量所占的内存空间字节数与相应的有符号类型量相同。但由于省去了符号位,故不能表示负数。 
实型变量: 
分为单精度(float型)、双精度(double型)和长双精度(long double型)三类。
单精度型占4个字节(32位)内存空间,其数值范围为3.4E-38~3.4E+38,只能提供七位有效数字。 
双精度型占8 个字节(64位)内存空间,其数值范围为1.7E-308~1.7E+308,可提供16位有效数字。 
长双精度型16 个字节(128位)内存空间,可提供18-19位有效数字。

一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较:

16位平台

char         1个字节8位

short        2个字节16位

int            2个字节16位

long         4个字节32位

指针         2个字节

32位平台

char         1个字节8位

short        2个字节16位

int            4个字节32位

long         4个字节

long long 8个字节

指针         4个字节

64位平台

char         1个字节

short        2个字节

int            4个字节

long         8个字节(区别)

long long 8个字节

指针        8个字节(区别)

二、编程注意事项

为了保证平台的通用性,程序中尽量不要使用long数据库型。可以使用固定大小的数据类型宏定义,这些宏定义需要引用stdint.h头文件:

typedef signed char       int8_t

typedef short int             int16_t;

typedef int                      int32_t;

# if __WORDSIZE == 64 typedef long int              int64_t; # else __extension__ typedef long long int      int64_t;

#endif

三、使用int时也可以使用intptr_t来保证平台的通用性,它在不同的平台上编译时长度不同,但都是标准的平台字长,比如64位机器它的长度就是8字节,32位机器它的长度是4字节,使用它可以安全地进行整数与指针的转换运算,也就是说当需要将指针作为整数运算时,将它转换成intptr_t进行运算才是安全的。intptr_t需要引用stddef.h头文件,它的定义如下:

#if __WORDSIZE == 64 typedef long int                intptr_t; #else typedef int                        intptr_t; #endif 编程中要尽量使用sizeof来计算数据类型的大小

以上类型定义都有相应的无符号类型。

四、使用ssize_t和size_t

它们分别是unsigned和signed size of computer word size。它们也是表示计算机的字长,在32位机器上是int型,在64位机器上long型。使用它们对于增加平台的通用性有很大好处,从某种意义上来说它们等同于intptr_t和uintptr_t。使用它们也需要引用stddef.h头文件。

五、socket的accept函数在有些操作系统上使用size_t是不正确的,因为accept接收的int*类型,而size_t的长度可能会超过int*的长度限制,导致错误。后来BSD使用sock_t来替代它。

 1.位域的声明

位域变量的声明与结构变量声明的方式相同。 如:

Struct sample{

  int a:7;        //类型说明符 位域名:位域长度

  int b:2;

  int c:6;

}data;

其中,datasample变量,共占两个字节。其中位域a占第一个字节的7位,位域b占第二个字节的低2位,位域c占第二个字节的高6位。

2.位域的对齐

   如果结构体中含有位域(bit-field),那么VC中准则是:

  1) 如果相邻位域字段的类型相同且其位宽之和小于声明数据类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

  2) 如果相邻位域字段的类型相同但其位宽之和大于类型的sizeof大小(如:char 的位域长度不能超过8int的字节长度不能超过32),则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

  3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++GCC都采取压缩方式;

系统会先为结构体成员按照对齐方式分配空间和填塞(padding,然后对变量进行位域操作

位域可以有无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:

Struct sample{

  char a:7;    //类型说明符 位域名:位域长度

  char b:2;

  char :2;

        char c:2  //无位域名的位数 直接跳过且这2位不能使用

}data;

#include <stdio.h>

#include <stdlib.h>

#include <memory.h>

struct A{     //结构体字节长度为8

    char a:8;          //占用第一个字节的8

    unsigned int b:5;     //占用第五个字节的低5

    unsigned int c:3;     //占用第五个字节的高3

};

int main()

{

    char testArry[10] = "0123456789";

    char testB[10] = {0};   

    struct A d;

     memcpy(&d, testArry, sizeof(d));

     printf("%d ", sizeof(d));

     printf("%d ", d.a);

     printf("%d ", d.b);

     printf("%d ", d.c);   

     system("pause");

     return 0;

}

编译运行输出结果:8  48  20  1

00110111 00110110 00110101 00110100   00110011 00110010 00110001 00110000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值