首页 / C++ / C++核心编程(一)
C++核心编程(一)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C++核心编程(一),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7245字,纯文字阅读大概需要11分钟。
内容图文
![C++核心编程(一)](/upload/InfoBanner/zyjiaocheng/592/db966091a13e438dbb9edbd249266806.jpg)
1. 内存分区模型
1.1 c++程序在执行时,将内存大方向划分为4个区域
- 代码区:存放函数体的二进制代码,由操作系统进行管理的
- 全局区:存放全局变量和静态变量以及常量
- 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
1.2 程序运行前
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域
代码区:
- 存放CPU执行的机器指令
- 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
- 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令
全局区:
- 全局变量和静态变量存放
- 全局区还包含了常量区,字符串常量和其他常量也存放在此
- 该区域的数据在程序结束后由操作系统释放
//全局变量
int g_a =10;
int g_b = 10;
//全局常量
const int c_g_a = 10;
const int c_g_b = 10;
int main(){
//局部变量
int a= 10;
int b = 10;
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 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修饰的全局常量和局部常量
cout<<"全局常量c_g_a的地址"<< (int)&c_g_a <<endl;
cout<<"全局常量c_g_b的地址"<< (int)&c_g_b <<endl;
const int c_a = 10;
const int c_b = 10;
cout<<"局部常量c_a的地址"<< (int)&c_a <<endl;
cout<<"局部常量c_b的地址"<< (int)&c_b <<endl;
//全局变量,静态变量,字符串常量,全局常量 放在全局区
//局部变量和局部常量 不在全局区(栈区)
system("pause");
return 0;
}
1.3 程序运行后
栈区:
由编译器自动分配释放,存放函数的参数值,局部变量等
注意事项:不要返回局部变量的地址,战区开辟的数据由编译器自动释放
int* func()
{
int a = 10;//局部变量 存放在栈区,栈区的数据在函数执行完后自动释放
return &a;
}
int main()
{
int *p = func();
cout << *p <<endl;//第一次可以打印正确的数字,是因为编译器做了保留
cout << *p << endl;//第二次这个数据就不再保留
system("pause");
return 0;
}
堆区:
由程序员分配释放,若程序员不释放,程序结束时由操作系统回收,在c++中主要利用new在堆区开辟空间
int *func()
{
int * p = new int(10); //用指针存储在堆区创建的地址
return p;
}
int main()
{
int *p = func();
cout<< *p <<endl;
cout<< *p <<endl;
system("pause");
return 0;
}
1.4 new
操作符
- c++中利用
new
操作符在堆区开辟数据 - 堆区开辟的数据由程序员手动开辟,手动释放,利用操作符
delete
- 语法:
new 数据类型
- 利用
new
创建的数据会返回该数据对应的类型的指针
int * func()
{
//在堆区创建整型数据
//new返回是 该数据类型的指针
int *p = new int(10);
return p;
}
void test01()
{
int *p = func();
cout << *p << endl;
cout << *p << endl;
//堆区的数据由程序员开辟和释放
delete p;
cout << *p <<endl; //发生错误(内存已释放)
}
void test02()
{
//创建整型数组,在堆区
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()
{
test01();
test02();
system("pause");
return 0;
}
2. 引用
2.1 引用的基本使用
作用:给变量其别名
语法:数据类型 &别名 = 原名;
int a = 10;
int &b = a;
b = 20 ; //此时a也变为20,因为a,b都是指向同一块内存
2.2 引用注意事项
- 引用必须初始化
- 引用在初始化后,不可以改变
int a = 10;
int &b = a; // 引用后面必须有=
int c = 12;
b = c; //这是赋值,不是更改别名,此时abc都为12
2.3 引用做函数参数
作用:函数传参时,可以利用引用的技术让形参修饰实参
优点:可以简化指针修改实参
//值传递
void swap01(int a, int b)
{
int temp = a;
a = b;
b =temp;
}
//地址传递
void swap02(int *a ,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//引用传递
void swap03(int &a , int &b)
{
int temp = a;
a = b;
b =temp;
}
int main()
{
int a= 10;
int b = 20;
swap01(a,b);
cout <<"a = "<<a<<"b = "<<b<<endl;
cout << "------------------------"<<endl;
swap02(&a,&b);
cout <<"a = "<<a<<"b = "<<b<<endl;
cout << "------------------------"<<endl;
swap03(a,b);
cout <<"a = "<<a<<"b = "<<b<<endl;
system("pause");
return 0;
}
总结:通过引用参数产生的效果同按地址传递是一样的
2.4 引用做函数的返回值
注意:不要返回局部变量引用
函数的调用可以作为左值
int& test01()
{
int a = 10;
return a;
}
int& test02()
{
static int a = 10; //静态变量
return a;
}
int main()
{
int &ref = test01();
cout << "ref = " << ref <<endl;//第一次编译器会保留
cout << "ref = " << ref <<endl;//第二次不保留
int &ref2 = test02();
cout << "ref2 = " << ref2 <<endl;
cout << "ref2 = " << ref2 <<endl;
test02() = 1000; //函数的调用可以作为左值(前提是函数的返回值是引用)
cout << "ref2 = " << ref2 <<endl;
cout << "ref2 = " << ref2 <<endl;
system("pause");
return 0;
}
2.5 引用的本质
实质:引用的本质在c++内部实现是一个指针常量
int a = 10;
int & ref = a; //自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改
ref = 20; //内部发现ref是引用,自动转换为: *ref = 20;
2.6 常量引用
作用:常量引用主要用来修饰形参,防止误操作
在函数形参列表中,可以加const
修饰形参,防止形参改变实参
void showValue(const int &val)
{
val = 1000;//加了const,报错,不可修改
cout << "Val = " << val <<endl;
}
int main()
{
//int a= 10;
//int &ref = a;
// int &ref = 10; 报错, 引用必须引一块合法的内存空间
// const int & ref = 10; 不报错,加上const之后,编译器将代码修改 int temp = 10; const int &ref = temp; ref 不可修改
int a = 100;
showValue(a);
system("pause");
return 0;
}
3. 函数
3.1 函数的默认参数
在C++中,函数的形参列表中的形参是可以有默认值的
语法:返回值类型 函数名 (参数 = 默认值) {}
int func(int a , int b = 20 , int c = 30)
{
return a+b+c;
}//如果我们传入了数据,就用自己的数据,如果没有,就用默认值
//注意事项
//1、如果某个位置已经有了默认参数,那么从这个位置往后,都必须有默认值
//2、如果函数的声明有了默认参数,函数的实现就不能有默认参数
/*
int func1(int a = 10, int b = 20);
int func1(int a = 10, int b = 20) //错误,声明有了默认值,实现不可以有默认值
{
return a+b;
}
*/
int main()
{
cout << func(10) <<endl; // =60
cout << func(10 , 30) <<endl; // =70
system("pause");
return 0;
}
3.1 函数占位参数
C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
语法:返回值类型 函数名 (数据类型){}
void func(int a , int)
{
cout << "this is func"<<endl;
}
void func1(int a , int = 10) //占位参数可以有默认值
{
cout << "this is func"<<endl;
}
int main()
{
func(10 , 20);
func1(10);
system("pause");
return 0;
}
3.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 main()
{
func();
func(10);
func(3.14);
func(10, 3.14);
func(3.14, 10);
system("pause");
return 0;
}
注意事项
- 引用作为重载条件
- 函数重载碰到函数默认参数
void func(int &a)
{
cout << "func (int &a)调用" << endl;
}
void func(const int &a)
{
cout << "func (const int &a)调用" << endl;
} // const int 和 int 类型不同
//当函数重载碰到默认参数,出现二义性,报错,尽量避免这种情况(传两个值可以,但传一个参数就会有二义性)
void func1(int a , int b =10)
{
cout << "func1 (int a , int b =10)调用" << endl;
}
void func1(int a)
{
cout << "func1 (int a)调用" << endl;
}
int main()
{
int a = 10;
func(a);//调用func (int &a)
func(10); //调用func (const int &a)
system("pause");
return 0;
}
内容总结
以上是互联网集市为您收集整理的C++核心编程(一)全部内容,希望文章能够帮你解决C++核心编程(一)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。