sizeof用法分析1

来源:百度文库 编辑:神马文学网 时间:2024/07/07 08:14:39
1、什么是sizeof    首先看一下sizeof在msdn上的定义:    The 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.    看到return这个字眼,是不是想到了函数?错了,sizeof不是一个函数,你见过给一个函数传参数,而不加括号的吗?sizeof可以,所以sizeof不是函数。网上有人说sizeof是一元操作符,但是我并不这么认为,因为sizeof更像一个特殊的宏,它是在编译阶段求值的。举个例子:cout<cout<cout<<1<cout<cout<cout<<4<cout< 
    (1)sizeof(object)
    也就是对对象使用sizeof,也可以写成sizeof object 的形式    (2)sizeof(typename)
    也就是对类型使用sizeof,注意这种情况下写成sizeof typename是非法的。下面举几个例子说明一下:
int i = 2;
cout<cout<cout<cout<cout<cout<3、数据类型的sizeof(1)C++固有数据类型    32位C++中的基本数据类型,也就char,short int(short),int,long int(long),float,double, long double
大小分别是:1,2,4,4,4,8, 10。    考虑下面的代码:cout<typedef long DWORD;
cout<<(sizeof(short) == sizeof(WORD))<cout<<(sizeof(long) == sizeof(DWORD))<double f2(){return 0.0;}
void f3(){}cout<cout<cout<cout<cout<cout<cout<int b[20] = {3, 4};
char c[2][3] = {"aa", "bb"};
cout<cout<cout<    数组a的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是7。c是多维数组,占用的空间大小是各维数的乘积,也就是6。可以看出,数组的大小就是他在编译时被分配的空间,也就是各维数的乘积*数组元素的大小。    结论:数组的大小是各维数的乘积*数组元素的大小。    这里有一个陷阱:int *d = new int[10];cout<cout<cout<cout<cout<6、向函数传递数组的问题考虑下面的问题:
#include
using namespace std;int Sum(int i[])
{
int sumofi = 0;
for (int j = 0; j < sizeof(i)/sizeof(int); j++) //实际上,sizeof(i) = 4
{
  sumofi += i[j];
}
return sumofi;
}int main()
{
int allAges[6] = {21, 22, 22, 19, 34, 12};
cout<system("pause");
return 0;
}    Sum的本意是用sizeof得到数组的大小,然后求和。但是实际上,传入自函数Sum的,只是一个int 类型的指针,所以sizeof(i)=4,而不是24,所以会产生错误的结果。解决这个问题的方法使是用指针或者引用。    使用指针的情况:
int Sum(int (*i)[6])
{
int sumofi = 0;
for (int j = 0; j < sizeof(*i)/sizeof(int); j++) //sizeof(*i) = 24
{
  sumofi += (*i)[j];
}
return sumofi;
}int main()
{
int allAges[] = {21, 22, 22, 19, 34, 12};
cout<system("pause");
return 0;
}
    在这个Sum里,i是一个指向i[6]类型的指针,注意,这里不能用int Sum(int (*i)[])声明函数,而是必须指明要传入的数组的大小,不然sizeof(*i)无法计算。但是在这种情况下,再通过sizeof来计算数组大小已经没有意义了,因为此时大小是指定为6的。
使用引用的情况和指针相似:int Sum(int (&i)[6])
{
int sumofi = 0;
for (int j = 0; j < sizeof(i)/sizeof(int); j++)
{
  sumofi += i[j];
}
return sumofi;
}int main()
{
int allAges[] = {21, 22, 22, 19, 34, 12};
cout<system("pause");
return 0;
}
    这种情况下sizeof的计算同样无意义,所以用数组做参数,而且需要遍历的时候,函数应该有一个参数来说明数组的大小,而数组的大小在数组定义的作用域内通过sizeof求值。因此上面的函数正确形式应该是:
#include
using namespace std;int Sum(int *i, unsigned int n)
{
int sumofi = 0;
for (int j = 0; j < n; j++)
{
  sumofi += i[j];
}
return sumofi;
}int main()
{
int allAges[] = {21, 22, 22, 19, 34, 12};
cout<system("pause");
return 0;
}7、字符串的sizeof和strlen    考虑下面的问题:char a[] = "abcdef";
char b[20] = "abcdef";
string s = "abcdef";cout<cout<cout<cout<cout<cout<cout<cout<   strlen是寻找从指定地址开始,到出现的第一个0之间的字符个数,他是在运行阶段执行的,而sizeof是得到数据的大小,在这里是得到字符串的容量。所以对同一个对象而言,sizeof的值是恒定的。string是C++类型的字符串,他是一个类,所以sizeof(s)表示的并不是字符串的长度,而是类string的大小。strlen(s)根本就是错误的,因为strlen的参数是一个字符指针,如果想用strlen得到s字符串的长度,应该使用sizeof(s.c_str()),因为string的成员函数c_str()返回的是字符串的首地址。实际上,string类提供了自己的成员函数来得到字符串的容量和长度,分别是Capacity()和Length()。string封装了常用了字符串操作,所以在C++开发过程中,最好使用string代替C类型的字符串。
8、从union的sizeof问题看cpu的对界    考虑下面问题:(默认对齐方式)union u
{
  double a;
  int b;
};union u2
{
  char a[13];
  int b;
};union u3
{
  char a[13];
  char b;
};cout<cout<cout<union u2
{
  char a[13];
  int b;
};union u3
{
  char a[13];
  char b;
};
#pragma pack(8)cout<cout< 9、struct的sizeof问题 因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下) struct s1{  char a;  double b;  int c;  char d; }; struct s2{  char a;  char b;  int c;  double d;}; cout<