动态内存分配以及指针与const

             在 C++程序中内存分为 5 个区,分别是栈、堆、自由存储区、全局/静态存储区和常量存储区。程序中的各种数据都存储在这些内存区域中。 

           栈区由编译器自动分配和释放,存放函数的参数以及局部变量。其分配运算内置于处理器的指令集中,效率很高。但是可使用的总量有限,一般不会超过 1M 字节。

           堆区中内存的分配和释放由开发者负责。一般用运算符 new 分配内存,并用运算符 delete 释放内存。一个 new 要对应一个 delete,否则会导致内存泄露。如果开发没有释放,在程序结束的时候操作系统会自动回收。在堆上可分配的内存比栈上大了很多,且使用非常灵活。

            自由存储区和堆类似,但是其内存管理是通过库函数 malloc 和 free 等进行的。在 C 程序中经常使用,虽然在 C++程序中仍然可以使用,但不如用堆方便。

           全局/静态存储区中存放的是全局变量和静态变量。该存储区分配的内存在整个程序运行期间一直有效,直到程序结束由系统回收。常量存储区中存储的是常量,通常不允许修改。在程序中定义的常量以及指针字符串都存储在

这里。

 

#include <iostream>

using  namespace std;

int   a; // 全局变量,存储在全局/静态存储区

int   main()

{

int  b; //局部变量,存储在栈上

int* p = new int();//由运算符 new 分配的,存储在堆上

static   int d; //静态变量,存储在全局/静态存储区

const   int e = 0; //常量,存储在常量存储区

delete  p; //释放堆中的内存

return0;

}

C++程序中的内存都要从上面的 5 个区中分配。不过栈、全局/静态存储区以及常量存储区中的分配是由编译器来进行的,并且在程序运行之前已经分配,因此称之为静态分配堆以及自由存储区上内存的分配,是在程序运行的过程中进行的,称之为动态内存分配。下节中主要介绍通过new 进行的动态内存分配。只 有 在 堆 上 和自 由 存 储 区 中分 配 的 内 存 需要 开 发 者 管 理。 其他 存 储 区中 的 变 量 只要定义即可,其内存的分配和释放由编译器负责

 

 

在堆上分配内存

在堆上分配内存,要使用 new 关键字,后面跟一个数据类型。如果需要对分配出的内存进行初始化,则在类型后面加上一个括号,并带有初始值。为了保存分配出内存的地址,应当使用一个Int *p=new int (3);   //p指向这块内存     3的意思是初始化 表示分配成功后*p为3,当然也可以不用初始值 eg:Int *p=new int ;//这种无初始值的情况下 若new的类型是类则会调用该类的默认构造函数

用new 为数组分配内存

Int *str =new int[10]// 10表示数组的长度 注意两种的括号的不一样;  好消息 好消息 用运算符 new 为数组分配内存空间时,其长度可以是变量,而不必是常量。因为动态内存分配在程序运行的时候才分配空间,所以当用 new 在堆上定义数组的时候,其长度可以是一个变量 不过嘛 缺点也是有的  那就是不能够对数组初始化

 

 

 

指向 const 的指针  他有两种写法(const int * p   或     int const *p)

       指向 const 的指针,指的是一个指针指向的数据是常量,不可以被修改,但指针变量本身可以被修改

   

 

   Eg:

   

Int a=0;

Const int *p;

P=&a;

*p=1;//错误 因为不能通过该const 指针修改其值

 const 修饰的变量,只能用指向 const 的指针来指向,而不能用普通的指针

 

 

 

指向 const 的指针,只限制了指向变量不可以被修改,但是指针本身的指向是可以修改的:

 

int a ;

int b;

const int * p = &a

p = &b // 修改指针的指向

 

 

  const 指针   (它就只有一种写法   int  * const p)

    const 指针,指的是指针变量本身是一个常量,只能指向定义时所给的那个数据,而不能指向别处,而对被指向的数据是没有影响的

int  a;

int * const p=&a;

如果不要int a  则错误因为不能修改 const 指针的指向,所以在定义的时候必须给一个初始值

指向 const 的 const 指针

 

Const int *p(int const *p);      Int * const p;     Const int  *const p;

    三种 const 指针的定义很相似,很难以区分,这里有一个简单的技巧:从标识符的开始处读它,

并从里向外读,const 指定那个“最靠近”的。因此根据这个理解:第一个定义表示 int 不可以被

改变,第二个表示 p 不可以被改变,第三个表示 int 和 p 都不可以被改变。

 

引用

 

   引用也是一种数据类型。不过,引用不能独立存在,而只能依附于一个变量。所以定义一个引用,必须要指明是哪个变量的引用。定义一个引用包括目标变量的数据类型、引用修饰符“&”、引用的标识符以及目标变量的标识符,其语法如下:

 

类型标识符 &引用名 = 目标变量名

 

 

    Eg:

 

 

     int a; //定义一个变量

     Int & b=a; // 定义一个上述变量的引用  &可不是取地址符呀

 

引用一旦定义,则始终跟其目标变量绑定,而不能改变为其他变量的引用

 

另外,引用在其生命周期内完全可以替代其目标变量。也就是说,所有施加于引用上的操作,其效果都等同于直接对引用的目标变量进行操作。而且一旦目标变量的值发生了改变,引用的值也会发生同样的改变

注意:

指针可以指向数组的地址来替代数组使用,而引用不可以替代数组,引用只能指向数组中的某一个元素

 

         函 数 模 板

 

 

<typenameT1, typename T2, int num, double value>

   上述模板参数列表中声明了两个类型参数 T1 和 T2,代表两种数据类型,可以是内置的类型,也可以是自定义类型。同时,该模板参数列表还声明了两个非类型参数 num 和 value,表示该模在定义过程中可以将 num  value 当做常量使用

  函数模板中使用非类型参数,其目的就是为函数引入一个常量,以供定义函数时使用。当然这

个常量也可以作为函数参数的默认值使用

 

C++标准规定模板参数必须在程序编译时确定。因此非类型的模板参数的值必须

是一个常量,而且是编译时就能确认的常量,包括字面常量、符号常量(const 

量)。

 

函数模板不是真正的函数,不能直接使用,必须先实例化

 

取函数模板的地址时也会导致函数模板的实例化。因为函数模板并不是真正的函数,所以其本

身也没有地址。但是 C++并不把“&函数模板名”(取地址符号‘&’也可以省略)这样的用法当做

一个错误,而是先对该函数模板进行实例化,然后取实例化所生成函数的地址

函数序运

的只。函例化译期址则程序运行期

 

                                                              shmily_h

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值