欢迎来到Cefler的博客
博客主页:那个传说中的man的主页
个人专栏:题目解析
推荐文章:题目大解析2
命名空间概念
命名空间可以被看作是一个包含了一组相关实体的容器。通过将实体放置在命名空间中,可以将它们与其他代码隔离开来,避免命名冲突。
其语法就是:
namespace 空间名
{ }
在空间里面,我们也还可以创建这些
引用空间⭐️
以上是我们自己创建空间,而我们平常还会引用已经写好的空间。
而这里又分为两种形式
namespace class1
{
int a = 1;
int b = 2;
}
using namespace class1;
int main()
{
cout << a << endl;
cout << b << endl;
return 0;
}
上述代码里我创建了一个命名空间,并且对其全部展开,而后能顺利打印空间中的变量a,b。
2.部分展开
示例如下
namespace class1
{
int a = 1;
int b = 2;
}
using class1::a;
这里我们用作用域限定符: :去展开空间中的部分变量a,此时b就无法被访问到了,而且部分展开时,是不用在using 后面加上namespace的。
那如果我只部分展开了部分变量,我还想访问其中的其它变量怎么办?
我们仍然可以用作用域限定符: :去针对性的访问空间中的某个变量,比如我想打印b
cout << class1::b << endl;
命名空间和头文件有什么区别?
命名空间和头文件是C++中的两个不同的概念。
命名空间是一种用于组织代码的机制,它可以将相关的函数、类、变量等放置在一个逻辑上的容器中,以避免命名冲突。通过使用命名空间,我们可以将代码模块化,并且可以在不同的命名空间中定义相同名称的实体而不会发生冲突。
头文件是一种用于包含代码的文件,通常包含函数、类、变量的声明和定义。头文件通常用于在多个源文件中共享代码,以避免重复编写相同的代码。通过包含头文件,我们可以在源文件中使用头文件中定义的实体,而无需重新编写它们的声明和定义。
因此,命名空间用于组织代码,避免命名冲突,而头文件用于共享代码和声明实体。
缺省参数概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
给的实参数目要和缺省数目一样
void Func(int a = 10, int b = 20, int c = 30)
{
}
void Func(int a , int b = 20, int c = 30)
{
}
部分缺省参数需要注意
void Func(int a = 10, int b , int c = 30)
{
}
概念
是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同
函数重载的好处是可以提高代码的可读性和灵活性。通过使用相同的函数名,我们可以根据不同的参数类型来执行不同的操作,而不需要为每种操作定义一个新的函数名。
重载的定义是方法名相同、参数类型不同,满足此条件即可,对返回值没有规定。
参数类型相同则不能称为重载,所以参数类型相同、但返回值不同的重载是不合法的。
但是函数重载可能会出现调用歧义的问题。如下
#include
using namespace std;
void func(int a)
{
cout << a << endl;
}
void func(int a,int b = 10)
{
cout << a + b << endl;
}
int main()
{
func(4);
return 0;
}
我们学过,一个程序的运行要进行四个步骤:预处理,编译,汇编,链接
汇编过程就是将汇编代码转换为二进制,并且形成符号表,为的就是后面函数调用时可以根据函数名找到函数。
但是c和c++有不同的函数名修饰规则
通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修
饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载
引用概念
引用的实质并不是创建一个新的变量,引用是给一个已经存在的变量取的一个别名,这个别名可以代表这个变量。
引用使用注意要点:
int main()
{
const int a = 0;
const int& a1 = a;//权限的平移
int b = 0;
const int& b1 = b;//权限的缩小
const int c = 0;
int& c1 = c;//权限的放大
return 0;
}
如果原变量不允许被改变,则任何可能可以改变原变量的引用都是放大权限。一般原变量也是引用就是可以被允许改变。
int main() {
int a = 1;
int& b = a;
int& c = b;
int& d = b;//可以引用多个别名
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;
}
1.传参
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
传参在任何情况下都可以使用
2.做返回值
int& Count()
{
static int n = 0;
n++;
// ...
return n;
}
做返回值使用情况:返回值在出作用域后仍存在不销毁
为什么呢?
我们上述知道,引用就是和原来的变量绑定在一起(相同地址),所以二者是属于同一本源的,一方改变,另一方也会发生变化,我们知道,函数结束进程后,该函数创建的栈帧就会销毁,里面所定义的变量自然也就不复存在了,这些变量就可能会变成随机值,而如果用引用返回,那么该引用值可能就会发生改变。
所以我们要规避这种风险情况。
结论:引用作为传参和返回值的效率高于值。
也好理解,传值操作只是实参的一份临时拷贝,它在创建栈帧的时候,还要专门创建临时变量,这无疑大大降低了效率。
概念
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
如果在函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。
在Debug模式下查看汇编情况
这里只展开了函数功能,并未调用函数创建新的栈帧空间。
1.内敛函数本质是以空间换时间
因为它是以函数体代替了函数调用,如果函数体本身大或者展开次数多的话,代码量就会非常大,会导致目标文件很大
2.内联说明只是对编译器的建议,是否采用取决于编译器
如果函数体过大,编译器会忽略内联声明,仍采用函数调用的方法。
所以我们一般只对调用频繁、函数体小、流程直接不递归的函数进行内联说明,以提高程序运行效率
3.inline不建议声明和定义分离,分离会导致链接错误
这里的声明和定义分离,是指声明和定义分别位于不同的.cpp文件当中。
因为内联函数调用是直接展开,没有地址,链接过程时,内联函数的地址并未进入符号表,找不到地址,自然会出现链接错误。
宏的优缺点?
优点:
1.增强代码的复用性。
2.提高性能。
缺点:
1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。
C++有哪些技术替代宏?
概念
用auto修饰的变量会自动匹配对应的类型。
int a = 0;
auto b = a;
此时auto会自动匹配,b的类型为int
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
1.auto不能用作函数参数,因为编译器无法对函数参数的原类型进行推导
2.auto不能用作声明数组
基于范围的for循环只要给出数组名,就会自动遍历数组。
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
for (auto x : arr)
{
cout << x << " ";
}
return 0;
}
注意:for循环迭代的范围必须是确定的
nullptr既代表0也是((void*)0)
如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注❤️ ,学海无涯苦作舟,愿与君一起共勉成长