请高手赐教c++中sizeof的原理

2024-11-08 12:16:02
推荐回答(5个)
回答1:

这样的问题最好在技术论坛上问,百度效果不好啊
(网上找来贴的 ,文中还是有sizeof源函数代码的)

一、好首先看看sizeof和strlen在MSDN上的定义:

首先看一MSDN上如何对sizeof进行定义的:
sizeof Operatorsizeof expressionThe sizeof keyword gives the amount of storage, in bytes, associated with a variable 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 array, sizeof returns the size of the entire array. The sizeof operator cannot return the size of dynamically allocated arrays or external arrays.

然后再看一下对strlen是如何定义的:

strlenGet the length of a string.Routine Required Header:strlen size_t strlen( const char *string );Parameterstring:Null-terminated string LibrariesAll versions of the C run-time libraries.Return ValueEach of these functions returns the number of characters in string, excluding the terminal NULL. No return value is reserved to indicate an error.RemarksEach of these functions returns the number of characters in string, not including the terminating null character. 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 = "0123456789";sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针sizeof(*ss) 结果 1 ===》*ss是第一个字符char ss[] = "0123456789";sizeof(ss) 结果 11 ===》ss是数组,计算到\0位置,因此是10+1sizeof(*ss) 结果 1 ===》*ss是第一个字符char ss[100] = "0123456789";sizeof(ss) 结果是100 ===》ss表示在内存中的大小 100×1strlen(ss) 结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前int ss[100] = "0123456789";sizeof(ss) 结果 400 ===》ss表示再内存中的大小 100×4strlen(ss) 错误 ===》strlen的参数只能是char* 且必须是以''\0''结尾的char q[]="abc";char p[]="a\n";sizeof(q),sizeof(p),strlen(q),strlen(p);结果是 4 3 3 2 第二个例子:
class X{int i;int j;char k;};X x;cout<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''结尾的。sizeof还可以用函数做参数,比如:
short f();printf("%d\n", sizeof(f()));输出的结果是sizeof(short),即2。
4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(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);}有关内容见: C++ PRIMER?
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定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式
四、结束语

sizeof使用场合。
1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:
void *malloc(size_t size), size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。2.用它可以看看一类型的对象在内存中所占的单元字节。
void * memset(void * s,int c,sizeof(s))3.在动态分配一对象时,可以让系统知道要分配多少内存。
4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。
5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
6.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

回答2:

sizeof 是运算符。测得的大小单位是 byte.
简单变量 short,long,float,double,等计算简单。int 大小 与编译器有关。

结构大小的计算比较麻烦,因为编译考虑不同变量类型内存对齐。

我们若不用sizeof计算大小,算出的大小与sizeof的结果可能不同。编译器计算大小很简单:分配的终了地址减起始地址。

回答3:

sizeof实际会被编译器替换成常量, 编译器在计算这个常量时是根据一些标准规则进行的. 例如 sizeof(int)=4 sizeof(long)在32位系统中是4,64位系统中是8
这个数字通常只能在编译时确定,至于sizoef(结构)也是一样,而且还与pragma pack的指定值有关.

源代码的话可以参考gcc,不过还是不建议你去看gcc的源代码.

回答4:

这东西的源码。。。
真高手也不知道,商业机密
不过可以自己写一个,但是有什么用呢
还必须用系统提供函数。
sizeof是官方提供方法,节省开发时间用的
即使拿到源码,离开了C++估计也白费

回答5:

sizeof是运算符,可用于任何变量名、类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号。

它在编译时起作用,而不是运行时。

详见百科:
http://baike.baidu.com/view/1356720.htm
百科是讲得很详细的
主要是存取结构,
你要源代码,不会是汇编嘛?
或者机器码

头疼