2020-12-12

cpp储存类别,链接,内存管理

1.作用域
作用域描述程序中可以访问标识符的区域。一个c变量的作用域可以是块作用域,函数作用域,函数原型作用域,或文件作用域。(常用的是块作用域)
1.块作用域是用一对花括号括起的代码。
2.函数原型作用域用于函数原型中的形参名。如

int f(int a,double b);

3.函数作用域仅使用在goto语句的标签。意味着即使一个标签首次出现在函数内层块中,它的作用域也能够延申整个函数。
4.变量定义在函数外面具有文件作用域,





2.链接
c变量有3中属性;外部链接,内部链接,或无链接。具有块作用域,函数作用域或函数原型作用域的变量都是无链接变量。意味着这些属于它们定义他们的块,函数或原型私有。具有文件作用域的变量可以是外部链接或内部链接。外部链接可以在多文件程序中使用,内部链接变量只能在一个翻译单元使用。



3.存储类别
在cpp上,列出了以下五种存储类型:

1.自动变量:

关键词auto.属于自动存储类别的变量具有自动存储期,块作用域且无链接,默认情况下,声明在块或函数头中的任何变量都属于自动存储类别。可以加上auto关键词.在块作用域中声明,具有自动存储期,即程序进入该块时变量存在,退出该块时变量被销毁.
如下所示

int f(int a) //定义f函数,a为形参
{
   auto int b,c=3; //定义b和c为整型的自动变量}

存储类别auto和数据类型int的顺序任意。关键字auto可以省略,如果不写auto,则系统把它默认为自动存储类别,它属于动态存储方式。程序中大多数变量属于自动变量。本书前面各章所介绍的例子中,在函数中定义的变量都没有声明为auto,其实都默认指定为自动变量。在函数体中以下两种写法作用相同:
① auto int b,c=3;
② int b,c=3;

2.寄存器变量:

关键词为register,其性质与自动变量很相似,块作用域,自动存储期.但是因为它被存储在寄存器中而不是内存中,所以无法获取它的地址.与普通变量相比,访问和处理这些变量的速度要更快。同时要注意的是,声明寄存器变量只是一种请求,最终是否将该变量存在寄存器中则是由编译器来决定.但无论是否被存入寄存器,该变量都无法获取地址.

如,可以将例4.14中的fac函数改写如下:

如可以将例4.14中的fac函数改写如下:
int fac(int n)
{
   register int i,f=1; //定义i和f是寄存器变量
   for(i=1;i<=n;i++) f=f*i;
   return f;
}

定义f和i是存放在寄存器的局部变量,如果n的值大,则能节约许多执行时间。
在程序中定义寄存器变量对编译系统只是建议性(而不是强制性)的。当今的优化编译系统能够识别使用频繁的变量,自动地将这些变量放在寄存器中。

3.静态变量无链接:

在块内用关键字static声明变量,具有块作用域,但它的存储期是静态的,也就是说,在该变量被创建后,程序停止运行才会释放该变量.在循环中,但程序再一次运行到该声明时,会跳过去.自动初始化为0.

4.12 静态局部变量的值。
#include <iostream>
using namespace std;
int f(int a)  //定义f函数,a为形参
{
   auto int  b=0; //定义b为自动变量
   static int c=3;//定义c为静态局部变量
   b=b+1;
   c=c+1;
   return a+b+c;
}

int main( )
{
   int a=2,i;
   for(i=0;i<3;i++)
  cout<<f(a)<<″ ″;
  cout<<endl;
  return 0;
}

运行结果为
7 8 9 

4.静态变量与外部链接:

关键词为extern.作为外部变量作用域自然是文件,静态存储期,感觉叫全局变量比较舒服,也比较熟悉,这种变量在所有块外面声明,可以在同一个程序不同翻译单元(很奇怪的名字,反正就是不同的文件)中作用.如果要在一个文件中使用另一个文件的全局变量,要用关键字extern.自动初始化为0.
例4.14 用extern对外部变量作提前引用声明,以扩展程序文件中的作用域。

#include <iostream>
using namespace std;
int max(int,int);  //函数声明
void main( )
{
   extern int a,b;//对全局变量a,b作提前引用声明
   cout<<max(a,b)<<endl;
}
int a=15,b=-7;//定义全局变量a,b
int max(int x,int y)
{
   int z;
   z=x>y?x:y;
   return z;
}

运行结果如下:
15
在main后面定义了全局变量a,b,但由于全局变量定义的位置在函数main之后,因此如果没有程序的第5行,在main函数中是不能引用全局变量a和b的。现在我们在main函数第2行用extern对a和b作了提前引用声明,表示a和b是将在后面定义的变量。这样在main函数中就可以合法地使用全局变量a和b了。如果不作extern声明,编译时会出错,系统认为a和b未经定义。一般都把全局变量的定义放在引用它的所有函数之前,这样可以避免在函数中多加一个extern声明。

5.静态变量与内部链接:

这个与全局变量的区别在于声明时需要加上static关键字,同时无法被其他文件使用.自动初始化为0.

***存储类别小结

存储类别存储期作用域链接声明方式
自动自动块内
寄存器自动块内,使用关键字registe
静态外部链接静态文件外部所有函数外
静态内部链接静态文件内部所有函数外,使用关键字static
静态无链接静态块内

**4.内存管理**
函数描述
*calloc(int num, int size);在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。
free(void *address);该函数释放 address 所指向的内存块,释放的是动态分配的内存空间。
*malloc(int num);在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
*realloc(void *address, int newsize);该函数重新分配内存,把内存扩展到 newsize。

上述函数多用于链表中,均处于<stdlib.h>中。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值