new基本语法:
在堆区创建数据,new返回的是该数据类型的指针;
堆区的数据由程序员管理开辟,程序员管理释放,如果想释放利用关键字delete;
在堆区开辟数组是要注意在最后释放数组时要加上中括号,如果只有数组名就会导致只是放第一个元素;
#include<iostream>
using namespace std;
int *test1()
{
int *p = new int(10);
return p;
}
void print()
{
int *p = test1();
cout << *p << endl;
delete p;
}
int *test2()
{
int *arr = new int[10];
return arr;
}
void print2()
{
int *arr = test2();
int i;
for (i = 0; i < 10; i++) {
arr[i] = i;
}
for (i = 0; i < 10; i++) {
cout << arr[i] << endl;
}
delete[] arr;
}
int main()
{
print();
print2();
system("pause");
return 0;
}
引用:相当于给变量起别名
语法:数据类型 &别名 = 原名;
注意事项:
引用必须要初始化;
引用在初始化后,不能再改变;
引用的数据要么在栈区要么在堆区;
int a = 10;
int c = 20;
itn &b = a; //引用必须初始化;
b = c; //此时相当于将c的值赋给b,同时a也等于10
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int c = 20;
int &b = a;
b = c;
cout <<"a = "<< a << endl;
cout <<"b = "<<b<< endl;
cout<<"c = " << c << endl;
system("pause");
return 0;
}
引用做函数参数:引用传递形参会修饰实参
#include<iostream>
using namespace std;
void mySwap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
mySwap(a, b);
cout << a << endl;
cout << b << endl;
system("pause");
return 0;
}
引用做函数的返回值:
不要返回局部变量(在栈区)的引用;
函数的调用可以作为左值;
#include<iostream>
using namespace std;
int &test01()
{
int a = 20; //局部变量保存在栈中
return a;
}
int& test02()
{
static int a = 20; //静态变量保存在静态区, 全局区的数据会在程序结束之后由系统释放
return a;
}
int main()
{
int &ref = test01();
cout << ref << endl; //第一次结果正确,是因为编译器做了保留
cout << ref << endl; //第二次结果错误,是因为a的内存已经释放掉了
int &ref2 = test02();
cout << ref2 << endl;
cout << ref2 << endl;
test02() = 100; //如果函数的返回值是引用,这个函数调用可以作为左值
cout << ref2 << endl;
cout << ref2 << endl;
system("pause");
return 0;
}
**引用的本质:**引用的本质在C++内部实现是一个指针常量(指针指向不能修改,指针所指数据可以修改)
常量引用:
使用场景:用于修饰形参,防止在函数中对形参进行修改导致主函数的变量也被修改。
int &a =10; //错误10是在全局变量,不能给引用赋值
const int &ref = 10; //加入const就可以了,编译器优化了代码,int temp = 10; const int &ref = temp
例子:
#include <iostream>
using namespace std;
void show(const int &a)
{
//a = 10; 因为加入const所以不能修改值
cout << a << endl;
}
int main()
{
//int &ref = 10; //错误:引用本身需要合法内存空间,因此运行错误
const int &ref = 10; //加入const就可以了,编译器优化了代码,int temp = 10; const int &ref = temp
//加入const之后数值就不能更改了
cout << ref <<endl;
int a = 100;
show(a);
system("pause");
return 0;
}
函数:
函数默认参数:
在函数定义时给形参赋值,在主函数调用时如果给形参赋值则用该值,如果没有赋值则用默认值。
注意事项:
如果某个位置已经有了默认参数,那么从这个位置往后必须都要都默认值。
函数声明和定义时只能有一个有默认参数(加入声明中有默认参数,则定义时不能有默认参数)
#include<iostream>
using namespace std;
int data(int a, int b = 10, int c = 20); //如果添加默认参数,则该参数之后的形参都要加上默认参数
int data(int a, int b, int c) //因为声明中有默认参数,所以形参不能再加默认参数
{
return a + b + c;
}
int main()
{
int a = data(10, 20);
cout << a << endl;
system("pause");
return 0;
}
函数占位参数:
语法:返回值类型 函数名(数据类型){};
void func(int a,int) //第二个参数就是占位参数
{
…
}
占位参数可以有默认参数;
函数重载:
可以让函数名相同,提高函数复用性;
函数重载满足的条件:
1.同一个作用域下;
2.函数名称相同;
3.函数参数类型不同或者个数不同或顺序不同;
函数的返回值不可以作为函数重载的条件;
#include<iostream>
using namespace std;
void print(int a ,int b)
{
cout << "a = " << a << endl;
}
void print(int a) //参数个数不同
{
cout << "a = " << a << endl;
}
void print2(int a, char b) //参数类型不同
{
cout << "a = " << a << endl;
}
int main()
{
print(1, 2);
print(2);
print(3, 'a');
system("pause");
return 0;
}
函数重载注意事项:
1.引用作为重载的条件:
函数中参数引用加const和不加const;
int &a =10; //错误10是在全局变量,不能给引用赋值
const int &ref = 10; //加入const就可以了,编译器优化了代码,int temp = 10; const int &ref = temp
2.函数重载碰到默认参数:
函数重载碰到默认参数可能会出现二义性;
#include<iostream>
using namespace std;
//引用作为参数
void func1(int &a)
{
cout << "func1(int &a)" << endl;
}
void func1(const int &a)
{
cout << "func1(const int &a)" << endl;
}
//默认参数作为重载条件
void func2(int a, int b = 20)
{
cout <<" func2(int a, int b = 20)" << endl;
}
void func2(int a)
{
cout << "func2(int a)" << endl;
}
int main()
{
int a = 10;
func1(a); //调用的是没有加const的函数
func1(20); //调用的是加const的函数
//func2(10); 会报错
func2(10, 20);
system("pause");
return 0;
}
learned from:黑马程序员