【C++研发面试笔记】3. 命名空间与内存管理

来源:互联网 发布:最好的seo课程 编辑:程序博客网 时间:2024/05/20 19:47

【C++研发面试笔记】3. 命名空间与内存管理

3.1 命名空间

命名空间就是将多个变量和函数等包含在内,使其不会与命名空间外的任何变量和函数等发生重命名的冲突。
在其中的很多实例中,都有这么一条语句:using namespace std;,即使用命名空间std,其作用就是规定该文件中使用的标准库函数都是在标准命名空间std中定义的。

3.1.1 使用命名空间解决名字冲突

修改两个头文件,把在头文件中声明的类分别放在两个不同的命名空间中。

// 对于头文件hearder1.h                     #include <cstring>   #include <cmath>   using namespace std;  namespace hearder1 { ...   // 声明函数变量   ...  } 

3.1.2 使用命名空间成员的方法

(1)使用命名空间别名
namespace TV=Television;
TV::func();
(2)使用using命名空间成员名
using TV::func();
以上语句声明:在本作用域(using语句所在的作用域)中会用到命名空间TV中的成员函数func(),在本作用域中如果使用该命名空间成员时,不必再用命名空间限定。
(3)使用using namespace命名空间成员名
在用using namespace声明的作用域中,命名空间的成员就好像在全局域声明的一样。因此可以不必用命名空间限定。显然这样的处理对写程序比较方便。但是如果同时用using namespace声明多个命名空间时,往往容易出错,因为两个命名空间可能会有同名的类和函数。
(4)无名的命名空间
由于命名空间没有名字,在其他文件中显然无法引用,它只在本文件的作用域内有效。在本程序中的其他文件中也无法使用该fun函数,也就是把fun函数的作用域限制在本文件范围中。在C浯言中可以用static声明一个函数,其作用也是使该函数的作用域限于本文件。C++保留了用static声明函数的用法,同时提供了用无名命名空间来实现这一功能。
(5)标准命名空间std
标准C++库的所有的标识符都是在一个名为std的命名空间中定义的,或者说标准头文件(如iostream)中函数、类、对象和类模板是在命名空间std中定义的。在std中定义和声明的所有标识符在本文件中都可以作为全局量来使用。但是应当绝对保证在程序中不出现与命名空间std的成员同名的标识符。
由于在命名空间std中定义的实体实在太多,有时程序设计人员也弄不请哪些标识符已在命名空间std中定义过,为减少出错机会,有的专业人员喜欢用若干个using命名空间成员声明来代替using namespace命名空间声明。但是目前所用的C++库大多是几年前开发的,当时并没有命名空间,库中的有关内容也没有放在std命名空间中,因而在程序中不必对std进行声明。

3.1.3 头文件include

#include "" 表示头文件一般是放在用户目录中
#include <> 表示头文件一般是放在系统目录中
在C++中使用这些头文件有两种方法:
(1)用C语言的传统方法
头文件名包括后缀.h,如stdio.h,math.h等。由于C语言没有命名空间,头文件并不存放在命名空间中,因此在C++程序文件中如果用到带后缀.h的头文件时,不必用命名空间。只需在文件中包含所用的头文件即可。
(2)用C++的新方法
C++标准要求系统提供的头文件不包括后缀.h,例如iostream、string。为了表示与C语言的头文件有联系又有区别,C++所用的头文件名是在C语言的相应的头文件名(但不包括后缀.h)之前加一字母c。例C语言中有关输入与输出的头文件名为stdio.h在C++中相应的头文件名为cstdio。C语言中的头文件math.h,在C++中相应的头文什名为cmath。此外,由于这些函数都是在命名空间std中声明的,因此在程序中要对命名空间std作声明:using namespace std;


3.2 内存管理

3.2.1 程序所占内存

一个由C/C++编译的程序占用的内存分为以下几个部分:

  • 1、栈区: 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
  • 2、堆区:般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
  • 3、全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。
  • 4、文字常量区:常量字符串就是放在这里的。程序结束后由系统释放。
  • 5、程序代码区:存放函数体的二进制代码。

3.2.2 内存堆栈的区别

  • A. 申请大小的限制:
    栈:栈顶的地址和栈的最大容量是系统预先规定好的,如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。系统是用链表来存储的空闲内存地址的。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
  • B. 申请效率的比较:
    栈由系统自动分配,速度较快。但程序员是无法控制的。
    堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一块内存,虽然用起来最不方便。但是速度快,也最灵活。
  • C. 堆和栈中的存储内容:
    栈:函数地址,函数的各个参数,局部变量等。
    堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
  • D. 存取效率的比较:
    char s1[] = "aaaaaaaaaaaaaaa";
    char *s2 = "bbbbbbbbbbbbbbbbb";
    aaaaaaaaaaa是在运行时刻赋值的; 而bbbbbbbbbbb是在编译时就确定的;
    但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

这篇博文是个人的学习笔记,内容许多来源于网络(包括CSDN、博客园及百度百科等),博主主要做了微不足道的整理工作。由于在做笔记的时候没有注明来源,所以如果有作者看到上述文字中有自己的原创内容,请私信本人修改或注明来源,非常感谢>_<

0 0