c++编程基础二

111 阅读4分钟

内存分区模型

c++执行时将内存分为划分4个区域
1.代码区:存放函数体的二进制代码,由操作系统进行管理的
2.全局区:存放全局变量和静态变量以及常量
3.栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
4.堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
在程序编译后:生成exe可执行程序,未执行该程序分为两个区域
代码区:
	存放CPU执行的机械指令
    代码区时共享区,共享目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
    代码区时只读的,使其只读的原因防止程序意外修改它的指令
 全局区:
 	全局变量和静态变量放在此。
    全局区还包含了常量区,字符串常量和其他常量也存放在此。
    该区域的数据在程序结束后操作系统释放。
全局变量:
静态变量:static int a;

程序运行后的内存:
	//栈区数据注意事项 --- 不要返回局部变量的地址
    //栈区的数据由编译器管理开辟和释放

{
	int *func(){	// 返回指针需要加*
    	int a=10;
        return &a;
    }
    int main(){
    	int *p =func;
        cout<<*p<<endl;	//第一次还可以
        cout<<*p<<endl;	//第二次出现乱码,因为局部变量用完就释放,所以不能返回
    }
}

堆区:由程序员分配释放若程序员不释放,程序结束时由操作系统回收
在c++中主要利用new在堆区开辟内存
void *func(){
	//利用关键字new可以将数据开辟到堆区
    int *p = new int(10);	// 10就是初始值
    return a;
}
int main(){
	int *p=func();
    cout<<p<<endl;	//这次就没有问题了
    return 0;
}
// 利用delete释放堆内存
int *func(){
	int *p = new int(10);	//如果数组 new int[10]	//代表10个元素
    return p;
}
int *func(){
	int *arr = new int[10];
    for(int i=0;i<10;i++){
    	arr[i]=i+100;
    }
}
int main(){
	
    int *p=func();
    //利用关键字delete释放
    delete p;
    // 如果释放数组
    delete[] arr;	//释放数组
	return 0;
}

引用

作用:给变量其别名
语法:数据类型 &别名=原名;
int a=10;
int &b=a;	//b可以操作a引用

注意事项:
1.引用必须要初始化;
2.引用一旦执行初始化以后就不可以更改;

引用做函数参数:
作用:函数传参时,可以利用引用的技术让形参修饰实参
优点:可以简化指针修改实参

//1.值传递
void mySwap01(int a,int b){
	int temp=a;
    a=b;
    b=temp;
}
//2.地址传递
void mySwap02(int *a,int *b){
	int temp=*a;
    *a=*b;
    *b=temp;
}
//3.引用传递
void mySwap03(int &a,int &b){
	int temp=a;
    a=b;
    b=temp;
}
int main(){
	int a=10;
    int b=20;
    mySwap01(a,b);
    mySwap02(&a,&b);
    mySwap03(a,b);
    return 0;
}

引用做函数返回值
作用:
不要返回局部变量的引用
int &est01(){
	int a = 10;	// 局部变量会出问题,存放在栈中
   	static int a=10;	//静态变量放在全局中
    return a;
}

int main(){
	int &ref=tes01();
    test01()=1000;	//如果函数的返回值是引用,这个函数调用可以作为左值,可以赋值
    return 0;
}

引用的本质:就是指针常量
void func(int& ref){
	ref=100;
}
int main(){
	int a=10;
	int& ref=a;
	ref=20;
	cout<<a<<endl;
	cout<<ref<<endl;
	func(a);
	return 0;
}
int* const ref = &a;

常量引用:
作用:修饰形参,防止失误

int a=10;
const int &ref=a;//引用必须要一块合法的内存空间
ref = 20;	//加入const之后变为只读,不可以修改
ref = 30;	// 错误
return 0;

void showValue(const int &val){
	val=100;
    cout <<val<<endl;
}

函数提高:

1.函数的默认参数 只要有默认参数就之后的后面都必须要有
int func(int a, int b=10;int c=10){
	return a+b+c;
}
2.函数的中声明和实现中只能有一个默认参数

函数占位参数:
返回值类型 函数名 (数据类型){}
void func(int a,int){	// 第二个就是占位参数
	
}
占位参数还可以有默认参数:
void func(int a,int=10){}	//

函数重载:函数名可以相同,提高复用性
函数重载条件:
1.同一个作用域下
2.函数名称相同
3.函数参数类型不同或者个数不同或者顺序不同
注意:函数的返回值不可以作为函数重载的条件
example:
void func(){
	cout<<"func的调用"<<endl;
}
void func(int a){	
	cout<<"func的调用!"<<endl;
}


函数重载注意事项:
1.引用作为重载的条件
const也可以
int a	void func(int &a)//这个是变量	func(10)//这个是常量
2.函数重载碰到默认参数
默认参数就容易报错,函数重载尽量不要写二进制