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;
    }
  • 相关阅读:
    CodeForces 7B
    CodeForces 4D
    离散化
    线段树入门
    洛谷 P3951 小凯的疑惑(赛瓦维斯特定理)
    Codeforces 1295D Same GCDs (欧拉函数)
    Codeforces 1295C Obtain The String (二分)
    Codeforces 1295B Infinite Prefixes
    Codeforces 1295A Display The Number(思维)
    Codeforces 1294F Three Paths on a Tree(树的直径,思维)
  • 原文地址:https://www.cnblogs.com/wangbogong/p/3112762.html
Copyright © 2011-2022 走看看