C++ 存储持续性,作用域和链接性
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
- cv-限定符
- const
- volatile:代码没有对内存单元修改,它的值也可能发生变化
编译器会有自己的优化过程
- mutable
结构(或者类)变量为const 其成员变量也可以修改。
struct data{
char name[10];
mutable int access;
}
如果,const data veep ; veep.name 不可以重新修改,veep.access 却可以修改
- 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();
不同平台,不同编译器对顺序要求不同。但是思想是一样。
存储方案和动态分配
- new/delete/malloc()
- float *p = new float[20]
extern float *p = new float[20] - int *p = new int(6);
int *pi = new int;
double *pd = new double(99.9);
int * ar = new int[4]{2,3,4,5}; - 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;
}
- using namespace David;
- using David::pail;
- 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;
}