Tagged: sizeof

09

sizeof用法的总结

sizeof几乎是各种笔试必考的知识点,昨天腾讯的笔试就中招了:(
现在总结一下(32位,vs2008,c++),下次再遇到就不怕了!

若想看看sizeof在MSDN是怎么说的话(英文的),请点击打开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
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:
1.A type name. To use sizeof with a type name, the name must be enclosed in parentheses.
2.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:
*/
// expre_sizeof_Operator.cpp
// compile with: /EHsc
#include 
 
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]

首先,要明确sizeof不是函数,也不是一元运算符,它是个类似宏定义的特殊关键字。sizeof()括号内的内容在编译过程中是不被编译的,而是被替代类型,如int a=8;sizeof(a)。在编译过程中,不管a的值是什么,只是被替换成类型int,所以结果为4。如果sizeof(a=6)呢?也是一样地转换成a的类型int,而且a=6不被编译,即执行完sizeof(a=6)后,a的值仍然是8!注意!

接下来通过各种例子说明其用法:
例1(美国某著名计算机软硬件公司2005、2007年面试题):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
struct{
	short a1;
	short a2;
	short a3;
}A;
struct{
	long a1;
	short a2;
}B;
 
int main()
{
	char* ss1="0123456789";
	char ss2[]="0123456789";
	char ss3[100]="0123456789";
	int ss4[100];
	char q1[]="abc";
	char q2[]="a\n";
	char* q3="a\n";
	char *str1=(char *)malloc(100);
	void *str2=(void *)malloc(100);
 
	cout<<sizeof(ss1)<<" ";//4,一个字符指针的大小
	cout<<sizeof(ss2)<<" ";//11,10个字符加1个"\0"
	cout<<sizeof(ss3)<<" ";//100,char型数组预分配100
	cout<<sizeof(ss4)<<" ";//400,int型数组预分配100
	cout<<sizeof(q1)<<" ";//4,还有一个“\0”
	cout<<sizeof(q2)<<" ";//3,“\n”算1个,还有1个“\0”
	cout<<sizeof(q3)<<" ";//4,一个字符指针的大小
	cout<<sizeof(A)<<" ";//6,2×3=6
	cout<<sizeof(B)<<" ";//8,结构体的长度一定是最长的数据元素的整数倍
	cout<<sizeof(str1)<<" ";//4,一个char型指针
	cout<<sizeof(str2)<<" ";//4,一个void型指针
 
	return 0;
}

在这个例子里面,主要有以下几个要注意的地方:
1、指针的大小为4;
2、数组的预分配大小;
3、数组里面的“\0”;
4、结构体的长度是最长的数据元素的整数倍。(这个要说为什么的话又要另一篇长篇大论了,注意涉及CPU的优化规则问题)

例2:

1
2
3
4
char szChar[MAX];
sizeof(szChar);//将会是MAX
void fun(szChar[MAX]){}
sizeof(szChar);//将会是4(指针大小)

这个特别的例子说明了预分配数组与在作为形参的预分配数组的区别!

例3:

1
2
3
4
5
6
char a[] = "abcde ";
int b[20] = {3, 4};
char c[2][3] = { "aa ", "bb "};
sizeof(a);//7,注意空格和“\0”
sizeof(b);//80,20个int型×4
sizeof(c);//6,2×3个char型×1

最后补充几点:
1、unsigned只是影响最高位(符号位),所以sizeof(unsigned int)==sizeof(int);
2、typedef后的自定义类型与原型一样,所以typedef int MYINT;sizeof(MYINT)==sizeof(int);
3、对函数使用sizeof,在编译阶段会被函数返回值的类型取代,所以int fun(){return 0;};sizeof(fun())==sizeof(int);
对于sizeof的用法,基本上就这些了,希望对各位有用,有什么补充的话请赐教:D
参考文章:
《程序员面试宝典》以及

深入理解sizeof

0
comments