关于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很喜欢用此方法,呵呵..