C sizeof详解

来源:互联网 发布:sql 7.0 修改sa密码 编辑:程序博客网 时间:2024/06/06 03:03

1.sizeof概念

 sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数,而是关键字。sizeof操作符以字节形式给出了其操作数的存储大小。

注意:

a.操作数可以是一个表达式或括在括号内的类型名。
b.操作数的存储大小由操作数的类型决定。

2.sizeof使用

(1)用于数据类型 
sizeof使用形式: sizeof(datatype)
数据类型必须用括号括住: sizeof(int)
(2)用于变量 
sizeof使用形式: sizeof(var_name) 或 sizeof var_name 

注意:

a.变量名可以不用括号括住.如sizeof (var_name),sizeof var_name等都是正确形式带括号的用法更普遍,大多数程序员采用这种形式。 

b.sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

3.常用数据类型sizeof结果(linuxv2.6)

(1)ANSI C正式规定字符类型为1字节。   
    sizeof(char)          = 1;
    sizeof(unsigned char) = 1;
    sizeof(signed char)   = 1; 
(2)其他类型在ANSI C中没有具体规定,大小依赖于实现。 
    sizeof(int)            = 4;
    sizeof(unsigned int)   = 4;
    sizeof(short int)      = 2;
    sizeof(unsigned short) = 2;
    sizeof(long int)       = 4;
    sizeof(unsigned long)  = 4;
    sizeof(float)          = 4;
    sizeof(double)         = 8;
    sizeof(long double)    = 12;
(3)当操作数是指针时,sizeof依赖于编译器。
Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。
一般Unix/Linux的指针字节数为4。    
例如: char *p;      //Linux
sizeof(p) = 4;
(4)当操作数具有数组类型时,其结果是数组的总字节数。
    例如: char a[5];
          int  b[5];
          sizeof(a) = 5;
          sizeof(b) = 20;
(5)当操作数是具体的字符串或者数值时,会根据具体的类型进行相应转化。
    例如: sizeof(8)    = 4;  //自动转化为int类型
          sizeof(8.8)  = 8;  //自动转化为double类型,注意,不是float类型
          sizeof("ab") = 3   //自动转化为数组类型,
                             //长度是4,不是3,因为加上了最后的'\n'符
                             //有资料说,会自动转化为指针类型(Linux为4)
                             //可能和操作系统与编译器有关系       
(6)当操作数是联合类型时,sizeof是其最大字节成员的字节数。
   当操作数是结构类型时,sizeof是其成员类型的总字节数,包括补充字节在内。   
(7)当操作数是函数中的数组形参或函数类型的形参:
   sizeof给出其指针的大小,Linux中值为4。

4.sizeof与数据结构

struct str_a{
double d;
char ch;
int data;
}stra;

struct str_b{
char ch;
double d;
int data;
}strb;

两个不同的结构,但是内部的元素是相同的,都是double,int,char,只是顺序不一样,就导致结果不一样。why?
这是因为操作系统存储数据的时候要对其,具体的情况如下:
类型
  对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
  Char
  偏移量必须为sizeof(char)即1的倍数
  int
  偏移量必须为sizeof(int)即4的倍数
  float
  偏移量必须为sizeof(float)即4的倍数
  double
  偏移量必须为sizeof(double)即8的倍数
  Short
  偏移量必须为sizeof(short)即2的倍数
对于stra:为上面的结构分配空间的时候,操作系统根据成员变量出现的顺序和对齐方式,先为第一个成员d分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员ch分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员data分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,操作系统自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(str_wu)=8+1+3+4=16,其中有3个字节是操作系统自动填充的,没有放任何有意义的东西。
对于strb:同样的道理,sizeof(char)=1,而1不是8的倍数,因而增加到8,sizeof(double)=8,现在开始地址是16,16是sizeof(int)的倍数,可以存入。因而总的地址数:sizeof(char)+7+sizeof(double)+sizeof(int)=20,而20不是8的倍数(sizeof(double)=8),所以需要在增加4个地址,即总共24。

5.sizeof与strlen()

sizeof和strlen()都可以用来计算指定的字符串的长度,区别在于:sizeof包括结束字符"\0",而strlen()不包括。

例如:

 

输出结果:

strlen(str)= 5,sizeof(str)=6