一:内存分区

1.代码区(程序运行前分的区)

  存放函数的二进制代码,由操作系统管理的。

特点:1.共享,共享的目的是对一些频繁被执行的程序只需要在内存中有一份代码即可。

        2.只读,目的是防止程序意外的修改了它的指令。

2.全局区(程序运行前分的区)

  全局变量和静态变量(static关键词)存放在这里。 还包含了常量区,字符串常量和全局常量(const修饰的全局变量)也存放在这里。

特点:该区域的数据在程序结束后是由操作系统释放的。

3.栈区(程序运行后分的区)

  由编译器自动分配释放,存放函数的参数值,局部变量等。

注:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。

#include <iostream>
using namespace std;

int* func()
{
	int a = 10; //栈区的局部变量
	return &a;
}

int main()
{
	int* p = func();

	cout << *p << endl;
	cout << *p << endl;

	return 0;
}

第一个值为10,因为编译器作了保留,第二次就不会保留了,值为乱码。

4.堆区(程序运行后分的区)

  由程序员分配释放,若程序员没有释放,程序结束时由操作系统回收。

  利用new将数据开辟到堆区,结束时用delete来释放。

#include <iostream>
using namespace std;

int* func()
{
	int* arr = new int(10); //指针本质是局部变量,存放在栈上,而指针保留的数据存放在堆区
	return arr;
}

//创建数组
void test()
{
	int* arr = new int[10];

	for (int i = 0; i < 10; i++)
		arr[i] = i + 100;

	for (int i = 0; i < 10; i++)
		cout << arr[i] << endl;

	delete[] arr;
}
int main()
{
	test();
	int* p = func();
	
	cout << *p << endl;
	cout << *p << endl;

	delete(p);

	return 0;
}

二:引用

1.引用的基本使用

作用:给变量起别名

语法:数据类型& 别名=原名

2.引用的注意事项

引用必须初始化。

引用一旦初始化后就不可以更改了。

3.引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参。

优点:可以简化指针修改实参,引用的语句更清楚简单。

#include <iostream>
using namespace std;

//1.值传递
void swap1(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
}

//2.地址传递
void swap2(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

//3.引用传递
void swap3(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}
int main()
{
	int a = 10, b = 20;
	//swap1(a, b); //形参不会修饰实参
	//swap2(&a, &b);//形参会修饰实参
	swap3(a, b);//形参会修饰实参
	
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;

	return 0;
}

4.引用做函数返回值

作用:引用是可以作为函数的返回值存在的

用处:函数调用作为左值

5.引用的本质

引用的本质在c++内部实现是一个指针常量。

6.常量引用

作用:常量引用主要用来修饰形参,防止误操作。

在函数行参列表中,可以加const修饰形参,防止形参改变实参。

#include <iostream>
using namespace std;

void show(const int& a)
{
	//a = 1000;//此时不可对a进行修改,会报错;
	cout << "a=" << a << endl;
}

int main()
{
	int a = 100;

	//此时编译器将代码修改为int temp=10;const int& arr=temp;
	//const int& arr = 10;
	show(a);

	return 0;
}

三:函数提高

1.函数默认参数

在c++中,函数形参列表中的形参是可以有默认值的。

语法:函数类型 函数名(参数= 默认值){}

如果在有默认值的情况下还传了数据,那么函数就会用我们传的数据。

注:①如果某个参数有默认值,那么从这个参数以后的每个参数都要有默认值。

  ②函数声明和函数实现只能有一个可以有默认值。(如果都有,会有二义性)

2.函数的占位参数

用来占位,函数调用必须填补该位置。

语法:函数类型 函数名(数据类型){}

3.函数重载

作用:函数名可以相同,提高复用性。

函数重载满足的条件:

  • 同一个作用域下
  • 函数名相同
  • 函数参数类型,个数或顺序不同
#include<iostream>
using namespace std;
//1.个数不同
void func1(int a)
{
	cout << "func1(int a)" << endl;
}
void func1(int a, int b)
{
	cout << "func1(int a,int b)" << endl;
}

//2.顺序不同
void func2(int a, double b)
{
	cout << "func2(int a,double b)" << endl;
}
void func(double a, int b)
{
	cout << "func2(double a,int b)" << endl;
}

//3.类型不同
void func3(int a)
{
	cout << "func3(int a)" << endl;
}
void func3(double a)
{
	cout << "func3(double a)" << endl;
}

int main()
{
	int a = 10, b = 20;
	double c = 3.14;
	func1(a);
	func1(a, b);
	cout << endl;

	func2(a, c);
	func2(c, a);
	cout << endl;

	func3(a);
	func3(c);

	return 0;
}

注:函数的返回类型不可以做重载条件。

注意事项:

1.引用作为重载条件

当传入10时,int& a=10不合法,所以不会调用func(int& a),而是调用func(const int& a).

2.函数重载碰到默认参数

此时会存在二义性,尽量避免这种写法。

 

 

更多推荐