🍬个人主页:Yanni.—
🌈数据结构:Data Structure.
🎂C语言笔记:C Language Notes
🏀OJ题分享: Topic Sharing
🌼C++详解:C++ in detail
前言:
在前面介绍了一些C++的基础知识,这次延续前一个文章,今天的内容非常重要,学好之后可以为后面的类与对象打下良好的基础,加深对C++的理解。
引用
引用的概念
void Textref()
{
int a = 0;
int& r = a;
printf("%p\n", &a);
printf("%p\n", &r);
}
下面是运行结果,可以发现地址是一模一样的,所以引用相当于给一个变量取了个名字,相当于一块空间有多个名字。
引用的特性
1.引用在定义时必须初始化。
2.一个变量可以有多个引用。(一个人可以有多个外号)
3.引用一旦引用一个实体,在不能引用其他实体。(一生只爱一个人)
void Textref()
{
int a = 10;//初始化
int& r = a;
int& m = r;
int& n = m;
printf("%p\n", &a);
printf("%p\n", &r);
printf("%p\n", &m);
printf("%p\n", &n);
}

引用的使用场景
1.做函数参数
void Add(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
当我们要传地址调用时,C语言中使用指针来接收实参,在通过解引用进而改变实参的值,而通过引用可以直接改变实参的值,更加的简洁方便,提高了效率。
2.做返回值
int count(int a, int b)
{
int c = a + b;
return c;
}
int& Count(int a, int b)
{
int c = a + b;
return c;
}
用int做返回值的时候,函数调用栈帧,结束时会销毁栈帧,在返回值的时候会生成临时变量储存c的值,然后再通过拷贝的形式给到其他地方。
用引用做返回值时,如果是局部变量创建再栈帧中,最终这个局部变量的空间会被回收,那么返回对象就找不到了,这样可能会发生越界访问,正确的做法应该是再类型前+static,变为静态变量,这样栈帧回收空间时则不会影响到返回对象。
int& Count(int a, int b)
{
static int c = a + b;
return c;
}
引用与指针的区别
int main()
{
int a = 10;
int& ra = a;
cout << "&a = " << &a << endl;
cout << "&a = " << &ra << endl;
return 0;
}
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
如下图,看下引用和指针的汇编代码的对比,可以发现,两者底层的实现是相似的。
引用和指针的不同点:
内联函数
内联函数的概念

内联函数的特性
int add(int x, int y)
{
return x + y;
}
int main()
{
for (int i = 0; i < 10000; i++)
{
add(1, 2);
}
return 0;
}
没学习内联函数之前,我们可以用宏再解决函数栈帧调用过多的问题。
#define add(x,y) return ((x)+(y))
不过宏有很多缺点:
1.不方便调试。
2.代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查。
所以遇到短小且频繁调用的函数,适合用内联函数来解决,比如上面的函数要调用函数栈帧10000次,我们只要再函数前+inline,这样就可以大大增加程序的效率。
inline int add(int x, int y)
{
return x + y;
}
int main()
{
for (int i = 0; i < 10000; i++)
{
add(1, 2);
}
return 0;
}
auto关键字(C++11)
#include <string>
#include <map>
int main()
{
std::map<std::string, std::string> m{ { "apple", "苹果" }, { "orange",
"橙子" },
{"pear","梨"} };
std::map<std::string, std::string>::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0; }
int TestAuto()
{
return 10; }
int main()
{
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0; }
C++中的指针空值nullptr
void f(int)
{
cout<<"f(int)"<<endl;
}
void f(int*)
{
cout<<"f(int*)"<<endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);
return 0;
}
在C++98之后,NULL经常被当作0来处理,而非指针空值,所以在之后的学习中用nullptr在表示指针空值。
好啦,这就是今天学习的分享啦!看到希望大家的三连呀!
如果有不当之处,欢迎大佬指正!