C/C++ :Sizeof 的用法

Sizeof有以下特点:

  1. Sizeof是C/C++中的一个运算符,不是一个函数,返回值为size_t
  2. sizeof不能被编译成机器码,编译过程中就会计算sizeof的具体值,然后用值替换掉sizeof ()。所以可以用sizeof() 来定义数组的维数。
  3. sizeof ()里面的内容也不能被编译,而是被替换成类型。
  4. sizeof 后面可以直接加变量名,不用加();sizeof一个类型时,必须加()
  5. sizeof的参数可以有 内置类型(如char、int、double、bool、string、指针 等)、struct/class自定义结构体、带返回值的函数、数组。不能sizeof一个返回值是void的函数,编译会报warning,但程序还是能正常执行的。Sizeof一个带返回值的函数,结果等同于sizeof返回值的类型。Sizeof一个数组得到的是这个数组总的内存大小。
  6. sizeof与strlen的区别,后者是函数,且参数必须是char*,后者在程序运行过程中才能被计算出来。前者计算的是字符串所占内存空间,所以会加上字符串结束符’\0’所占的1个字节;后者计算的字符串长度,不加字符串结束符’\0’。

以下是一个sizeof知识相关的代码示例。其中,需要注意以下几点。

  1. sizeof (a = 6),a= 6是不被编译的,执行完之后a的值依然是9.
  2. Sizeof(str)得到的是数组的长度,sizeof(str_0)得到的是字符串所占内存的大小,包含’\0’所占的1个字节。
  3. sizeof (str_1)得到的是二维数组总的内存大小,strlen (str_1)则是错误的写法,因为strlen的参数只能是char*。
  4. Sizeof一个C++的string类型,是一个特殊的存在,有帖子中这样解释:string的实现在各库中可能有所不同,但是在同一库中相同一点是,无论你的string里放多长的字符串,它的sizeof()都是固定的,字符串所占的空间是从堆中动态分配的,与sizeof()无关。我使用gcc 5.0,得到的sizeof(string)结果是32.
  5. 一个空结构体(struct 或class),不包含任何成员变量,不包含虚函数,则sizeof这个结构体的结果等于1。
  6. 一个结构体(struct 或class)中包含虚函数,则sizeof的结果需要加上一个指针类型(虚函数表指针)的长度。
  7. sizeof (var[10])是正常的数组var的内存大小,但在fun_test_var(char var[])中,var[]退化成了char *,所以函数内sizeof(var)其实是sizeof(char *),结果为8byte。
//sizeof
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
class empty {
};
class empty_1 :public virtual empty {
};
class empty_2 {
public:  
  int f_int() {int a = 10;return a ;}
  double f_double() {double a = 10.0;return a ;}
  void f_void () {;}
}  ;

class Base{
 public:
  virtual void f(int) {cout<<"base f(int)"<<endl;}
  virtual void f(double) {cout<<"base f(double)"<<endl;}
};

int fun_test_var(char var[]){
  //warning: ‘sizeof’ on array function parameter ‘var’ 
  //  will return size of ‘char*’ [-Wsizeof-array-argument]
  return sizeof(var);
}

int main(int argc, char** argv){
  //https://www.cnblogs.com/wanghetao/archive/2012/04/04/2431760.html
  cout<<sizeof 2<<endl; // 2被解析成int类型的object, sizeof object的用法,合理
  cout<<sizeof(2)<<endl; // 2被解析成int类型的object, sizeof(object)的用法,合理
  cout<<sizeof(int)<<endl;// sizeof(typename)的用法,合理
  //cout<<sizeof int<<endl; // 错误!对于操作符,一定要加()

  int a = 9;
  cout <<" sizeof (a) "<<dec<<sizeof (a = 6)<<endl;
  cout <<" a = "<<a <<endl;

  char str[20] = "123456";
  cout <<" sizeof (str) "<<dec<<sizeof (str)<<endl;
  cout <<" strlen (str) "<<dec<< strlen (str)<<endl;

  char str_0 [] = "123456";
  cout <<" sizeof (str_0) "<<dec<<sizeof (str_0)<<endl;//have '\0' 
  cout <<" strlen (str_0) "<<dec<< strlen (str_0)<<endl;//don't have '\0'  

  char str_1[2][20] = {"123456", "hello"};
  cout <<" sizeof (str_1) "<<dec<<sizeof (str_1)<<endl;
  cout <<" strlen (str_1) "<<dec<< strlen (str_1[0])<<endl;

  string str_2 [2] = {"0123456789 0123456789 0123456789 0123456789", "hello"};
  cout <<" sizeof (str_2) "<<dec<<sizeof (str_2)<<endl;
  cout <<" sizeof (string) "<<dec<<sizeof (string)<<endl;

  cout <<" sizeof (empty) "<<dec<<sizeof (empty)<<endl;
  cout <<" sizeof (empty_1) "<<dec<<sizeof (empty_1)<<endl;
  cout <<" sizeof (empty_2) "<<dec<<sizeof (empty_2)<<endl;
  empty_2 test_2;
  cout <<" sizeof (empty_2.f_int) "<<dec<<sizeof (test_2.f_int())<<endl;
  cout <<" sizeof (empty_2.f_double) "<<dec<<sizeof (test_2.f_double())<<endl;
  //warning: invalid application of ‘sizeof’ to a void type [-Wpointer-arith]
  cout <<" sizeof (empty_2.f_void) "<<dec<<sizeof (test_2.f_void())<<endl;
  
  cout <<" sizeof (Base) "<<dec<<sizeof (Base)<<endl;

  char var [10] ;
  cout <<" sizeof (var[10]) "<<dec<<sizeof (var)<<endl;
  cout <<" fun_test_var(var) "<<dec<<fun_test_var(var)<<endl;
}

参考:https://www.cnblogs.com/wanghetao/archive/2012/04/04/2431760.html

运行结果:

猜你喜欢

转载自blog.csdn.net/zgcjaxj/article/details/105934561