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

2023-07-21  本文已影响0人  zcwfeng

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-限定符
  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;
}
上一篇下一篇

猜你喜欢

热点阅读