C++蓝桥算法前置必备
- 1.C++基础回顾
- 数组中数组名的作用
- 函数的默认参数
- const修饰指针
- 2.C++中的内存分配
- 3.C++中的引用
- 函数做引用的参数
- 引用做函数的返回值
- 引用的本质
- 4.C++中的模板
1.C++基础回顾
有一定的C语言基础,下面是一些基础回顾
-
while() 重在条件判断
for( ; ; )重在计数
-
if 侧重于判断区间
case侧重判断单个数字或字符,如果case中没有break,那么将会向下执行
数组中数组名的作用
- 查看二维数组所占内存空间
#include
#include using namespace std; int main() { int arr[40]; cout << sizeof(arr) << endl; return 0; } - 获取二维数组首地址
cout << arr << endl; cout << &arr[0] << endl;
函数的默认参数
int func(int a, int b = 10, int c = 10) {return a + b + c; } //1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值 //2. 如果函数声明有默认值,函数实现的时候就不能有默认参数 int func2(int a = 10, int b = 10); int func2(int a, int b) {return a + b; } int main() {cout << "ret = " << func(20, 20) << endl; cout << "ret = " << func(100) << endl; cout << "func2 = " << func2() << endl; return 0; }
const修饰指针
看const右侧修饰的是什么,如果是指针 那就是常量指针,意思是指针指向的值不可以改,但是指针指向可以改; 如果const右侧修饰的是一个常量,那就是指针常量,意思是指针指向不可以改,但是指针指向的值可以改。后面也会遇到
int a = 100; int b = 200; //常量指针 const int * p1 = &a; // *p1 = 20; 报错 p1 = &b; cout << p1 << endl; cout << &b << endl; //指针常量 int * const p2 = &a; *p2 = 30; // p2 = &b; 报错 cout << *p2 << endl; cout << a << endl;
2.C++中的内存分配
- 内存分区的四个区域
//全局变量 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; cout << "字符串常量地址为: " << (int)&"hello world" << endl; cout << "字符串常量地址为: " << (int)&"hello world1" << endl; cout << "全局常量c_g_a地址为: " << (int)&c_g_a << endl; cout << "全局常量c_g_b地址为: " << (int)&c_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; const int c_l_a = 10; const int c_l_b = 10; cout << "局部常量c_l_a地址为: " << (int)&c_l_a << endl; cout << "局部常量c_l_b地址为: " << (int)&c_l_b << endl; return 0; }
不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
int * func() {int a = 10; return &a; } int main() {int *p = func(); cout << *p << endl; cout << *p << endl; return 0; }
全局区包括全局变量、静态变量和静态常量。同时该区域还包括字符串常量和其他常量。
该区域的数据在程序结束后有操作系统释放。
如果一定要在函数中返回局部变量的地址,那可以利用new在堆区开辟内存,堆区开辟的内存由程序员分配释放,若程序员不释放,程序结束时由操作系统回收。
int* func() {int* a = new int(10); return a; } int main() {int *p = func(); cout << *p << endl; cout << *p << endl; //利用delete释放堆区数据 delete p; //cout << *p << endl; //报错,释放的空间不可访问 return 0; }
在堆区开辟数组,注意和变量不同的是在释放的时候需要在delete后面加上[]
//堆区开辟数组 int main() {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 后加 [] delete[] arr; return 0; }
3.C++中的引用
函数做引用的参数
函数传参时,可以利用引用的技术让形参修饰实参,其效果和指针一样。
简单理解代码就是给例子中的变量a起了一个别名,但在形参中起的别名和main函数中的别名是一样的,其优点是可以简化指针修改实参。
//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); cout << "a:" << a << " b:" << b << endl; mySwap02(&a, &b); cout << "a:" << a << " b:" << b << endl; mySwap03(a, b); cout << "a:" << a << " b:" << b << endl; return 0; }
引用做函数的返回值
一定注意,不要返回局部变量引用
如果函数的返回值是引用,这个函数调用可以作为左值。
//返回局部变量引用 int& test01() {int a = 10; //局部变量 return a; } //返回静态变量引用 int& test02() {static int a = 20; 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; //因为函数的返回值是引用类型,所以函数可以作为左值; //同时 ref2是函数的一个别名,所以当函数的值改变时,引用的别名也会改变。 cout << "ref2 = " << ref2 << endl; cout << "ref2 = " << ref2 << endl; return 0; }
引用的本质
引用的本质就是在C++内部实现了一个指针常量。
意思就是指针的指向是不可以修改的,但是指针所指向的值是可以修改的。
int* const ref == &a; //两者是等价的
下面这段代码能正确的说出 那就表明明白了。
#include
using namespace std; //发现是引用,转换为 int* const ref = &a; void func(int& ref){cout << "ref:" << ref << endl; ref = 100; // ref是引用,转换为*ref = 100 } int main(){int a = 10; cout << "a:" << a << endl; //自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改 int& ref = a; ref = 20; //内部发现ref是引用,自动帮我们转换为: *ref = 20; cout << "a:" << a << endl; cout << "ref:" << ref << endl; func(a); cout << "ref:" << ref << endl; cout << "ref的地址:" << &ref << endl; cout << "a的地址:" << &a << endl; return 0; } 4.C++中的模板
目前只是简单的学习了下,方便后面在STL能够看懂并使用系统提供的模板
函数的模板使用的关键字为template
函数模板的语法
T为通用的数据类型,名称可以替换,通常为大写字母
template
使用函数的模板有两种方式:自动类型推导(就是不指定参数的类型,让编译器自己推) 第二种是显示指定类型
模板的目的是为了提高函数的复用性,将类型参数化
template
void mySwap( T &a, T &b) {T temp = a; a = b; b = temp; } void test01() {int a = 10; int b = 20; //1.有参数时 // 第一种:自动类型推导 mySwap(a, b); // 第二种: 显示指定类型 mySwap (a, b); cout << "a = " << a << endl; cout << "b = " << b << endl; } // 2、无参数时 模板必须要确定出T的数据类型,才可以使用 template void func() {cout << "func 调用" << endl; } void test02() {//func(); //错误,模板不能独立使用,必须确定出T的类型 func (); //利用显示指定类型的方式,给T一个类型,才可以使用该模板 } int main() {test01(); test02(); return 0; } 当模板无传入的形参时,模板不能独立使用,必须确定出T的类型,需要显示指定类型的方式,给T一个类型,才可以使用该模板。
所以使用模板时必须确定出通用数据类型T,并且能够推导出一致的类型。
-