C语言中sizeof的用法

如题所述

第1个回答  2022-07-29
  sizeof是C/C++中的一个操作符(operator),作用就是返回一个对象或者类型所占的内存字节数。返回值类型为size_t,在头文件stddef.h中定义

  这是一个依赖于编译系统的值,一般定义为typedef unsigned int size_t;编译器林林总总,但作为一个规范,都会保证char、signed

  char和unsigned char的sizeof值为1,毕竟char是编程能用的最小数据类型。

  MSDN上的解释为:

  The sizeof keyword gives the amount of storage, in bytes, associated with avariable or a

  type (including aggregate types). This keyword returns a value of type

  size_t.

  2、语法:

  sizeof有三种语法形式,如下:

  1) sizeof( object ); // sizeof( 对象 );

  2) sizeof( type_name ); // sizeof( 类型 );

  3) sizeof object; // sizeof 对象;

  所以一下三种sizeof的使用都是对的

  复制代码 代码如下:

  #include

  main()

  {

  int b;

  printf("%dn",sizeof b);

  printf("%dn",sizeof(b));

  printf("%dn",sizeof(int));

  }

  4、基本数据类型的sizeof

  这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系

  统相关的,所以在不同的系统下取值可能不同,这务必引起我们的注意,尽量不要在

  这方面给自己程序的移植造成麻烦。一般的,在32位编译环境中,sizeof(int)的取值为4。

  5、指针变量的sizeof

  等于计算机内部地址总线的宽度。所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以

  字节为单位),可以预计,在将来的64位系统中指针变量的sizeof结果为8。

  指针变量的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针变量所占内存大小相等,所以

  MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构(使用

  指向结构体的指针)。

  6、数组的sizeof

  数组的sizeof值等于数组所占用的内存字节数,如:

  char a1[] = "abc";

  int a2[3];

  sizeof( a1 ); // 结果为4,字符 末尾还存在一个NULL终止符

  sizeof( a2 ); // 结果为3*4=12(依赖于int)

  sizeof当作了求数组元素的个数是不对的,求数组元素的个数有下面两种写法:int c1 = sizeof( a1 )

  / sizeof( char ); // 总长度/单个元素的长度

  int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长度/第一个元素的长度。注意数组名做函数参数传递

  时退化为指针。

  7、结构体的sizeof

  struct S1

  {

  char c;

  int i;

  };

  sizeof的结果等于对象或者类型所占的内存字节数,好吧,那就让我们来看看S1的内存分配情况:S1 s1

  = { 'a', 0xFFFFFFFF };s1的地址为0x0012FF78,其数据内容如下:

  0012FF78: 61 CC CC CC FF FF FF FF中间夹杂了3个字节的CC看看MSDN上的说明:When applied to a

  structure type or variable, sizeof returns the actual size, which may

  include padding bytes ed for alignment.

  这就是字节对齐!为什么需要字节对齐计算机组成原理教导我们这样有助于加快计算机的取数速度,否则

  就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数

  据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的`地址上,让宽度为4的基本

  数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能

  需要加入填充字节,所以整个结构体的sizeof值就增长了。

  1、sizeof是运算符,跟加减乘除的性质其实是一样的,在编译的时候进行执行,而不是在运行时才执行。

  那么如果编程中验证这一点呢?

  复制代码 代码如下:

  #include

  using namespace std;

  int main()

  {

  int i=1;

  cout<

  sizeof(++i);

  cout<

  return 1;

  }

  输入结果为 1

  1

  sizeof 中的++i 的副作用并没有显示出来,原因只可能有一个,在编译的时候sizeof执行以后将++i 处理了,++i 的副作用因此被消除了。如果sizeof 是在运行时进行的话,则肯定要注意++i 。实际上sizeof的实现应该是用宏来做的,宏在编译时进行执行。具体实现可以参考下面。

  2、sizeof('a')在C语言中的结果是4,在C++中结果是1,看过某篇文章说C中sizeof侧重于“数”,而C++中sizeof更侧重于“字符”。

  3、文章中讲了两个用宏实现sizeof的经典应用

  复制代码 代码如下:

  //适用于非数组

  #define _sizeof(T) ((size_t)((T*)0 + 1))

  //适用于数组

  #define array_sizeof(T) ((size_t)(&T+1)-(size_t)(&T))

  先举两个小例子说明两个宏的应用,对于第一个如 _sizeof(int); 的结果就是4;对于第二个先声明一个大小为4的数组int a[4];那么array_sizeof(a)结果为16.

  对于非数组的宏定义,先是将0转换为T*类型的指针所指向的地址(此时地址为0)。然后对T类型的地址加1,相当于加上了T类型的大小(即得到了非数组T的大小)。前面的size_t只是将地址转化为int型的整数返回。

  一个简单的例子:int* p; p=p+1; ——p是一个int*类型的指针, p+1在地址空间上相当于加上了4个字节。

  对 于数组的宏定义,类似于非数组的宏定义,为了方便理解,这里可以把数组T看成一个用户自定义的类型,&T表示数组类型的指针,对于数组类型指针加 1相当于在地址上加上了该数组大小。由于是用户自定义的类型所以不能强制将0转化为数组类型的地址,只能用加1后的地址减去之前的地址,得到的差值就是数 组本身所占的字节大小。

  拓展阅读:C语言变量理解

  一、变量的概念

  程序设计就是让计算机按照一定的指令来进行工作,可以说数据的处理是程序设计的主要任务。那么数据是怎么加入到计算机的内存中呢?计算机最初的功能就是能够存储数据并处理数据的机器。那么数据是怎么加入到计算机的内存中呢?在学习程序设计之前,很多学生对计算机的硬件设施都大概已经很熟悉了。计算机的硬件设施中有一个区域是用来存储数据的,计算机在工作的过程中会频繁的从这个区域读入和读出数据。要想让计算机按照某些指令(程序)自动工作,首先必须把数据存储到计算机的存储空间中。在某种计算机语言中实现这种数据存储功能的就是变量。变量就是计算机内存中的某一个存储单元。

  二、变量的定义

  C语言中变量在使用之前必须先对其进行定义,变量的定义的一般形式如下:【存储类别】数据类型变量名;其中存储类别是可以省略的。

  1、存储类别计算机的内存一般分为三个部分:1)程序区;2)静态存储区;3)动态存储区;为了高效的发挥计算机的功能,不同类型的变量存放在不同的内存区域。变量的存储类别决定了变量中的数据在计算机内存中的存储位置。C语言中局部变量存放在动态存储区,全局变量或者静态变量存放在静态存储区。

  2、数据类型在用程序处理问题之前,首先必须确定用何种方式描述问题中所涉及到的数据。这个问题在C语言中是由数据类型来决定的。变量的本质表现为在计算机中的存在时间和存储空间。变量的数据类型是用来决定变量在计算机中占用内存空间的大小。比如:整型数据在TC编译系统中占用两个字节的存储空间。C语言变量的类型不仅确定了数据在计算机内存中的存储区域的大小,同时确定了该数据能够参与的各种运算。任何一个C语言的变量必须有确定的数据类型,不管这个变量如何变化,变量的值都必须符合该变量数据类型的规定。

  3、变量的名字通过以上介绍我们知道C语言中的变量就是计算机的某个存储单元,假设你给某个变量赋予了一个数值,对变量的处理其实就是对这个数据的处理。那么计算机是如何快速准确的找到这个数据呢?计算机的内存是以字节为单位进行划分的。每个存储单元都有自己的地址编号,就向宾馆中房间的房间号一样。计算机就是通过地址来准确的确定数据的存储位置。但是对于程序员特别是非专业计算机人士,如果用计算机内存地址记录数据是非常难操作的。

  为了更好的掌控变量,C语言规定可以给每个变量其一个容易识别的名字。这个名字的命名规则遵循C语言的标识符命名规则。C语言的变量名的命名在遵循C语言标识符规则的前提下,原则上可以是任意长度字符的组合。但是目前很多的C语言编译系统只能识别前31个字符,如果两个变量的前31个字符相同,则编译系统会认为这两个变量时同一个变量。为了避免这种混淆的出现最好避免使用多余31个字符的变量名。变量的理解变量就是计算机中的某个存储单元。定义某个变量本质上就是向计算机申请一些存储区域。这个存储区域的大小由变量的数据类型决定,这个存储区域的位置有变量的存储类类别决定。给变量赋予某个数值,其实就是向该变量对应的存储单元读入数据,对变量的处理就是对这个存储单元中的数据的处理。并且这个存储单元中的数据在程序的运行期间是可以发生变化的。
相似回答