关于sizeof的一些东西

今天写POJ 2737 大数运算的时候,突然发现自己以前关于sizeof运算符的理解有点错误,于是认真查阅了一点资料,编程实现了一些东西,写篇文章总结一下。

 

先看下MSDN上关于sizeof的解释:

Visual C++ Language Reference

sizeof Operator

Yields the size of its operand with respect to the size of type char.

sizeof unary-expression

sizeof ( type-name )

 Remarks

The result of the sizeof operator is of type size_t, an integral type defined in the include file STDDEF.H. This operator allows you to avoid specifying machine-dependent data sizes in your programs.

The operand to sizeof can be one of the following:

  • A type name. To use sizeof with a type name, the name must be enclosed in parentheses.
  • An expression. When used with an expression, sizeof can be specified with or without the parentheses. The expression is not evaluated.

When the sizeof operator is applied to an object of type char, it yields 1. When the sizeof operator is applied to an array, it yields the total number of bytes in that array, not the size of the pointer represented by the array identifier. To obtain the size of the pointer represented by the array identifier, pass it as a parameter to a function that uses sizeof. For example:

 Example

// expre_sizeof_Operator.cpp

// compile with: /EHsc

#include <iostream>

 

size_t getPtrSize( char *ptr )

{

   return sizeof( ptr );

}

 

using namespace std;

int main()

{

   char szHello[] = "Hello, world!";

 

   cout  << "The size of a char is: "

         << sizeof( char )

         << "\nThe length of " << szHello << " is: "

         << sizeof szHello

         << "\nThe size of the pointer is "

         << getPtrSize( szHello ) << endl;

}

 Sample Output

The size of a char is: 1

The length of Hello, world! is: 14

The size of the pointer is 4

When the sizeof operator is applied to a class, struct, or union type, the result is the number of bytes in an object of that type, plus any padding added to align members on word boundaries. The result does not necessarily correspond to the size calculated by adding the storage requirements of the individual members. The /Zp compiler option and the pack pragma affect alignment boundaries for members.

The sizeof operator never yields 0, even for an empty class.

The sizeof operator cannot be used with the following operands:

  • Functions. (However, sizeof can be applied to pointers to functions.)
  • Bit fields.
  • Undefined classes.
  • The type void.
  • Dynamically allocated arrays.
  • External arrays.
  • Incomplete types.
  • Parenthesized names of incomplete types.

When the sizeof operator is applied to a reference, the result is the same as if sizeof had been applied to the object itself.

If an unsized array is the last element of a structure, the sizeof operator returns the size of the structure without the array.

The sizeof operator is often used to calculate the number of elements in an array using an expression of the form:

sizeof array / sizeof array[0]

 

大致翻译如下(错了表怪我):

参考visual C++

sizeof 运算符

返回其操作数的字节数(也是char类型字节的倍数).

sizeof 一元表达式

sizeof ( 类型 )

 Remarks

Sizeof返回的结果是size_t类型(定义在STDDEF.H中的一种整数类型),它可以让你在程序中避免涉及与机器有关的数据字节数(避免了例如int等在各机器中实际所占字节不同的情况)

Sizeof的操作数如下

  • 数据类型,必须用括号.
  • 表达式,括号随意..

sizeof的操作数是char时返回1,当其应用到一个数组时,返回整个数组的字节长度,而不是数组指针(就是数组名)的大小,想要获得数组指针的大小,可以把数组的名字(标识符)当作参数传给一个函数,例如:

 Example

// expre_sizeof_Operator.cpp

// compile with: /EHsc

#include <iostream>

 

size_t getPtrSize( char *ptr )

{

   return sizeof( ptr );

}

 

using namespace std;

int main()

{

   char szHello[] = "Hello, world!";

 

   cout  << "The size of a char is: "

         << sizeof( char )

         << "\nThe length of " << szHello << " is: "

         << sizeof szHello

         << "\nThe size of the pointer is "

         << getPtrSize( szHello ) << endl;

}

 Sample Output

The size of a char is: 1

The length of Hello, world! is: 14

The size of the pointer is 4

SOURCE CODE:

visual studio:


int main()
{
    
char a[100= "123456765";
    
char* p = a;

    
int n1= sizeof(a);
    
int n2 = sizeof(p);

    cout
<<n1<<endl<<n2<<endl;

}

----------------------------------------------------------------------------------------------

结果:
100
4


反汇编调试如下:


    
char a[100= "123456765";
004135D8  mov         eax,dword ptr [
string "123456765" (415860h)] 
004135DD  mov         dword ptr [ebp
-6Ch],eax 
004135E0  mov         ecx,dword ptr ds:[415864h] 
004135E6  mov         dword ptr [ebp
-68h],ecx 
004135E9  mov         dx,word ptr ds:[415868h] 
004135F0  mov         word ptr [ebp
-64h],dx 
004135F4  push        5Ah  
004135F6  push        
0    
004135F8  lea         eax,[ebp
-62h] 
004135FB  push        eax  
004135FC  call        @ILT
+470(_memset) (4111DBh) 
00413601  add         esp,0Ch 
    
char* p = a;
00413604  lea         eax,[ebp-6Ch] 
00413607  mov         dword ptr [ebp-78h],eax 

    
int n1= sizeof(a);
0041360A  mov         dword ptr [ebp
-84h],64h 
    
int n2 = sizeof(p);
00413614  mov         dword ptr [ebp-90h],4 

OD:


00413618    8D45 9E         lea     eax, dword ptr [ebp-62]
0041361B    
50              push    eax
0041361C    E8 BFDBFFFF     call    004111E0
00413621    83C4 0C         add     esp, 0C
00413624    8D45 94         lea     eax, dword ptr [ebp-6C]
00413627    8945 88         mov     dword ptr [ebp-78], eax
0041362A    C785 7CFFFFFF 
6>mov     dword ptr [ebp-84], 64
00413634    C785 70FFFFFF 0>mov     dword ptr [ebp-90], 4
0041363E    8BF4            mov     esi, esp

 


以上代码说明了原因:

数组顺序存储在EBP-6C,EBP-6C就是a的地址,p存储在EBP-78,[EBP-78]才是a的地址,加不加方括号是不同的,涉及汇编里地址的索引方法问题..


    
int n1= sizeof(a);
0041360A  mov         dword ptr [ebp
-84h],64h 
    
int n2 = sizeof(p);
00413614  mov         dword ptr [ebp-90h],4

这两句好像是表示sizeof运算符的结果在编译时就确定了,直接得到常量..

sizeof运算符应用于自定义类型,如class struct 联合体,其返回值(说返回值不合适,sizeof是操作符,不是函数,)是这个类型的(实际)字节数,可能包含一些插入字节或者机器字节对齐字节,而不是返回其成员所占空间精确的结果,修改编译选项可以调整这个(具体不翻译了)


class A{
private:
    
int a;
    
char b;
    
char c;
};

int main()
{
    A a;
    A
& b = a;
    
    cout
<<sizeof a<<endl<<sizeof b<<endl;

}

-------------------------------------------------------------------------------

结果:

8

8

这个例子说明自定义类型存在字节对齐,还说明引用果真可以和原类型sizeof后返回结果一致


Sizeof从不返回1,即使其操作数是一个空类


class A{};
int main()
{
    A a;
    cout
<<sizeof a<<endl;
}
---------------------------------------
结果:
1

Sizeof不可以应用在一下操作数上

  • Functions. (However, sizeof can be applied to pointers to functions.)
  • Bit fields.
  • Undefined classes.
  • The type void.
  • Dynamically allocated arrays.
  • External arrays.
  • Incomplete types.
  • Parenthesized names of incomplete types.

sizeof操作符应用到一个应用上,其结果和原类型本身一致.

If an unsized array is the last element of a structure, the sizeof operator returns the size of the structure without the array.

不翻译

Sizeof的一个很大的作用就是计算数组的长度,通过如下的表达式:

sizeof array / sizeof array[0]


int main()
{
    
int ary[10= {1};
    cout
<<sizeof ary/sizeof ary[0]<<endl;//<beginning in C++>
}
------------------------------------------------------------------------
结果:
1

Ivor Horton很喜欢用此方法,呵呵..

posted @ 2009-01-27 21:45  端木  阅读(485)  评论(0编辑  收藏  举报