美文网首页
C++ 存储持续性,作用域和链接性

C++ 存储持续性,作用域和链接性

作者: zcwfeng | 来源:发表于2023-07-21 00:37 被阅读0次

    C 语言常用小点
    C字符串
    C 基础-指针,函数处理器
    C 文件操作
    JNI 基础 C语言版

    C++ 基础知识点大纲

    [C++ 基础经验知识点]
    C++ 基础代码模板和使用
    C++ 基础-定点模式
    C++ 宏定义
    C++ 指针区分
    C++ 指针特别篇-指针转换和智能指针
    C++ 类的继承和多继承
    C++ this 原理
    C++浅拷贝和深拷贝的原理
    C++ 函数
    C++ 仿函数
    C++ 友元函数理解
    C++ STL
    C++ 模板函数纯虚函数和Java对比
    C++ 函数运算符重载(二)化简版
    C++ 多线程
    C++ 算法包和源码简析
    C++ 存储持续性,作用域和链接性

    自动存储,执行完代码内存自动释放,生命周期由程序控制。 生命周期短再方法等大括号内(代码块内)
    静态存储持续性: static定义,函数外部定义,整个程序结束生命周期结束
    线程存储持续性: thread_local
    动态存储持续性: new 分配 delete释放。 由人工控制。

    代码块作用域

    #include <iostream>
    using namespace std;
    int main()
    {
        int teledeli = 5;
        {
            int teledeli = 20;
            int weight = 30;
            cout << "teledeli:" << teledeli << endl;
            cout << "weight:" << weight << endl;
        }
        cout << "teledeli out:" << teledeli << endl;
        return 0;
    }
    

    结构体和类类似,方法可以定义在结构体中

    #include <iostream>
    using namespace std;
    struct Stock
    {
        int a;
        void show(const Stock &s)
        {
            cout << s.a << endl;
        }
    };
    
    int main()
    {
        Stock s;
        s.a = 100;
        s.show(s);
        return 0;
    }
    

    外部变量,就是文件内函数外面的变量
    static 存储在堆生命周期是整个程序

    #include <iostream>
    using namespace std;
    int c = 30;
    static int b = 20;
    
    int main1()
    {
        {
            static int a = 10;
            cout << a << endl;
    
        }
       cout << b << endl;
       cout << c << endl;
    }
    

    在多文件程序中,可以在一个文件(且只能在一个文件)中定义一个外部变量。使用该变量的其他文件必须使用关键字extern声明它

    统计输入字符的个数

    #include <iostream>
    using namespace std;
    void strcount(const char *str);
    
    const int ArSize = 10;
    // int total = 0;
    int main()
    {
        char input[ArSize];
        char next;
        cin.get(input, ArSize);
        while (cin)
        {
            cin.get(next);
            while (next != '\n')
            {
                cin.get(next);
            }
            strcount(input);
    
            cin.get(input, ArSize);
        }
        return 0;
    }
    void strcount(const char *str)
    {
        int count = 0;
        static int total = 0;
    
        cout << "\"" << str << "\" contains ";
        while (*str++)
        {
            count++;
        }
        total += count;
        cout << "total: " << total << endl;
        cout << "count: " << count << endl;
    }
    

    两个文件中,全局限定变量和static 内部限定变量区别(链接性)
    file1

    #include <iostream>
    using namespace std;
    
    int tom = 3; // 全局外部变量
    int disc = 30;
    static int harry = 300; // 全局内部变量
    void remote_accessx();
    int main()
    {
        cout << "tom = " << tom << " in &tom  " << &tom << endl;
        cout << " disc = " << disc << " in &disc " << &disc << endl;
        cout << " harry = " << harry << " in &harry " << &harry << endl;
        remote_accessx();
        return 0;
    }
    
    

    file2

    
    #include <iostream>
    
    using namespace std;
    extern int tom;
    static int disc = 10;
    int harry = 1000;
    
    
    void remote_accessx()
    {
        cout << "tom = " << tom << " in &tom  " << &tom << endl;
        cout << " disc = " << disc << " in &disc " << &disc << endl;
        cout << " harry = " << harry << " in &harry " << &harry << endl;
    }
    
    

    说明符和限定符
    auto register static extern thread_local mutable

    1. cv-限定符
    • const
    • volatile:代码没有对内存单元修改,它的值也可能发生变化
      编译器会有自己的优化过程
    1. mutable
      结构(或者类)变量为const 其成员变量也可以修改。
    struct data{
    char name[10]; 
    mutable int access;
    }
    

    如果,const data veep ; veep.name 不可以重新修改,veep.access 却可以修改

    1. const
      const 修饰的变量,不会影响变量声明周期。变量声明周期不会改变。const的外置变量限定在了当前文件中。
      比如:文件1:const int test = 10; 通过inclue 等 文件2: const int test = 30; 互不影响。extern const int test = 10;后,升级为外部变量,但是不能再给test进行修改,可以extern const int test ;这个时候这个test == 10

    函数和链接性

    函数内部是不能在此定义函数。默认函数的链接是外部的。
    也可以用extern 声明,证明在外部是有函数定义的。(所以可以省略)
    用static 定义函数,那么在其他文件中用 static 也可以定义同样函数,那么限定为文件内部,外部看不见。

    static 声明函数是内部,只能在当前文件查找,我们做一个实验

    file1

    #include <iostream>
    using namespace std;
    static void remote_access();
    void remote_access();
    
    int main()
    {
    
        cout << "main access" << endl;
    
        remote_access();
    
        return 0;
    }
    
    void remote_access()
    {
        cout << "remote_access 1" << endl;
    }
    

    file2

    #include <iostream>
    using namespace std;
    
    static void remote_access()
    {
        cout << "remote_access 2" << endl;
    }
    void remote_access();
    
    

    不同平台,不同编译器对顺序要求不同。但是思想是一样。

    存储方案和动态分配

    1. new/delete/malloc()
    2. float *p = new float[20]
      extern float *p = new float[20]
    3. int *p = new int(6);
      int *pi = new int;
      double *pd = new double(99.9);
      int * ar = new int[4]{2,3,4,5};
    4. new/new [] /delete/delete []

    char buffer1[20];
    char buffer2[500];
    Struct_custom *p2 = new (buffer1) Struct_custom;
    int *p4 =new (buffer2)int[20];

    new 负责在堆找到足够满足要求的内存块

    
    #include <iostream>
    using namespace std;
    const int BUF = 512;
    char buffer[BUF];
    const int N = 5;
    int main()
    {
    
        cout << "buffer[BUF] address at:" << &buffer << endl;
    
    
        double *pd1, *pd2;
        int i;
        cout << "Calling new and palcement new\n";
        pd1 = new double[N];
        pd2 = new (buffer) double[N];
        for (i = 0; i < N; i++)
        {
            pd2[i] = pd1[i] = 1000 + 2.0 * i;
        }
        cout << "Memory addresses:\n"
             << " heap:" << pd1 << " static:" << (void *)buffer << endl;
        cout << "Memory content:\n";
        for (i = 0; i < N; i++)
        {
            cout << pd1[i] << " at" << &pd1[i] << ";";
            cout << pd2[i] << " at" << &pd2[i] << endl;
        }
        cout << "\n Calling new and palcement new a second time:\n";
        double *pd3, *pd4;
        pd3 = new double[N];
        pd4 = new (buffer) double[N];
        for (i = 0; i < N; i++)
        {
            pd4[i] = pd3[i] = 1000 + 4.0 * i;
        }
        cout << "Memory content:\n";
        for (i = 0; i < N; i++)
        {
            cout << pd3[i] << " at" << &pd3[i] << ";";
            cout << pd4[i] << " at" << &pd4[i] << endl;
        }
        cout << "\n Calling new and palcement new a third time:\n";
        delete[] pd1;
        pd1 = new double[N];
        pd2 = new (buffer + N * sizeof(double))double[N];
        for (i = 0; i < N; i++)
        {
            pd2[i] = pd1[i] = 1000 + 2.0 * i;
        }
       
        cout << "Memory content:\n";
        for (i = 0; i < N; i++)
        {
            cout << pd1[i] << " at" << &pd1[i] << ";";
            cout << pd2[i] << " at" << &pd2[i] << endl;
        }
        return 0;
    }
    
    

    打印后buffer 的存储地址收地址,和new出来的地址是同一个块是个静态地址,new double是动态的。

    名称空间

    #include <iostream>
    using namespace std;
    double pail;
    namespace David
    {
        double pail;
        void fetch();
    }
    
    namespace Lucy
    {
        double pail;
        void fetch();
    }
    
    int main()
    {    
        pail = 10;
        Lucy::pail = 20;
        cout << David::pail << Lucy::pail << endl;
        return 0;
    }
    
    1. using namespace David;
    2. using David::pail;
    3. David::pail;

    Namespace.h

    #include <iostream>
    #include <string>
    namespace pers
    {
        struct Person
        {
            std::string fname;
            std::string lname;
        };
        void getPerson(Person &rp);
        void showPersion(const Person &rp);
    }
    
    namespace debts
    {
        using namespace pers;
        struct Debt
        {
            Person name;
            double amount;
        };
        void getDebts(Debt &rd);
        void showDebt(const Debt &rd);
        double sumDebts(Debt *ar, int n);
    
    }
    

    Namespace.cpp

    #include <iostream>
    #include "Namespace.h"
    namespace pers
    {
        using std::cin;
        using std::cout;
        void getPerson(Person & rp)
        {
            cout << "Enter first name: ";
            cin >> rp.fname;
            cout << "Enter last name: ";
            cin >> rp.lname;
        }
        void showPersion(const Person& rp)
        {
            cout << rp.lname << ", " << rp.fname;
        }
    }
    
    namespace debts
    {
        void getDebts(Debt & rd)
        {
            getPerson(rd.name);
            cout << "Enter debt: ";
            cin >> rd.amount;
        }
        void showDebt(const Debt& rd)
        {
            showPersion(rd.name);
            cout << "  Debt is:$ " << rd.amount << std::endl;
        }
        double sumDebts(Debt * ar,int n) 
        {
            int total = 0;
            for (int i = 0; i < n; i++)
            {
                total += ar[i].amount;
                showPersion(ar[i].name);
                showDebt(ar[i]);
            }
    
            return total;
            
    
        }
    }
    
    

    UseNamespace.cpp

    #include <iostream>
    #include "Namespace.h"
    void other();
    void another();
    int main()
    {
        using debts::Debt;
        Debt golf = {
            "Banny", "Goatsniff", 120.0
    
        };
    
        showDebt(golf);
        other();
        another();
    }
    
    void another()
    {
        using pers::Person;
        Person collector ={"Milo","Rightshift"};
        showPersion(collector);
        std::cout << std::endl;
    }
    
    void other()
    {
        using std::cout;
        using std::endl;
        using namespace debts;
        Person dg = {"Doodles", "Glister"};
        showPersion(dg);
    
        Debt zipply[3];
        int i;
        for (i = 0; i < 3; i++)
        {
            getDebts(zipply[i]);
        }
        for (i = 0; i < 3; i++)
        {
            showDebt(zipply[i]);
        }
        cout << "total debt: $" << sumDebts(zipply, 3) << endl;
    }
    

    相关文章

      网友评论

          本文标题:C++ 存储持续性,作用域和链接性

          本文链接:https://www.haomeiwen.com/subject/bjszudtx.html