面向对象编程自学笔记整理
八、程序的内存模型
/*******************************1.全局区*********************************/
//总结
//C++程序运行分为全局区和代码区
//代码区特点:共享与只读
//全局区存放:全局变量,静态变量,常量
//常量区中存放:const修饰的全局常量,字符串常量
//#include<iostream>
//using namespace std;
//
全局变量
//int g_a = 10;
//int g_b = 10;
const修饰的全局变量,全局常量
//const int c_a = 10;
//const int c_b = 10;
//
//
//int main()
//{
全局区
//
//
全局变量,静态变量,常量
创建普通局部变量
// int a = 10, b = 20;
// cout << "局部变量a的地址为:" << (int)&a << endl;
// cout << "局部变量b的地址为:" << (int)&b << endl;
//
// cout << "全局变量g_a的地址为:" << (int)&g_a << endl;
// cout << "全局变量g_b的地址为:" << (int)&g_b << endl;
//
// //静态变量,在普通变量前加static,属于静态变量
// static int s_a = 10;
// static int s_b = 10;
// cout << "静态变量s_a的地址为:" << (int)&s_a << endl;
// cout << "静态变量s_b的地址为:" << (int)&s_b << endl;
//
// //常量
// //字符串常量
// cout << "字符串常量的地址为:" << (int)&"hello world" << endl;
// //const修饰的局部变量
// const int c_la = 10;
// const int c_lb = 10;
// cout << "局部常量c_la的地址为:" << (int)&c_la << endl;
// cout << "局部常量c_lb的地址为:" << (int)&c_lb << endl;
//
// cout << "全局常量c_a的地址为:" << (int)&c_a << endl;
// cout << "全局常量c_b的地址为:" << (int)&c_b << endl;
// //c_const常量 g_global全局 l_local 局部
// system("pause");
// return 0;
//}
/*******************************2.栈区*********************************/
//#include<iostream>
//using namespace std;
//
栈区由编译器自动释放,存放函数的参数值,局部变量
注意事项:不要返回局部变量的地址,栈区开辟的地址由编译器自动释放
//
//int* func(int b)//形参变量也会存放在栈区
//{
// b = 100;
// int a = 10;//局部变量,存放在栈区,栈区数据在函数执行完后会自动释放
// return &a;//返回局部变量地址
//}
//int main()
//{
// //接受func函数返回值
// int * p = func(10);
// cout << *p << endl;
// cout << *p << endl;
//
// system("pause");
// return 0;
//}
/*******************************3.堆区*********************************/
//#include<iostream>
//using namespace std;
//
堆区的数据由程序员决定保存和释放
//int* func()
//{
利用关键字new,可以将数据开辟到堆区
// //指针本质为局部变量,放于栈上,指针保存的数据放在堆区
// int *p=new int(10);
// return p;
//}
//
//int main()
//{
// //在栈区开辟数据
// int* p = func();
// cout << *p << endl;
// system("pause");
// return 0;
//}
/*******************************4.new操作符*********************************/
//new在堆区开辟内存空间
//delete在堆区释放内存空间
#include<iostream>
using namespace std;
//1.new的基本语法
int* func()
{
//在堆区创建整形数据
//new返回 该数据类型指针
int* p = new int(10);
return p;
}
void test01()
{
int* p = func();
cout << *p << endl;
//堆区的数据由程序员管理开辟,由程序员管理释放
//如果想释放堆区的数据,利用关键字delete
delete p;
//cout << *p << endl;//内存已经被释放,再次访问就是非法操作,会报错
}
//2.在堆区利用new开辟数组
void teat02()
{
//在堆区创建10整形数组
int* arr = new int[10];//代表数组有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()
{
test01();
teat02();
system("pause");
return 0;
}
九、变量引用
/*************************1.引用的基本语法注意事项**********************************/
//#include<iostream>
//using namespace std;
//int main()
//{
引用:给变量起别名
语法:数据类型 &别名=原名;
// /*int a = 10;
// int& b = a;
// cout << "a=" << a << endl;
// cout << "b=" << b << endl;
// b = 1000;
// cout << "a=" << a << endl;
// cout << "b=" << b << endl;*/
引用的注意事项:
1.引用必须要初始化
// //int& b;//错误,必须初始化
2.引用一旦初始化就不可更改
// int a = 10;
// int& b = a;
// int c = 20;
// b = c;//赋值操作
// cout << "a=" << a << endl;
// cout << "b=" << b << endl;
// cout << "c=" << c << endl;
// system("pause");
// return 0;
//}
/*************************2.引用做函数参数**********************************/
//#include<iostream>
//using namespace std;
交换函数
1.值传递
//void swap01(int a,int b)
//{
// int temp;
// temp = a;
// a = b;
// b = temp;
// /*cout << "swat01 a=" << a << endl
// << "sawt01 b=" << b << endl;*/
//}
//
2.地址传递
//void swap02(int *a,int *b)
//{
// int temp;
// temp = *a;
// *a = *b;//解引用
// *b = temp;
//}
//
3.引用传递
//void swap03(int& a, int& b)
//{
// int temp;
// temp = a;
// a = b;
// b = temp;
//}
//
//int main()
//{
// int a = 10, b = 20;
// //swap01(a, b);//值传递,形参不会修饰实参
// //swap02(&a, &b);//地址传递,形参可以修饰形参
// swap03(a, b);//引用传递,形参可以修饰实参
// cout << "a=" << a << endl
// << "b=" << b << endl;
// system("pause");
// return 0;
//}
/************************* 3.引用做函数的返回值**********************************/
//#include<iostream>
//using namespace std;
//
引用做函数的返回值
1.不要返回局部变量的引用
//int& test01()
//{
// int a = 10;//局部变量存放在栈区,函数执行完就销毁
// return a;
//}
2.函数的调用可以作为左值
//int& test02()
//{
// static int a = 10;//静态变量存放于全局区,全局区的数据在程序结束后释放
// return a;
//}
//
//int main()
//{
// //int ref1 = test01();
// //cout << "ref1=" << ref << endl;//结果错误,内存已经释放
// //cout << "ref1=" << ref << endl;
//
// int ref2 = test02();
// while (1)
// {
// cout << "ref2=" << ref2 << endl;
// cout << "ref2=" << ref2 << endl;
// }
// test02()=100;//函数返回值为引用,这个函数的调用可以作为左值
// while (1)
// {
// cout << "ref2=" << ref2 << endl;
// cout << "ref2=" << ref2 << endl;
// }
// system("pause");
// return 0;
//}
/************************* 4.引用的本质**********************************/
//引用的本质就是在C++内部实现一个指针常量
//const (前值后向)
//const 在前 指针指向的值不可更改 const int *p=&a;
//const 在后 指针指向的方向不可更改 int *const P=&a;
//发现是引用,转换为 int *const ref=&a;
//#include<iostream>
//using namespace std;
//
//void func(int& ref)
//{
// ref = 100;
// //转换为*rer=100;
//}
//int nain()
//{
// int a = 10;
// //自动转化为int * const ref=&a;
// //指针指向不可改变,这也就是引用不可更改的原因
// int& ref = a;
// ref = 20;//ref是引用,转化为*rer=20;解引用
//
// cout << "a=" << a << endl;
// cout << "ref=" << ref << endl;
//
// system("pause");
// return 0;
//}
/************************* 5.常量的引用**********************************/
#include<iostream>
using namespace std;
//打印数据函数
void showvalue(const int &value)//加const 防止形参中的数据改变实参中的值
{
//value = 1000;//值不可更改,报错
cout << "value=" << value << endl;
}
int main()
{
//作用:常量引用主要是用来修饰形参,防止误操作
//使用场景:可以用const修饰形参,防止形参改变形参
//int a = 10;
//const int& ref = 10;//引用必须引用一块合法的内存空间
//加上const后,编译器将代码修改为int temp=10; const int &ref=temp;
//ref = 20;//报错:const(前值后向)在前,引用的值不可更改
int a = 10;
showvalue(a);
cout << "a=" << a << endl;//发生形参中的赋值将实参中的数据更改的情况
system("pause");
return 0;
}
十、函数的高级应用
/********************1.函数默认参数***********************************/
//#include<iostream>
//using namespace std;
//
函数默认参数
若用户传入数据,就用用户传入数据,若没有,就用默认值
语法:返回值类型 函数名 (形参=默认值)
//int func1(int a, int b, int c)
//{
// return a + b + c;
//}
//int func2(int a, int b=20, int c=10)
//{
// return a + b + c;
//}
//
注意事项
1.某个位置已经有了默认参数,从这个位置往后,从左到右都必须要有默认值
int func2(int a=10, int b, int c )
{
return a + b + c;
}
2.如果函数的声明有了默认参数,函数实现就不能有默认参数
声明和实现只能有一个设有默认参数
//int func3(int a=10, int b=20);//函数声明
//int func3(int a, int b)//函数实现
//{
// return a + b;
//
//}
//int main()
//{
// cout << func1(10, 30, 20) << endl;
// cout << func2(10,40) << endl;
// cout << func3(10, 40) << endl;
// system("pause");
// return 0;
//}
/********************2.函数占位参数***********************************/
//C++中形参列表必须要有占位参数,调用该位置时必须要填补该位置
//语法:返回值类型 函数名(数据类型){}
//#include<iostream>
//using namespace std;
//
占位参数
目前阶段的占位参数还用不到,后续阶段或用到
//void func1(int a, int)
//{
// cout << "this is func1!" << endl;
//}
//
//void func2(int a, int =10)
//{
// cout << "this is func2!" << endl;
//}
//int main()
//{
// func1(10, 10);
// func2(10);
// system("pause");
// return 0;
//}
/********************3.函数重载***********************************/
//作用:函数名相同,提高复用性
//函数重载的条件
/*
1.同一个作用域
2.函数名称相同
3.函数参数类型不同或者个数不同或者顺序不同
*/
//注意:函数返回值不可以作为函数重载的条件
//#include<iostream>
//using namespace std;
//
条件1.必须在同一个作用域下
条件2.函数名称相同
条件3.函数参数类型不同,或者个数不同,或者顺序不同
//
//void func()
//{
// cout << "func的调用" << endl;
//}
//
//void func(int a)
//{
// cout << "func(int a)的调用!" << endl;
//}
类型不同
//void func(double a)
//{
// cout << "func(double a)的调用!" << endl;
//}
顺序不同
//void func(int a, double b)
//{
// cout << "func(int a,double b)的调用!" << endl;
//}
//
//void func(double a, int b)
//{
// cout << "func(double a,int b)的调用!" << endl;
//}
//
注意:函数返回值不可以作为函数重载的条件
int func(double a, int b)
{
cout << "func(double a,int b)的调用!" << endl;
}
//
//
//int main()
//{
// func();
// func(10);
// func(3.145);
// func(3, 4.5);
// func(3.3, 3);
// system("pause");
// return 0;
//
//}
/********************4.函数重载的注意事项***********************************/
#include<iostream>
using namespace std;
//函数重载的注意事项
//1.引用作为重载条件
void func(int& a)//int &a=10 不合法;
{
cout << "func(int &a)的调用" << endl;
}
void func(const int& a)//const int &a=10;合法
{
cout << "func(const int &a)的调用" << endl;
}
//2.函数重载作为函数的默认参数,出现二义性
void func2(int a,int b=10)
{
cout << "func2(int a,int b)的调用" << endl;
}
void func2(int a)
{
cout << "func2(int a)的调用" << endl;
}
int main()
{
//int a = 10;//变量传入,选择上面的调用
//func(a);
//func(10);
//func2(10);//当函数重载碰到默认参数,会出现二义性,产生歧义,函数重载不加默认参数报错
system("pause");
return 0;
}