C++学习(九)——内存模型和名称

本文详细探讨了C++中的内存模型和名称空间,包括单独编译、存储持续性、作用域和链接性,以及名称空间的使用。重点讲解了不同存储类型的特性,如自动存储、静态存储和动态存储,还有静态链接与动态链接的区别。同时,深入介绍了名称空间的作用,如何避免命名冲突,以及using声明和using编译指令的应用。
摘要由CSDN通过智能技术生成

内存模型和名称空间

一、单独编译

将组件函数放在单独的文件中,然后将它们连接成可执行的程序。将结构声明放到头文件中,使用#include包含(“”),例如:

  • 头文件:包含结构声明和结构中的函数原型
  • 源代码文件:包含与结构有关的函数的代码
  • 源代码文件:包含调用与结构线管的函数的代码

头文件中包含的内容有:
- 结构声明
- 类声明
- 函数原型
- 内联函数
- 模板声明
- 使用#define或const定义的符号常量

在同一个文件中只能包含同一个头文件1次,为了防止包含多次,使用#ifndef来预处理

#ifndef COORDIN_H_
#define COORDIN_H_
#endif
注1:define语句的使用
#define MAXIMUN 4096 //创建符号常量

二、存储持续性、作用域和链接性

  • 自动存储持续性:在函数中定义的变量
  • 静态存储持续性:static,在程序运行整个过程中都存在
  • 线程存储持续性(C++11):thread_local声明
  • 动态存储持续性:new分配的内存,直到delete将其释放掉
1. 作用域和链接
  • 作用域描述名称在文件中多大范围可见,类中成员作用域为整个类
  • 链接性分为外部和内部,内部只能在该文件中使用
2.自动存储连续性

默认情况下,函数中声明的函数参数和变量的存储连续性为自动,作用域为局部,没有链接性。
自动变量只在包含它们的函数或代码块中可见

自动变量和栈
栈是LIFO,最后加入栈中的变量先被弹出,按函数调用顺序进站出站

寄存器变量:

register int count_fast;//建议编译器使用寄存器来存储自动变量
3.静态持续变量

所有经他变量在整个程序执行期间都存在
- 外部链接性:代码块外
- 内部链接性:代码块外、static
- 无链接性:代码块内、static

int global = 1000; // 静态变量,外部链接性,可以在程序的其他文件中使用
static int one_file =50; //静态变量,内部链接性,只能在该文件中使用
int main()
{
}
void funct1(int n)
{
    static int count = 0; 
    //静态变量,无链接性,只能在funct1()中使用它,
    int llama = 0;
}
4.静态持续性、外部链接性

外部变量也成全局变量,在每个使用外部变量的文件中,都应该声明它,单变量只能定义一次,因此C++提供两种声明
- 定义声明(定义):给变量分配存储空间
- 引用声明(声明):引用已有的变量,不分配内存空间,使用extern族谱为关键字

double up; // up = 0
extern int blem; //blem defined elsewhere
extern char gr = 'z'; //定义

如果要在多个文件中使用,那么在一个文件中包含定义,其他文件中使用关键字extern

//file1.cpp
extern int cats = 20;//extern不是必需的
int dogs = 22;
int fleas;
···
//file2.cpp
extern int cats;
extern int dogs;

在函数中使用extern声明外部变量,就可以在该函数中使用
::作用域解析运算符放在变量名前时表示该变量的全局版本

5. 静态持续性、内部链接性

相同变量名的static类型(静态外部变量)可以隐藏另一文件中的常规外部变量,链接性为内部的静态变量可以在同一文件的多个函数之间共享数据

6. 静态存储持续性、无链接性

该变量只在该代码块中可用,但它在该代码块不处于活动和状态时仍然存在。

处理行数如可能长于目标数组的方法:

cin.get(unput,Arsize);
while(cin)
{
    cin.get(next);
    while(next ! = '\n')//后面还有字符没读完
        cin.get(next);//读取后面的字符
    strcount(input);
    cout << ""<<endl;
    cin.get(input,Arsize);
}
7.说明符和限定符

说明符:同一声明中不能使用多个说明符(除thread local)
- register
- static
- extern
- thread local
- mutable
限定符:
- const
- volatile:该变量随时可能发生变化

(1)mutable:即使结构、类变量为const类型,其某个成员也可可以被修改。

struct data{
    chat name[30];
    mutable int accesses;
};
const data veep={"Claybourge Clodde", 0,};
strcpy(veep.name, "Joye Joux"};// not allowed
veep.accesses++; //allowed

(2)const:const全局变量链接为内部的,与使用了static一样,这样放在头文件中就不违反单定义规则,不需要使用extern

8.函数和链接性

不允许在一个函数中定义另一个函数,默认情况下,函数的链接性是外部的,可以在文件中共享,可以使用static使之成为内部的。

9.存储方案和动态分配

(1) 使用new运算符初始化

//()包含初始值
int *pi = new int(6); //*pu set to 6
//[]初始化数组,{}包含初始值
int *ar = new int[4] {2,4,6,7};
//{}初始化结构
struct where{double x;double y;double z;};
where *one = new where{2.5,5.3,7.2};
//其他
int *pi = new int;

(2)定位new运算符:不能用delete删除

#include<new>
char buffer1[50];
p1 = new (buffer1) chaff;

三、名称空间

1.传统C++名称空间
  • 声明区域:可以在其中进行声明的区域
  • 潜在作用域:从声明点开始,到声明区域的结尾,但作用域要从定义开始。
2.新的C++名称空间

通过定义一种新的声明区域来创建命名的名称空间,一个名称空间中的名称不会与另外一个名称空间中的名称发生冲突。
名称空间可以嵌套。
- 用户定义的名称空间

namespace Jill{
    double bucket(double n){...}
    double fetch;
    int pal;
    struct Hill(...};
    }
Jill::Hill mole;
  • 全局名称空间:对应于文件级声明区域
3.using声明和using编译指令
  • using声明:使一个名称可用
using Jill::fetch;//以后可直接使用fetch
  • using编译指令:是所有名称都可用,如果与局部名称发生冲突,局部名称将覆盖掉它
using namespace Jack;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值