目录
前言:
一.缺省参数
1.缺省参数的概念
2.缺省参数的分类
全缺省参数
半缺省参数
二,函数重载
1,函数重载的概念
2,调用原理
3,函数重载底层实现原理
三,写静态库与使用
四,引用
1,引用的概念
2,引用特性
3,常引用
4,使用场景
5,引用与指针的区别(可以点以下链接 ,非常详细哟)
6, 宏
五,内联函数
1,定义
六,auto关键字
1,定义: auto具有自动存储器的局部变量。
2,auto使用场景
3,auto不能使用的时候
七,指针空值nullptr
前言:
有兴趣的小伙伴可以跟着筱俞一起学习c++哦,让我们每天都进步一点点。点赞关注不迷路呀!!对内容有什么疑惑的可以评论或者私信我呢,我会尽快回复的呢。
c++既然称为c语言的进化版本那么对于函数参数,c++相对于c语言在函数参数更加严谨。
缺省参数从字面意思来看就是缺失省去了一个参数,但我们还能理解为备胎,这个词在生活中并不少见,而且这个词也可以让我们很好的理解什么是缺省参数。就是说我们有一个备胎,然后如果现在没有对象的话就可以直接用备胎,如果有的话,那么也不需要去管那个备胎。虽然这样解释有点不恰当,咳咳勿喷,口下留情。但是缺省参数就是这样的一个存在。
定义:缺省参数就是声明或者定义时给函数的参数给一个默认值,在调用的时候如果没有给定实参,那么就采用该默认值,否则就使用给定的实参。
int A(int a = 1) {
return a;
}
int main() {
A();//此时没有给定实参那么就输出1
A(10);//此时给定实参那么就输出10
}
//此时三个参数都给定了缺省参数
int A(int a = 1, int b = 2,int c = 3){
return a;
}
//此时只有俩个参数给定了缺省参数,这时为半缺省参数
int A(int a, int b = 2,int c = 3){
return a;
}
注意:
半缺省参数必须要从左向右依次给定,并且不可以间隔啊,好兄弟要整整齐齐的
缺省参数不能在函数声明和定义中同时出现,如果不一样的话那么编译器就会拿不定主意啊,他不想给你承担后果,所以他就会给你报错,让你自己去判断
缺省参数必须是常量或者全局变量
要记得c语言可不支持哟
在学习的过程中我还认识了cdecl这个关键字,就记录下来了,现阶段就学到了以下,以后遇到再进行补充:
他的作用是调用约定,顾名思义是调用函数之前提前约定好一些事情。用法以后补充呀。
在语言中,一个词可以有很多的意思,但是我们可以根据上下文的联系来理解他的意思,即该词呗重载了。
所以函数重载也可以理解为一词多义。
定义:是函数的一种特殊情况,c++允许在同一个作用域里面声明几个功能类似的同名函数,但是他们的形参列表(参数个数,类型,顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
注意:函数重载与返回值类型是否相同无关
int Add(int left, int right) {
return left + right;
}
double Add(double left, double right) {
return left + right;
}
long Add(long left, long right) {
return left + right;
}
int main() {
Add(1, 2);
Add(1.1, 2.2);
Add(1L, 2L);
return 0:
}
当所给实参,满足其中一个函数时候,那么就直接调用此函数;当所给实参没有确定的函数时候,那么编译器会尝试隐式类型转换,如果还是无法从找到,那么就会报错。
有时候在c++工程里面可能需要将某些函数按照c语言的方式来编译,那么就可以在函数前面加上extern “C”,他就可以告诉编译器,将该函数按照c语言规则来编译。
extern "C" int Add(int left, int right);
int main() {
Add(1, 2);
Add(1.1, 2.2);
Add(1L, 2L);
return 0;
}
简单描述一下:
/*
* 方法一:
#pragma comment(lib,"静态库所在的位置")
#include"静态库的名字";
方法二:
直接调节VS的设置(较为繁琐,我另写一篇,想看的可以去看)
*/
引用并不是新定义了一个变量,而是给已经存在的变量一个新的名称,他不会重新开辟空间,他与他的变量一起使用一块空间;引用达到了和指针类似的效果,注意仅仅是类似,指针和引用还有有区别的。
概念:给某个实体取别名,目的为了简化代码。
引用可以说是“外号”,就是我们平时给朋友取外号,给王者荣耀,英雄联盟里面的英雄,野怪取外号一样,虽然我们叫的不是他们本来的名字,但是我们说出来他的外号就知道是他,引用也是这样的意思。
void Test1() {
int a = 1;
int& ra = a;
cout << a << endl;
cout << ra << endl;
}
int main() {
Test1();
}
运行如下,a与ra值相同。
注意:引用类型必须和实体是同种类型。
如:int& ra;//这条语句就是错误的,编译器会报错
会使用const关键字。
void Test()
{
const int a = 10;
//int& ra = a;因为a用const修饰限定则a为常量
const int& ra = a;
const int& b = 1;
//int& b = 1;b为常量
double d = 23.34;
//int& rd = d;类型不同
const int& rd = d;
}
1,做参数
void Swap(int& left,int& right)
{
int temp = left;
left = right;
right = temp;
}
2,做返回值
int& Cout()
{
static int n = 0;
n++;
return 0;
}
写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/124197884
注意:const修饰的内容不仅仅是一个常量,还具有宏替换的效果,并且发生在编译时。
int main() {
const int a = 0;
int* pa = (int*)a;//因为a的类型为const int*,所以要强制类型转换
*pa = 10;
cout << a << endl;
cout << *pa << endl;
return 0;
}
此时很明显a的值并没有改变,这就是他具有宏替换的效果。
概念:以inline关键字修饰的函数叫做内联函数。
编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数可以提升程序的运行效率。
注意:想要看到内联函数的过程,不能在debug下进行,在release下可以看到函数替换调用的过程。因为在debug模式下编译器不会对代码进行优化。
缺点:inline 是以空间换时间的做法,所以inline就不适合代码很长或者有很多循环或者递归的函数。
inline对于编译器只是一种建议,编译器会自动优化。
inline不建议声明与定义分开写,可能会报错,分开会导致链接错误。
auto只是一个展位符,编译器在编译代码阶段,会根据变量的初始化表达式来推演变量的初始化表达类型。
auto不需要给变量类型,可以不指定。
注意:
auto定义的变量必需要初始化,因为编译器要根据初始化表达式的类型来替换auto。
int main() {
auto a = 10;
auto b = 1.234;
cout << typeid(a).name() << endl;//输出a的类型
cout << typeid(b).name() << endl;
return 0;
}
1,auto用指针的时候可以不带*,但是引用的时候需要带上&。
2,当auto在同一行定义多个变量的时候,需要定义相同的类型,要不然编译器会报错。
1,auto不能作为函数的参数
void A(auto b)//此时不容许
{}
2,auto不能用来声明数组
void A()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};
}
3,范围for循环
int main() {
int arr[] = { 1,2,3,4,5 };
//for循环的括号由“ :”分为俩部分,第一部分是范围内用于迭代的变量,第二部分则表示迭代的范围
for (auto e : arr)
cout << e << " ";
cout << endl;
return 0;
}
错误示例:
// 编译报错---int*的范围是不具体的--编译器编译阶段无法确认p所表示的类型
int* p = arr;
for (auto e : p)
cout << e << " ";
cout << endl;
for的 另一种用法:
int main() {
int arr[] = { 1,2,3,4,5 };
//不加&那么e就是arr数组中每一个元素的一份拷贝
for (auto e : arr)
e *= 2;
cout << endl;
for (auto e : arr)
cout << e << " ";
//e就是arr数组中每一个元素的别名
for (auto& e : arr)
e *= 2;
cout << endl;
for (auto e : arr)
cout << e << " ";
return 0;
}
NULL是一个宏
nullptr_t是一个类型
注意: