【C++的探索路2】内存空间,引用与函数

来源:互联网 发布:短篇小说推荐 知乎 编辑:程序博客网 时间:2024/06/06 01:53

上节主要对C++结构化编程的基本架构进行了一个简单的梳理。本系列第二篇文章将对不同区域的内存空间存放什么东西,以及引用与函数进行相应简单的解释与练习。本文章主要是一些基础性概念问题,对应编程例程可能较少。

内存空间

该部分有一些内容涉及到后面函数,数组等部分知识,后面也会相互遥相呼应。

C++的内存空间主要有四种:代码区,全局数据区,堆区以及栈

代码区

也就是我们平时所用主函数的地址,主函数即main函数,程序入口的地址。

全局数据区

存放两种:一个是存放全局变量,另外一个存放静态(static)局部变量。

对于变量方面的知识,小小的补充一下

则存放局部变量,该应用注意实例为:如果在主函数内部定义大的数组,则容易对栈进行破坏

为保存动态内存分配分配出来的内存。

全局变量、局部变量以及静态变量

全局与局部变量均如其名,全局变量即所有函数均可以使用,局部变量只能在定义它的内部使用。全局变量则存放于全局数据区,局部变量则放于栈区。

那么什么是静态变量呢?有没有动态变量,和动态内存分配又有没有什么关系呢

这里的动静是指变量的内存地址到底变不变的意思。在运行过程中发生改变的就是动态变量,而在程序运行过程中不发生改变的就是静态变量。静态局部变量放在全局数据区,地址固定,存储空间不会被其他变量所占用,而动态变量则会发生改变。

而剩下的则就是动态变量,与动态内存分配有着很大的区别。动态内存分配只能分配出堆的内存;而动态变量则包括堆(动态内存分配)和栈(局部变量)的内容。

因此静态变量的特点就是:1,内存地址在运行过程中不发生改变。2,存储在全局数据区。

整体脉络

如下图:                                                     

引用与函数

引用与函数部分涉及知识点相对较多,个人选取了部分可能相对较为实用的部分进行记载与记录,如果后续存在遗漏或者错误的地方将会进行完善。

该部分整体结构如下:

主要有两个部分,一个是引用,另外一个为函数。这两部分经常与指针相互耦合,本来想一口气说完,估计可能会比较混杂,就放在下一部分进行记录。

引用

引用这部分首先我们介绍其基本概念,接着我们对有一些特殊用途的引用的应用部分进行说明;另外在函数的书写过程中会有两种情况:传值与传引用,这一部分将用程序进行说明,最后将对常引用部分进行讲解,因为常引用在函数调用过程中非常常见。

基本概念:

引用的基本形式为:类型名&引用名=同类型的某些变量名。

有几个点需要注意:

第一点:一定需要初始化

第二点:只能引用变量

引用作为函数返回值

什么叫做引用作为函数返回值呢?就是如程序所示令函数放在赋值号的左边,可以运行

#include<iostream>using namespace std;int n = 4;int &SetValue(){return n;}int main() {SetValue() = 0;cout << n << endl;return 0;}

我们知道,一般函数是用于赋值号的右边:返回值对变量或函数进行赋值,那么这种奇怪的形式有什么用或者用于什么地方呢?在后续C++面向对象编程的运算符重载(比如流插入流提取部分)及STL部分有相应的例程。

传值与传引用

这部分属于函数的部分,还是单独摘出来到这个部分,记得原来上C语言课程的时候,传值与传引用经常作为迷惑题的一种来诱导大家入坑。

所谓传值就是将变量复制(copy)一份,而不是从他家里把他给请出来(复制地址),而传引用则直接把需要使用的变量的家(地址)作为主战场进行相应的运算。似乎有点抽象,放两个程序:

第一个程序:传值

#include<iostream>using namespace std;void Exchange(int a, int b) {int tmp;tmp = b;b = a;a = tmp;}int main() {int a, b;cout << "please count in a & b" << endl;cin >> a >> b;Exchange(a, b);cout << "a,b交换值为: " << "a=" << a << " b=" << b << endl;return 0;}

乍一看,这个程序应该似乎大概也许或然可以实现交换程序,首先将b的值给了临时变量tmp,然后a把他的值复制给了b,最后tmp也就是和原来的b相等的这货把自己的值给了a;一切是那么的水到渠成。

然而运行这个所谓的Exchange()交换函数以后,发现这个Exchange()除了长得像交换函数,其实并没有什么卵用。

问题出在哪呢,就出在函数传值上面。由上述内存空间我们知道函数一般是单独使用栈进行相应的运算,只是利用了一个临时(请注意临时的存储区域;并不是和全局函数一样有一个恒久远的内存区域进行运算。

在运算过程中,首先经过赋值的a和b经过拷贝,传参给Exchange()函数(注意只是传了一个复印本,而不是原件)经过一系列交换后,快到达cout语句的时候,Exchange()烟消云散了,之前的工作全白瞎了。a依然是a, b还是那个b, 这就是传值的作用。

其实简而言之,传值就是复制品在函数内部瞎搞,子函数一完蛋,各回各家各找各妈(这句话并不是想表达传值没有用途的意思)。


第二个程序:传引用1

#include<iostream>using namespace std;void Exchange(int& a, int& b) {int tmp;tmp = a;a = b;b = tmp;}int main() {int a, b;cout << "please count in a & b"<<endl;cin >> a >> b;Exchange(a, b);cout << "a,b交换值为: " << "a="<<a<<" b="<<b << endl;return 0;}

运行完上面这个程序我们会发现,好像交换起作用了,这是由于我们的Exchange()函数中使用了形式为引用参数最终地址进行交换也就是这个函数这两个形参彻底交换了个窝。

所以在实际运算过程中应当注意传值与传引用的不同用法。


第三个程序:传引用2

#include<iostream>using namespace std;void Exchange(int* p, int* p1) {int tmp;tmp = *p;*p = *p1;*p1 = tmp;}int main() {int a, b;cout << "please count in a & b"<<endl;cin >> a >> b;Exchange(&a, &b);cout << "a,b交换值为: " << "a="<<a<<" b="<<b << endl;return 0;}
这是传引用的第二个例子,主要是利用了指针对地址进行交换,直接在函数的运算过程中就是传递&a,&b这种地址值,所以可以进行移动。


函数

基础知识:

1,函数的作用:基本封装一些功能,提供接口。如上面所述比如我们需要实现一个交换程序,就定义一个Exchange()函数进行交换。

2,函数的形式: 返回值类型  函数名(参数表){函数体}

函数如同变量一样需要返回值,函数名就和我们给小孩起名一样,不然不知道哪个是哪个,参数表即需要传递的参数,函数体即我们需要实现的功能。

函数的重载

重载不仅在结构化编程中有着相应的用途,在面向对象的后续过程中也有着广泛的应用。注意这个重载的重不是体重的那个重而是重庆的那个重,重载即重复载入的意思。

重载的用途就是允许函数取相同的名字,但是参数表一定要不(这一点在后续面向对象的运算符重载中也是一样的道理)。


举个例子

#include<iostream>using namespace std;void Max(int a, int b) {cout << "Max1" << endl;}void Max(double a, double b) {cout << "Max2" << endl;}int main() {int a = 3, b = 4;Max(a, b);double c = 4, d = 5;Max(c, d);return 0;}

上述就是两个Max函数,如果C++不支持重载功能,那么对待不同类型参数求取Max()值将遇到很大的困难,我们需要定义一个不同的名字,而这往往会给程序员造成很大的困扰。上面两个Max函数他们不同的就是他们参数表,参数表不同函数在运算过程中可以根据参数表实现相应对应的重载函数运算从而得到我们想要得到的东西。


函数的可扩充性:

函数的可扩充性也体现在参数表上,其可以允许缺省最右边连续几个参数不赋值。

例子如下:

void  Function2(int x, int y = Max(a, b), int z = a*b) {}

在定义了上述函数以后,我们可以使用

Function2(4,9)Function2(4,2,3)

进行运算,第二个函数即参数完全赋值,而第一个函数则将使用默认值:z=a*b进行第三个参数的填充。

然而下面这种情况不允许

Function2(4, ,3)


原因是其违背了缺省连续的几个参数的原则。

总结

至此对于引用与函数部分的内容全部讲述完毕,其主要内容总结如下:


函数部分还有这库函数与头文件、函数的定义与声明等等重要的内容没有讲述,因为相对比较简单可以自行搜阅相关资料进行了解