static、const用法

一、static用法

C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。

一、面向过程设计中的static
1、静态全局变量:在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:

//Example 1
#include <iostream>
static int n; //定义静态全局变量void fn()
{n++;cout << n << endl;
}void main()
{n = 20;cout << n << endl;fn();
}

静态全局变量有以下特点:

  • 该变量在全局数据区分配内存;
  • 未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);
  • 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;
  • 静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。

对于一个完整的程序,在内存中的分布情况如下图:

  1. 代码区
  2. 全局数据区
  3. 堆区
  4. 栈区

一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。

细心的读者可能会发现,Example 1中的代码中将static int n; 改为 int n; 程序照样正常运行。的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:

  • 静态全局变量不能被其它文件所用;
  • 其它文件中可以定义相同名字的变量,不会发生冲突;

 您可以将上述示例代码改为如下:

//Example 2
//File1
#include <iostream>
void fn();
static int n; //定义静态全局变量int main()
{n = 20;cout << n << endl;fn();
}//File2
#include <iostream.h>
extern int n;
void fn()
{n++;cout << n << endl;
}

编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。 试着将static int n; 改为int n; 再次编译运行程序,细心体会全局变量和静态全局变量的区别。

2、静态局部变量
  在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。
  我们先举一个静态局部变量的例子,如下:
  //Example 3
  #include <iostream.h>
  void fn();
  void main()
  { fn();
  fn();
  fn();
  }
  void fn()
  { static n=10;
  cout<<n<<endl;
  n++;
  }
  通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
  但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
  静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
  静态局部变量有以下特点:
  该变量在全局数据区分配内存;
  静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
  静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
  它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束; 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1025 反转链表 (25 分

给定一个常数 K 以及一个单链表 L&#xff0c;请编写程序将 L 中每 K 个结点反转。例如&#xff1a;给定 L 为 1→2→3→4→5→6&#xff0c;K 为 3&#xff0c;则输出应该为 3→2→1→6→5→4&#xff1b;如果 K 为 4&#xff0c;则输出应该为 4→3→2→1→5→6&#xff0c;即…

1026 程序运行时间 (15 分

要获得一个 C 语言程序的运行时间&#xff0c;常用的方法是调用头文件 time.h&#xff0c;其中提供了 clock() 函数&#xff0c;可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间单位是 clock tick&#xff0c;即“时钟打点”。同时还有一个常数 CLK_TCK&…

【C++基础】常见面试问题(二)

1. 指针和引用的区别 指针保存的是所指对象的地址&#xff0c;引用是所指对象的别名&#xff0c;指针需要通过解引用间接访问&#xff0c;而引用是直接访问指针可以改变地址&#xff0c;从而改变所指的对象&#xff0c;而引用必须从一而终&#xff1b;引用在定义的时候必须初始…

1028 人口普查 (20 分)

某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的&#xff0c;但不一定是合理的——假设已知镇上没有超过 200 岁的老人&#xff0c;而今天是 2014 年 9 月 6 日&#xff0c;所…

static关键字用法

static修饰局部变量 静态局部变量存储在全局静态区生存期为整个程序生命周期&#xff0c;但是其作用域仍与自动变量相同&#xff0c;只能在定义该变量的函数内使用该变量。退出该函数后&#xff0c;尽管该变量还继续存在&#xff0c;但不能使用它。静态局部变量若在声明时未赋以…

1029 旧键盘 (20 分)

旧键盘上坏了几个键&#xff0c;于是在敲一段文字的时候&#xff0c;对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字&#xff0c;请你列出肯定坏掉的那些键。 输入格式&#xff1a; 输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段…

volatile、const的用法

1. volatile 访问寄存器要比访问内存要块&#xff0c;因此CPU会优先访问该数据在寄存器中的存储结果&#xff0c;但是内存中的数据可能已经发生了改变&#xff0c;而寄存器中还保留着原来的结果。为了避免这种情况的发生将该变量声明为volatile&#xff0c;告诉CPU每次都从内存…

1030 完美数列 (25 分)

给定一个正整数数列&#xff0c;和正整数 p&#xff0c;设这个数列中的最大值是 M&#xff0c;最小值是 m&#xff0c;如果 M≤mp&#xff0c;则称这个数列是完美数列。 现在给定参数 p 和一些正整数&#xff0c;请你从中选择尽可能多的数构成一个完美数列。 输入格式&#xff…

《STL源码剖析常见面试问题》

1. 当vector的内存用完了&#xff0c;它是如何动态扩展内存的&#xff1f;它是怎么释放内存的&#xff1f;用clear可以释放掉内存吗&#xff1f;是不是线程安全的&#xff1f; (1). vector内存用完了&#xff0c;会以当前size大小重新申请2*size的内存&#xff0c;然后把原来…

1034 有理数四则运算 (20 分)

本题要求编写程序&#xff0c;计算 2 个有理数的和、差、积、商。 输入格式&#xff1a; 输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数&#xff0c;其中分子和分母全是整型范围内的整数&#xff0c;负号只可能出现在分子前&#xff0c;分母不为 0。 输出格式&…

1035 插入与归并 (25 分)

根据维基百科的定义&#xff1a; 插入排序是迭代算法&#xff0c;逐一获得输入数据&#xff0c;逐步产生有序的输出序列。每步迭代中&#xff0c;算法从输入序列中取出一元素&#xff0c;将之插入有序序列中正确的位置。如此迭代直到全部元素有序。 归并排序进行如下迭代操作&a…

迭代式失效情况

vector 向容器插入元素后&#xff1a; 如果容器是vector或string&#xff0c;且存储空间被重新分配&#xff0c;则指向容器的迭代器会失效&#xff1b;如果存储空间未重新分配&#xff0c;指向插入点位置号之前的元素的迭代器仍然有效&#xff0c;但是指向插入点之后的元素的迭…

1039 到底买不买 (20 分)

小红想买些珠子做一串自己喜欢的珠串。卖珠子的摊主有很多串五颜六色的珠串&#xff0c;但是不肯把任何一串拆散了卖。于是小红要你帮忙判断一下&#xff0c;某串珠子里是否包含了全部自己想要的珠子&#xff1f;如果是&#xff0c;那么告诉她有多少多余的珠子&#xff1b;如果…

【Leetcode】111. 二叉树的最小深度

给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明: 叶子节点是指没有子节点的节点。 示例: 给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回它的最小深度 2. 解题思路&#xff1a;…

1040 有几个PAT (25 分

字符串 APPAPT 中包含了两个单词 PAT&#xff0c;其中第一个 PAT 是第 2 位(P)&#xff0c;第 4 位(A)&#xff0c;第 6 位(T)&#xff1b;第二个 PAT 是第 3 位(P)&#xff0c;第 4 位(A)&#xff0c;第 6 位(T)。 现给定字符串&#xff0c;问一共可以形成多少个 PAT&#xff…

g

1. 何时需要成员初始化列表&#xff1f;过程是什么&#xff1f; 当初始化一个引用成员变量时&#xff1b;初始化一个const成员变量时&#xff1b;当调用一个基类的构造函数&#xff0c;而构造函数拥有一组参数时&#xff1b;当调用一个成员类的构造函数&#xff0c;而他拥有一组…

【Leetcode | 1】93. 复原IP地址

给定一个只包含数字的字符串&#xff0c;复原它并返回所有可能的 IP 地址格式。 示例: 输入: "25525511135" 输出: ["255.255.11.135", "255.255.111.35"] 方法一&#xff1a; class Solution { public:vector<string> restoreIpAddresse…

1051 复数乘法 (15 分)

复数可以写成 ( 的常规形式&#xff0c;其中 A 是实部&#xff0c;B 是虚部&#xff0c;i 是虚数单位&#xff0c;满足 1&#xff1b;也可以写成极坐标下的指数形式 (&#xff0c;其中 R 是复数模&#xff0c;P 是辐角&#xff0c;i 是虚数单位&#xff0c;其等价于三角形式 (。…

【Leetcode | 13】56. 合并区间

给出一个区间的集合&#xff0c;请合并所有重叠的区间。 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. 示例 2: 输入: [[1,4],[4,5]] 输出: [[1,5]] 解释: 区间 [1,4] 和 [4,5] 可被视为重叠…

1050 螺旋矩阵 (25 分

本题要求将给定的 N 个正整数按非递增的顺序&#xff0c;填入“螺旋矩阵”。所谓“螺旋矩阵”&#xff0c;是指从左上角第 1 个格子开始&#xff0c;按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列&#xff0c;满足条件&#xff1a;mn 等于 N&#xff1b;m≥n&#xff1b;且…