深入sizeof的使用详解

经常在C下编程,不了解精通sizeof就有点说不过去了,本文可没有sizeof与strlen的区别哦,尽管这个对比很经典,不过,将就点吧。

一、sizeof的概念
  sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。
    操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 

二、sizeof的使用方法
1、用于数据类型 
  sizeof使用形式:sizeof(type) 
  数据类型必须用括号括住。如sizeof(int),还有sizeof int ,或sizeof(variable)三种方式。 

2、用于变量 
  sizeof使用形式:sizeof(var_name)或sizeof var_name 
  变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。 
  注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。 
  如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。 
 
三、sizeof的结果

  sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 
  1、若操作数具有类型char、unsigned char或signed char,其结果等于1。 
  ANSI C正式规定字符类型为1字节。 
  2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double类型的sizeof
      在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。 
  3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。 
  4、当操作数具有数组类型时,其结果是数组的总字节数。 
  5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。 
  让我们看如下结构: 
          struct A{
                      char b; 
                      double x;
                   } a; 
  在某些机器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。 
  这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。 
  6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。 

四、sizeof与其他操作符的关系
  sizeof的优先级(各操作符的优先级可参考C语言运算符优先级列表(超详细):)为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。 

五、sizeof的主要用途
  1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如: 
     void *malloc(size_t size), 
     size_t fread(void *ptr, size_t size, size_t nmemb,FILE * stream)。 
  2、sizeof的另一个的主要用途是计算数组中元素的个数。例如: 
     void * memset(void *s,int c,sizeof(s))。 

六、建议
  由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
  本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,
    第二部分总结出VC中sizeof的主要用法。
    1、 sizeof应用在结构上的情况
  请看下面的结构:
       struct MyStruct
       {
             double dda1;
             char dda;
             int type
       };
  对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求:
       sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13
  但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗?
  其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。
  各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
  下面用前面的例子来说明VC到底怎么样来存放结构的。
       struct MyStruct
       {
             double dda1;
             char dda;
             int type
       };
       sizeof(MyStruct)=8+1+3+4=16,
    其中有3个字节是VC自动填充的,没有放任何有意义的东西。  
附:更改C编译器的缺省字节对齐方式
    在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:
· 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
· 使用伪指令#pragma pack (),取消自定义字节对齐方式,恢复缺省对齐。
    另外,还有如下的一种方式:
· __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
· __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。

七、sizeof用法总结
  在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个总结。
  A.参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。
  B.参数为数组或指针。下面举例说明.
           int a[50];              //sizeof(a)=4*50=200; 求数组所占的空间大小
           int *a=new int[50];     // sizeof(a)=4; a为一个指针,sizeof(a)是求指针的大小,在32位系统中,当然是占4个字节。
  C.参数为结构或类。sizeof应用在类和结构的处理情况是相同的。但有两点需要注:
             第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。
             第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都有唯一的地址。
  下面举例说明:
       Class Test{int a;static double c};     //sizeof(Test)=4.
       Test *s;                               //sizeof(s)=4,s为一个指针。
       Class test1{ };                        //sizeof(test1)=1;
  D. 参数为其他。下面举例说明。
       int func(char s[5]);
       {
              cout << s ; //函数的参数在传递的时候系统处理为一个指针,所以sizeof(s)实际上为求指针的大小。
              return 1;
       }
       sizeof(func( "1234" ))=4;    //因为func的返回类型为int,所以相当于求sizeof(int).

(0)

相关推荐

  • C#中sizeof的用法实例分析

    sizeof是C#中非常重要的方法,本文就以实例形式分析C#中sizeof的用法.分享给大家供大家参考.具体分析如下: 在C#中,sizeof用来计算类型的大小,单位是字节.有这样的一个类: public class MyUglyClass { public char myChar1; public int myInt; public char myChar2; } 在客户端,试图使用sizeof计算该类型的大小. class Program { static void Main(string[

  • C语言中sizeof()与strlen()函数的使用入门及对比

    sizeof()函数 1,是什么?     sizeof其实就是一个运算符,和那些+,-一样的东西,在程序编译的时候进行解析转换.虽然我们经常见到sizeof后面跟着个小括号,长得和函数差不多,但它和函数完全是两码事. 2,有什么用?     sizeof其实就是用于告诉我们编译器在为某一特定数据或者某种数据类型的数据在存储空间中开辟空间时,开辟的空间大小,以字节为单位. 3,怎么用?     sizeof(类型),或者sizeof(变量)都可以,得到的就是类型或者变量的存储空间.当对变量用的时

  • C语言位运算和sizeof运算符详解

    位运算和sizeof运算符 C语言中提供了一些运算符可以直接操作整数的位,称为位运算,因此位运算中的操作数都必须是整型的.位运算的效率是比较高的,而且位运算运用好的话会达到意想不到的效果.位运算主要有6种:与(&),或(|),取反(~),异或(^),左移(<<),右移(>>). 1.位运算中的类型转换 位运算都必须进行Integer Promotion.在进行运算之前,都必须将char型.short型的数据转换为int或者unsigned int型再参与运算. 如下面这段程

  • C++无法重载点符号、::、sizeof等的原因

    大多数的运算符能够被程序员重载.例外的是:     . (点符号) :: ?: sizeof 并没有什么根本的原因要禁止重载?:.仅仅是因为,我没有发现有哪种特殊的情况需要重载一个三元运算符.注意一个重载了 表达式1?表达式2:表达式3 的函数,不能够保证表达式2:表达式3 中只有一个会被执行. Sizeof 不能够被重载是因为内建的操作(built-in operations),诸如对一个指向数组的指针进行增量操作,必须依靠它.考虑一下: X a[10]; X* p = &a[3]; X* q

  • php检测数组长度函数sizeof与count用法

    本文实例讲述了php检测数组长度函数sizeof与count用法.分享给大家供大家参考.具体如下: 在php检测数组长度的函数有sizeof count 下面看个简单实例: 复制代码 代码如下: $colorlist = array("apple"=>"red", "grass"=>"green","sky"=>"blue","night"=>

  • sizeof()的简单介绍

    (一)基本概念 sizeof操作符以字节形式给出了其操作数的存储大小.操作数可以是一个表达式或括在括号内的类型名.操作数的存储大小由操作数的类型决定. (二)使用方法 1.用于数据类型 sizeof使用形式:sizeof(type) ,如sizeof(int) 2.用于变量 sizeof使用形式:sizeof(var_name)或sizeof var_name 变量名可以不用括号括住.如sizeof (var_name),sizeof var_name等都是正确形式.带括号的用法更普遍,大多数程

  • C语言中的sizeof操作符用法及和strlen的区别

    一. 定义: sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数.其返回值类型为size_t,在头文件stddef.h中定义.在32位系统中: char的sizeof值为1,char是我们编程能用的最小数据类型. short的sizeof值为2: int.float.long为4: double为8: 所有的指针的sizeof值都为4. 二.语法: sizeof有三种语法形式,如下: 1) sizeof( object ); //

  • 解析一个有关sizeof用法的题目--sizeof(i++)

    复制代码 代码如下: #include <stdio.h>  int main()  {  int i;  i = 10;  printf("%d\n", i);  printf("%d\n", sizeof(i++));  printf("%d\n", i);  return 0;  } 这三行输出应该是什么?答案是:10410第三个为什么不是11? i为什么没有自增?请看C++标准;5.3.3 sizeofThe sizeof o

  • C语言中关于sizeof 和 strlen的区别分析

    1.编译时计算运算符sizeof,可用类型或变量做参数,计算占用内存的大小.sizeof后若是类型必须加括弧,若是变量名可不加括弧.sizeof(x)可用来定义数组维数如: 复制代码 代码如下: printf("%d\n", sizeof(short)); 输出的结果为短整型的长度2.用结构类型或变量做参数时,sizeof 返回实际的大小,当用于静态数组时,sizeof 返回全部数组的尺寸.sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 2.运行时计算strlen,

  • 浅析C语言中的sizeof

    这是一个依赖于编译系统的值,一般定义为typedef unsigned int size_t;编译器林林总总,但作为一个规范,都会保证char.signedchar和unsigned char的sizeof值为1,毕竟char是编程能用的最小数据类型.MSDN上的解释为:The sizeof keyword gives the amount of storage, in bytes, associated with avariable or atype (including aggregate

随机推荐