zoukankan      html  css  js  c++  java
  • sizeof运算符

      sizeof运算符是C/C++比较灵活知识点,本节总结它们的常见用法与错误。

      sizeof运算符用于计算数据在内存中占有的字节数。如果sizeof运算于数组,它将会计算数组占有的内存空间。但是需要注意的是,如果采用指针在函数直接传递数据,编译器是无法知道数组的长度,因此,sizeof运算将退化成对指针的运算:

    #include "stdafx.h"
    int funa(char my_str[100])
    {
        cout<<sizeof(my_str)<<endl;    //输出:4
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        char my_str[] = "l love lili";
        char*p = my_str;
        cout<<sizeof(my_str)<<endl;    //输出:12
        cout<<sizeof(p)<<endl;         //输出:4
        system("pause");
        return 0;
    }

       那么,如何才能让程序正常输出100个字节?为了解决这个问题,需要利用C++的“数组引用”作为参数:

    int funa(char (&my_str)[100])
    {
        cout<<sizeof(my_str)<<endl;    //输出:100
    }

    但是上面的函数也仅能接受长度为100字符数组,传入其他参数将会报错,为此,为了让程序更具有泛化能力,我们将上面的函数变成模板函数:

    template<typename T, size_t N>
    int funa(typename (&T)[N])
    {
        cout<<sizeof(my_str)<<endl;    //输出:N
    }

      借此机会,我们进一步讨论C++类相关的内存空间分配。首先,我们看一下空类的大小:

    //Null_Class.h
    
    #ifndef CLASS_NULL
    #define CLASS_NULL
    
    #include "stdafx.h"
    
    class NullClass
    {
    public:
        void fun_a();
    };
    
    #endif
    
    //main.cpp
    #include "stdafx.h"
    #include "class.h"
    
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        NullClass null_class;
        cout<<sizeof(null_class);   //输出:1
        system("pause");
        return 0;
    }

      尽管当前类属于空类,仍然占有一个字节的内存空间。这是由于类被实例化造成的,每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址。

      而对于非空类(无继承关系)其空间大小等于其成员数据的大小,需要注意的是:1)类中的static成员变量存放于全局的数据存储空间,并不占有实例化类的空间大小,2)为了快速的访问数据,编译器会对C++类中的成员变量自动内存对齐:自动按照成员函数内存最大的对齐。

    // claass.h 
    #ifndef CLASS_H
    #define CLASS_H
    
    #include "stdafx.h"
    
    class Base_Class
    {
    public:
        void fun_a();
    private:
        int value_a;
      static int value_b;
      char value_c; };
    #endif //main.cpp #include "stdafx.h" #include "class.h" int _tmain(int argc, _TCHAR* argv[]) { BaseClass base_class; cout<<sizeof(base_class); //输出:8 = int类型内存空间大小(4) + char类型对齐int类型的内存空间大小(4) system("pause"); return 0; }

     如果类存在着继承关系,需要注意三点:1)子类的内存空间大小需要加上父类的数据成员的空间大小;2)若存在虚函数继承,需要在内存中增加一个虚函数指针的存储空间。它们在内存中的存放顺序是:虚函数指针,父类数据成员,自己的数据成员。

    //  class.h 文件
    #ifndef CLASS_H
    #define CLASS_H
    
    #include "stdafx.h"
    
    class BaseClass
    {
    public:
        void fun_a();
        virtual void fun_b(){cout<<"Base class"<<endl;}
    private:
        int value_a;
        static int value_c;
        char value_b
     };
    
    class DerivateClass : public BaseClass
    
    {
    
    public:
        virtual void fun_b(){cout<<"Derivative Class"<<endl;};
    private:
        int value_d;
    }; #endif
    
    //main.cpp文件
    #include "stdafx.h"
    #include "class.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        BaseClass base_class;
        DerivateClass derivate_class;
        cout<<sizeof(base_class)<<endl;            //输出:12 = 虚函数指针长度大小(4) + int字节大小(4) +char字节对齐int字节大小(4) 
        cout<<sizeof(derivate_class)<<endl;       //输出:16 = BaseClass的大小 + 自己成员变量的大小(4)
        system("pause");
        return 0;
    }
  • 相关阅读:
    java设计模式演示样例
    一步一步写算法(之排序二叉树)
    收集经常使用的.net开源项目
    jdbc连接数据库
    Android开发系列(二十二):AdapterViewFlipper的功能和使用方法
    ProgressDialog使用总结
    HDU 4916 树分治
    [Unity3D]自制UnityForAndroid二维码扫描插件
    IOS ARC和非ARC文件混用
    让子弹飞Demo版
  • 原文地址:https://www.cnblogs.com/wangbogong/p/3112762.html
Copyright © 2011-2022 走看看