浅谈如何理解C语言中的运算符sizeof _时代人物智库_http://www.ems86.com/index.php
 
时代智库
 
浅谈如何理解C语言中的运算符sizeof
投稿信箱:87610500@163.com   编辑部:电话:010-86109586广告部:电话:010-86109586发行部:电话:010-86109586

浅谈如何理解C语言中的运算符sizeof 
崔庆红
(江苏省盐城广播电视大学东台分校,江苏 东台 224200) 
  摘 要:  本文重点讨论了C语言和C++语言中的运算符sizeof,从该运算符的定义和用 途入手,详细介绍了它的使用方法,并通过实例进行讲析,更有助于对该运算符进行理解。 
  关键词: C语言;sizeof 
  中图分类号: TP312 文献标识码:A    文章编号: 1008-7508( 2010)011-0099-02
  在C语言和C++语言中,利用运算符sizeof用于获得某一数据或数据类型的对象在内存中 所占的字节数。因为同一种数据类型在不同的编译系统中所占空间不一定相同。例如,在基 于16位的编译系统中,int型数据占用2个字节,但现在普遍使用的是基于32位的编译系统, int型数据要占用4个字节,以后的编译系统会怎么样处理,我们是无法预测的。因此,为 了提高程序的可移植性,延长软件的生命周期,不要对一种数据类型所占空间大小做任何假 定,程序中应当通过sizeof操作符获得这一信息。还有,就是在进行动态分配某一类型的对 象时,所分配的字节数也是与当前系统有关,当用户不知道分配了多少个字节时,此时运算 符sizeof就可以发挥它的作用了。笔者结合在教学中的实践知识,谈谈对该运算符的理解。

   一、正确理解运算符sizeof的涵义及用途 
  1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。Sizeof 的操作结果类型是size_t,在一般的编译系统中定义为
Typedef unsigned size_t;
因此size_t等同于unsigned。
例如:  
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))
  3.在进行动态分配某一数据对象时,可以知道系统分配了多少内存。 
  4.便于一些特定的数据类型的扩充,在windows中就有很多结构类型(比如指针、结构类 型)就有一个专用的字段是用来放该类型的字节大小。 
  5.由于操作数的字节数在运算时可能出现一些变化,在涉及到具体的操作数字节大小时 ,最好用sizeof来代替常量计算,这样可以避免一些错误。 
  6.如果操作数是函数中的数组形参或函数类型的形参,利用运算符sizeof可以给出其指 针的大小。

  二、仔细辨别sizeof与strlen的不同  
  sizeof运算符可以获取某个类型的对象在内存中所占的单元字节数;strlen函数可以求 得某个字符串的长度。首先看看sizeof和strlen在MSDN上的定义:
在MSDN上对sizeof是这样进行定义的:
sizeof Operator
sizeof expression
The sizeof keyword gives the amount of storage, in bytes, associated with a vari able or a type (including aggregate types). This keyword returns a value of type  size_t.The expression is either an identifier or a type-cast expression (a type  specifier enclosed in parentheses).When applied to a structure type or variable , sizeof returns the actual size, which may include 
padding bytes inserted for alignment. When applied to a statically dimensioned a rray, sizeof returns the size of the entire array. The sizeof operator cannot re turn the size of dynamically allocated arrays or external arrays.
  在MSDN上对strlen是这样定义的: 
strlen
Get the length of a string.Routine Required Header:
strlen <string.h>
size_t strlen( const char *string );Parameter string:Null-terminated string Lib raries All versions of the C run-time libraries.Return Value Each of these funct ions returns the number of characters in string, excluding the terminal NULL. No  return value is reserved to indicate an error.Remarks Each of these functions r eturns the number of characters in string, not including the terminating null ch aracter. wcslen is a wide-character version of strlen; the argument of wcslen is  a wide-character string. wcslen and strlen behave identically otherwise.
  再来看下面这个例子:
  例如: 
char *ss = “123456789”;
sizeof(ss) 结果为 4 , ss是指向字符串常量的字符指针
sizeof(*ss) 结果为 1 ,*ss是第一个字符
char ss[] = “123456789”;
sizeof(ss) 结果为 10 ,ss是数组,计算到字符\0位置,因此是10
sizeof(*ss) 结果为 1,*ss是第一个字符
char ss[100] = “123456789”;
sizeof(ss) 结果是为100 ,ss表示在内存中的大小 100×1(字符型占1个字节)
strlen(ss) 结果是为9,strlen是个函数内部实现是用一个循环计算到字符\0为止之前
int ss[100] = “123456789”;
sizeof(ss) 结果为 400,ss表示在内存中的大小 100×4(整型占4个字节)
strlen(ss) 错误 ,strlen的参数只能是char* 且必须是以“\0”结尾的
char q[]=“abcde”;
char p[]=“ab\n”;
sizeof(q),sizeof(p),strlen(q),strlen(p);
结果是 6 4 5 3      
  通过与strlen的比较,可以发现它们的定义及使用方法都不相同,在使用时不可将它们混淆 。

  三、熟练掌握运算符sizeof的运算方法  
  先来看下面这两个例子:
  第一个例子:
class X
{
int i;
int j;
char k;
};
X x;
cout<<sizeof(X)<<endl; 结果为 12 ,内存补齐
cout<<sizeof(x)<<endl; 结果为 12 ,同上
  第二个例子:
char szPath[MAX_PATH]
如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,但是将szPath作为虚参声明 时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小) 。
   通过以上这两个例子,对sizeof可以理解如下:
  1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该 类型保证能容纳实现所建立的最大对象的字节大小。 
  2.sizeof是运算符,strlen是函数。 
  3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以“\0”结尾的。s izeof还可以用函数做参数,比如: 
short f();
printf(“%d\n”, sizeof(f()));
输出的结果是sizeof(short),即2。 
  4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。 
  5.大部分编译程序在编译的时候就把sizeof计算过了是类型或是变量的长度,这就是si zeof(x)可以用来定义数组维数的原因 
char str[20]=“0123456789”;
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
  6.strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,不是类型占内 存的大小。 
  7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个 操作符不是个函数。 
  8.当适用于一个结构类型或变量时,sizeof 返回实际的大小, 当适用于静态数组空间 ,sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的 数组的尺寸。
  9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如: 
fun(char [8])
fun(char [])
  都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知 道数组的大小,如果想在函数内知道数组的大小, 需要这样做:进入函数后用memcpy拷贝 出来,长度由另一个形参传进去 
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
  10.计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU 取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把 结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样 做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生 成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际 不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数 据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对 齐。 
  11.sizeof操作符不能用于函数类型、不完全类型或位字段。不完全类型指具有未知存 储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等 。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为c har char_v[MAX]且MAX未知,sizeof(void)都不是正确形式 。
  总之,在C语言中应正确使用运算符sizeof,才可以正确获取某一类型的对象在内存中 所占的单元字节数,由系统决定某一动态对象所占的字节数,或进行一些类型扩充。


收稿日期: 2010-10-08
作者简介:   崔庆红(1977~),江苏东台人,江苏省盐城广播电视大学东台分校讲师。研究 方向:计算机专业教学。
 

 

2012-11-12 13:14:02 - http://www.ems86.com/
“虚实”在中国山水画中的作用 4/2
新茗谷雨翠青青,紫砂名壶有长兴。(作者单位:长兴雉城金陵陶坊) 10/23
真知困得 ——魏军科国画品读 田荣军          1/20
美术馆展览品牌化管理  1/17
现代室内空间设计中融入传统木雕艺术的策略 1/17
 

组织机构

收录证书

关于我们 在线投稿 汇款方式 全站搜索 友情链接

        说明:部分文章源于网络转载,原作者无法查证,如有侵犯版权或不同意网络资源共享,请联系指出,我们会立即进行改正或删除有关内容。
        咨询电话:029-86191817  投稿信箱:87610500@163.com