C++入门

本文介绍了C++中的命名空间,解释了如何避免命名冲突以及全展开和部分展开的使用。接着讨论了函数重载的概念和为何C++支持它,以及缺省参数的规则。此外,还详细讲解了引用的特性,包括作为传参和返回值的效率优势。内联函数和宏的区别也被提及,最后提到了C++11的新特性,如auto关键字和基于范围的for循环。
摘要由CSDN通过智能技术生成

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:那个传说中的man的主页
🏠个人专栏:题目解析
🌎推荐文章:题目大解析2

在这里插入图片描述


👉🏻命名空间

命名空间概念
命名空间可以被看作是一个包含了一组相关实体的容器。通过将实体放置在命名空间中,可以将它们与其他代码隔离开来,避免命名冲突。

语法就是:

namespace 空间名
{ }

在空间里面,我们也还可以创建这些👇🏻

  • 变量
  • 数组
  • 结构体
  • 函数
  • 嵌套空间

引用空间⭐️

以上是我们自己创建空间,而我们平常还会引用已经写好的空间。
而这里又分为两种形式

  1. 全部展开
    示例如下👇🏻
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++中的两个不同的概念。

命名空间是一种用于组织代码的机制,它可以将相关的函数、类、变量等放置在一个逻辑上的容器中,以避免命名冲突。通过使用命名空间,我们可以将代码模块化,并且可以在不同的命名空间中定义相同名称的实体而不会发生冲突

头文件是一种用于包含代码的文件,通常包含函数、类、变量的声明和定义。头文件通常用于在多个源文件中共享代码,以避免重复编写相同的代码。通过包含头文件,我们可以在源文件中使用头文件中定义的实体,而无需重新编写它们的声明和定义。

因此,命名空间用于组织代码,避免命名冲突,而头文件用于共享代码和声明实体。

👉🏻 输入输出

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
    以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型

在这里插入图片描述

👉🏻 缺省参数

缺省参数概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
给的实参数目要和缺省数目一样

  • 全缺省参数
    即函数参数中都有给缺省值
void Func(int a = 10, int b = 20, int c = 30)
 {
    
 }
  • 部分缺省参数
void Func(int a , int b = 20, int c = 30)
 {
    
 }

部分缺省参数需要注意

  1. 半缺省参数必须从右往左依次来给出,也不能间隔着给
    错误案例👇🏻
void Func(int a = 10, int b , int c = 30)
 {
    
 }
  1. 缺省参数不能在函数声明和定义中同时出现,且缺省参数只能在声明中给
    为什么呢?首先因为声明是我们能看的见的,我们在声明中给了缺省值,但定义中不给,就是怕定义中的缺省值和声明不一样,这就很矛盾了,所以为了避免这种矛盾问题,缺省值就只在声明中给。
  2. 缺省值必须是常量或者全局变量
  3. C语言不支持(编译器不支持)

👉🏻函数重载

概念
是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同
函数重载的好处是可以提高代码的可读性和灵活性。通过使用相同的函数名,我们可以根据不同的参数类型来执行不同的操作,而不需要为每种操作定义一个新的函数名。

重载的定义是方法名相同、参数类型不同,满足此条件即可,对返回值没有规定
参数类型相同则不能称为重载,所以参数类型相同、但返回值不同的重载是不合法的

但是函数重载可能会出现调用歧义的问题。如下👇🏻

#include<iostream>
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语言:编译之后,函数名字的修饰不会发生改变
  • 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;
}

在这里插入图片描述
🤔什么情况是放大权限?

如果原变量不允许被改变,则任何可能可以改变原变量的引用都是放大权限。一般原变量也是引用就是可以被允许改变。

  • 一个变量可以有多个别名
  • 引用一旦引用了一个实体,就不能再引用其它的实体,用C语言的话说,就是这个引用的地址从此和所引用的实体绑定(相同),不会再发生变化了,从一而终。
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++有哪些技术替代宏?

  1. 常量定义 换用const enum
  2. 短小函数定义 换用内联函数

👉🏻auto关键字

概念
用auto修饰的变量会自动匹配对应的类型。

int a = 0;
auto b = a;

此时auto会自动匹配,b的类型为int
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

auto使用注意点

  • 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
  • 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto()
{
    auto a = 1, b = 2; 
    auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

auto不能应用的场景

1.auto不能用作函数参数,因为编译器无法对函数参数的原类型进行推导
2.auto不能用作声明数组

👉🏻基于范围的for循环(C++11)

基于范围的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(C++11)

nullptr既代表0也是((void*)0)

👉🏻getline函数

在C++的string库中,getline()函数是用于从输入流中读取一行文本的函数。

getline()函数的基本语法如下:

getline(istream& input, string& str, char delimiter='\n');

其中,参数说明如下:

  • input:输入流对象,表示从哪个输入流中读取数据。可以是cin、文件流对象等。
  • str:字符串对象,用于存储读取到的文本行。
  • delimiter(可选):字符型参数,表示行的结束符,默认为换行符 \n

使用getline()函数的示例代码如下:

#include <iostream>
#include <string>

int main() {
    std::string line;
    
    // 从标准输入中读取一行文本
    std::cout << "请输入一行文本:";
    std::getline(std::cin, line);
    std::cout << "你输入的文本是:" << line << std::endl;
    
    return 0;
}

运行以上示例代码时,程序会等待用户在终端输入一行文本,用户按下回车键后,getline()函数会将输入的文本存储到line字符串中,并输出到终端上。

需要注意的是,getline()函数会读取一行文本,包括行末的换行符(如果有的话),但不会将换行符保存到字符串中。如果不指定delimiter参数,默认的行结束符是换行符\n,但也可以通过指定其他字符作为结束符来读取特定格式的文本行。


如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值