#include<iostream>
using namespace std;//标注空间
#include<string>
#include<time.h>
#include<cstdlib>
//面向对象
/*C++在执行过程当中4个区域:代码区:存放二进制代码,由操作系统进行管理;
全局区:存放全局变量以及静态变量(static)、常量;
栈区:由编译器自动分配释放,存放函数的参数值、局部变量、等
堆区:由程序员分配与释放,若程序员不释放,程序结束时系统会回收
(不同的区存放数据,赋予的生命周期不同灵活性不同)
*/
//程序运行 !前!:在编译后生成exe可执行程序,未执行程序前可分为两个区域 (在还没运行程序前就有了 代码区 全局区)
//代码区:存放CPU执行的机械指令((由二进制存储)写的代码); 代码区是 !共享的(频繁执行的程序在内存当中有一份代码即可)!
//! 只读的(防止程序意外修改代码)!
//全局区:全局变量、静态变量、常量(字符串常量、其他常量) 【这个区域的数据在程序结束之后由 操作系统 管理与释放】
//有全局修饰的变量都在全局区当中!
//全局变量(不再函数体当中的变量)
//int g_a = 10;
//int g_b = 10;
//int main()
//{
//写在函数体内的变量都叫局部变量!!!!!
//int a = 10;
//int b = 10;
//cout << "局部变量a 的地址是多少: " << (int)&a << endl;//(int )强制转换为10进制数
//cout << "全局变量a 的地址是多少: " << (int)&g_a << endl;
//cout << "局部变量 b 的地址是多少: " << (int)&b << endl;
//cout << "全局变量a 的地址是多少: " << (int)&g_b << endl;
//全局变量与局部变量不是放在一个内存区当中
//静态变量
//static int s_a = 10;//在普通变量前面加上 "static" 属于静态变量---也放在全局区当中!
//常量
//字符串常量:由 "" 引起来的字符都叫字符串常量!---也在全局区当中
//cout << "字符串常量的地址为: " << (int)&"hellow" << endl;
//const修饰的变量(全局与局部)
//return 0;
//}
//程序运行 !后 !的:
//栈区:由编译器自动分配释放,存放函数的参数值、局部变量、等----不要返回局部变量的地址!!!!!
//堆区: 由 !程序员 !分配与释放,若程序员不释放,程序结束时系统会回收
//在堆区当中开辟内存:new 关键字 与 delete 关键字(C++当中)!!!!!
//栈区
//int* fh(int b)//b-形参也会放在栈区
//{
// int a = 10;//局部变量;-----存放在!栈区!,栈区的数据在函数执行完后自动释放!
// return &a;//返回局部变量的地址!
//}
//int main()
//{
// int *p = fh(1);//接收fh的返回值
// cout << *p << endl;//编译器会保留一次 所以第一次可以打印正确的数据
// cout << *p << endl;//当函数执行玩栈上的数据就清空了 第二次数据就不再保留
// return 0;
//}
//堆区 (new语句)
//释放利用 “delete”操作符
//int *func()
//{
// //利用new关键字 可以开辟数据到堆区!(new 数据类型(初始值);-创建一个变量其值是初始值!!!!!)会返回new 区值的 地址 !!!!!应该用地址指针来接收它!
// int *p=new int(10);//但这个指针本质上还是 局部变量!-也是放在 栈区 但是指针保存的数据放在了 堆区!!!!!
// return p;
//}
//void test01()
//{
// int *p = func();
// cout << *p << endl;
//
// //释放堆区
// delete p;
// cout << *p << endl;//内存已经被释放 再次范围即错误!
//}
////在堆区开辟数组()
//void test02()
//{
// //创建10个整形数据的数组! 在堆区
// int *arr=new int[10];//创建一个数组 new 数据类型[数组当中的元素个数];!!!!!-----会返回这一段连续内存空间的 首地址!
// for (int i = 0; i < 10; i++)
// {
// arr[i] = i + 100;//给堆区当中的数组元素 赋值!!!!!
// }
// for (int j = 0; j < 10; j++)
// {
// cout << arr[j] << endl;//打印堆区当中数组的元素!!!!!
// }
// delete[] arr;//释放数组的时候要加[] 才可以释放
//}
//int main()
//{
// //test01();
// //int *p = func();
// //cout << *p << endl;
// //cout << *p << endl;
// //cout << *p << endl;//不管打印几次 只要不释放值都在 直到结束程序的运行系统会自然释放!!!!!
// test02();
// return 0;
//}
//引用:给函数起 别名 ----- 数据类型 &别名=原名 (别名可以和原名是一样的)!!!!!
//注意事项:必须初始化;引用初始化后 不可以 改变!!!!!
//int main()
//{
// //引用
// int a = 10;
// //引用的初始化
// int &b = a;
// cout << "a= " << a << endl;
// cout << "&a= " << &a << endl;
// cout << "b= " << b << endl;
// cout << "&b= " << &b << endl;//操作同一块 内存!
// //引用初始化后不可以改变!!!!! 赋值操作而不是更改引用!!!!!
// int c = 20;
// b = c;//赋值操作会是赋给那块内存 所以都会受到影响!!!!!
// cout << "a=" << a << endl;
// cout << "&a=" << &a << endl;
// cout << "b=" << b << endl;
// cout << "&b=" << &b << endl;
// cout << "c=" << c << endl;
// cout << "&c=" << &c << endl;
//
// return 0;
//}
//引用作函数参数:传递参数的时候可以 用引用的技术让 形参修饰实参-----可以简化指针修饰操作!!!!!
//利用引用实行外部函数 功能是-交换数据
//1.值传递(形参不会修饰实参)
//void test01(int a,int b)
//{
// int temp = a;
// a = b;
// b = temp;
// cout << " a1= " << a << " b1= " << b << endl;//形参发生改变
//}
// //2.地址传递(利用形参取修饰实参)
//void test02(int *a,int *b)
//{
// int temp = *a;
// *a = *b;
// *b = temp;
// cout << " a2= " << *a << " b2= " << *b << endl;
//}
// //3.引用传递(形参也会修饰实参!!!!!)
//void test03(int &a,int &b)//引用符 int &a=b;
//{
// int temp = a;
// a = b;
// b = temp;
// cout << " a3= " << a << " b3= " << b << endl;
//}
//
//int main()
//{
// int a = 10;
// int b = 20;
//
// test01(a, b);
// cout << " a0.1= " << a << " b0.1= " << b << endl;//实参没发生改变!
// test02(&a, &b);
// cout << " a0.2= " << a << " b0.2= " << b << endl;//实参受形参影响发生改变;
// test03(a, b);
// cout << " a0.3= " << a << " b0.3= " << b << endl;//实参受形参影响发生改变;!!!!!
// return 0;
//}
//引用作函数返回值:
//1.!不要 !返回局部变量的引用
//int& test01()//int& -----表示局部变量的返回了
//{
// int a = 10;//局部变量 存放在四区当中的:栈区
// return a;
//}
//2.函数的调用可以作为左值存在
//int& test02()
//{
// static int b = 90;//static-静态变量关键字!!!!! 存放在全局区!在程序结束后才由系统释放!
// return b;
//}
//int main()
//{
// int &ref = test01();
// cout << ref << endl;//第一次可以打印是因为 栈区的保留!!!!!
// cout << ref << endl;//第二次栈区清空释放 所以结果是错误的!!!!!
//
// int &ref2 = test02();
// cout << ref2 << endl;
// test02() = 1000;
// cout << ref2 << endl;//函数的调用可以作为左值存在 -----可以作为被赋值的对象!!!!!
// //这还是对 b的存储区进行赋值! ref2只是b的别名!!!!!!
// return 0;
//}
//引用的本质是实现一个 指针常量!!!!!(指针的指向是不能修改的 但是值是可以改动的)!!!!!
int main()
{
int a = 10;
int &ref = a;
//其实等价于: int *const ref=&a;(指针的指向是不能修改的 所以引用指向是不能修改的!) const 是固定
ref = 20;
//编译器内部理解为 *ref=20;
cout << "a:" << a << endl;
cout << "ref:" << ref << endl;
return 0;
}
//常量引用:用来const 修饰形参 防止误操作!!!!!
void showl(int &val)
{
val = 900;
cout << val << endl;
}
void showl2(const int &val)
{
val = 900;//显示错误了!!!!!就不会修改值
cout << val << endl;
}int main()
{
//int a = 10;
//int & ref = a;//引用必须引用一块合理的内存空间!!!!!
////int & ref = 10;是错误的
//const int & ref = 10;//是正确的 加上const后 编译器将代码修改为:int temp=10;int & ref=temp;!!!!!
////但是这样 ref=20;修改其就是错误的了!!!!!
int a = 100;
showl(a);
cout << a << endl;
return 0;}