当前位置: 首页 > news >正文

C++语法学习之路

C++语法学习之路

​ C++ 是在 C 的基础之上,容纳进了面向对象编程思想,并增加了许多有用的库,以及编程范式等。前期的 C++ 主要是在补充 C 语言的不足,以及对 C 设计不合理的地方进行优化。

一、关键字

C++ 有63个关键字,C 语言只有32个关键字。C++ 在 C 语言的基础之上增加了更多的关键字。

关于这些新增的关键字,我们不需要一下子就去全部搞懂。在学和用的过程中,我们慢慢就会熟能生巧了。

auto 关键字

auto 类型,能根据右边的表达式自动推导表达式的类型。在类型名比较长的时候有很大的作用。

int a = 1;
auto b = a;
auto c = a + 1.1;

NULL 与 nullptr

// C语言
#define NULL 0
// C++
#define nullptr ((void*)0)

二、命名空间 namespace

命名空间主要解决命名冲突的问题。命名冲突可能会是我们写的变量函数和调用的库冲突了,也可能是和同事的变量函数命名冲突了,导致编译不通过。

​ 如果是使用 C 语言,我们只能去修改冲突的变量函数名。C++ 加入了命名空间以后就解决了这个问题。

命名空间增加了命名空间域的概念,其他域还有类域(class)局部域全局域。同时还加入了 :: (域作用限定符)。变量和函数只会在自己的域内发挥作用,通过 :: 在其他域中引用需要的域变量函数。

// 全局域
int a = 0;

// 命名空间域A
namespace A
{
	int a = 2;
} // 不能给分号

int main()
{
	// 局部域
	int a = 1;
	// ::的前面是跟的域名,后面则是变量函数名
	// 空代表的是全局域
	printf("%d\n", a);
	printf("%d\n", ::a);
	printf("%d\n", A::a);
	return 0;
}
# cmd 命令输出
1
0
2

​ 使用 using namespace 展开命名空间域后,就会把命名空间域里的代码暴露到其他域。这时全局域下的变量 a 和**命名空间域 A **下的变量 a 会冲突。

​ 所以我们一般不要直接把命名空间域展开,这会出现许多问题。而是通过域作用限定符 :: 去调用命名空间域中的变量函数。

int a = 0;
namespace A
{
    int a = 1;
}
// 解注下面代码,此时爆红 "a" 不明确
// using namespace A

int main() {
    std::cout << a << std::endl;
    std::cout << A::a << std::endl;
    return 0;
}

命名空间嵌套

命名空间域是可以嵌套的。调用嵌套命名空间里的变量函数需要先从外层开始调用。

namespace A
{
	int a = 2;
	namespace B
	{
		int a = 2;
	}
}// 不能给分号
printf("%d\n", A::B::a);

命名空间合并

多个同名的命名空间会被合并属于同一个命名空间,不能有同名变量函数。

namespace A
{
	int a = 2;
}

namespace A
{
	int b = 1;
}

C++标准库和命名空间的关系

​ 传统的 C 语言标准库都是以 .h 结尾的头文件( #include <stdio.h> )。在 C++ 早期,C++ 的标准库也是以 .h 结尾的。但是在加入命名空间以后 C++ 的标准库不再使用 .h 结尾,并且把标准库里的东西全部加入到了一个命名空间中,名为 std

// C 头文件
#include <stdio.h>
// C++ 早期头文件
#include <iostream.h>
// C++ 头文件
#include <iostream>
using namespace std;

C++ 标准库中写的代码都是放在一个同名为 std 的命名空间域中的。

#include <iostream>
namespace std
{
   
	// iostream库的代码
}
#include <list>
namespace std
{
   
	// list库的代码
}
#include <vector>
namespace std
{
   
	// vector库的代码
}

所以如果你想使用 C++ 的标准库,你不但要去包含头文件还需要在使用的地方限定标准库的命名空间 std

#include <iostream>
int a = 1;
std::cout << a << std::endl;

// 展开常用的std元素
using std::cout;
using std::endl;
cout << a << endl;

三、C++ 的输入输出

C++ 的输入输出使用了IO流。cplusplus.com/reference 这是 C++ 标准库的文档,里面包含了IO流的介绍。

使用 cout 标准输出对象(控制台)和 cin 标准输入对象 (键盘) 时,必须包含 <iostream> 头文件并在使用的地方展开 std<<流插入运算符>>流提取运算符

#include <iostream>
using namespace std;
int a = 2024;
int main()
{
   
	cout << "Hello Word!" << " " << a << endl;
	int b = 0;
	cin >> b;
	cout << "Hello Word!" << " " << b << endl;
	return 0;
}
# cmd 命令输出
Hello Word! 2024
2023
Hello Word! 2023

​ 可以看到,C++ 的输入输出并没有指定变量类型,这是 C++ 的两个新特性叫 函数重载运算符重载 来实现的,可以达到自动识别类型的效果。

​ 还值得一提的是,C语言的输入输出 ( printfscanf ) 通常比 C++ 的输入输出要快。这主要是因为 C++ 兼容 C 语言,C++ 在去缓冲区输入输出信息时会先检测有没有 C 语言的东西,如果有会先清空缓冲区再去输入输出信息。当然你也可以去把 C++ 的这个缓冲区检测取消掉,这个时候 C++ 的输入输出速度就提上来了。

四、缺省参数

​ C++ 支持缺省参数,在写缺省参数的时候需要严格按照语法来写。如果不是全缺省,缺省参数一定是在函数参数的右边的。因为我们调用函数时,函数形参会从左往右依次取值,如果第一个是缺省参数而第二个不是缺省参数,我又只传了一个参数该怎么办呢?

​ 这时,因为 C++ 语法不支持这样做,所以这个函数参数写法是错误的。

#include <iostream>
using namespace std;
// 错误写法
void Function(int a = 1, int b, int c = 3)
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}

// 正确写法
void Function(int a, int b = 2, int c = 3)
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}
int main()
{
	Function(4);
	return 0;
}

缺省参数不能在函数定义函数声明中同时给,只能在函数声明中给出。不然会出现语法错误,编译器不知道该用哪一个。

// 函数声明
void Function(int a = 1, int b = 2, int c = 3);
int main()
{
	Function(4);
	return 0;
}
// 函数定义
void Function(int a, int b, int c)
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}

五、函数重载

​ C++ 支持函数重载函数重载是指函数名相同,但是参数类型不同。参数类型不同分为参数个数不同、类型不同、类型顺序不同。只要符合其中任意一个条件就符合函数重载

​ 值得一提的是返回值不同并不能构成函数重载

函数重载的调用歧义

​ 注意看,下面这两个函数是否满足函数重载。答案是满足,但是这两个函数在调用的时候会出现问题,如果调用这个函数的时候没有加参数那么是调用的哪一个函数呐?编译器也不知道,所以会报错函数调用出现歧义。

void Function()
{
	cout <<
http://www.dtcms.com/a/122371.html

相关文章:

  • Mac监控新风尚:酷炫界面,性能监控更直观!
  • 数字图像处理作业4
  • SQLite 中日期型数据定义及处理(Delphi 版本)
  • IDEA :物联网ThingsBoard-gateway配置,运行Python版本,连接thingsboard,接入 MQTT 设备
  • [ACM_1] 输入输出 | 多行 | 多组 | getline(cin,s) | cin处理
  • 【MySQL】——事务的隔离性
  • Dubbo的简单介绍
  • 数据分析-Excel-学习笔记Day1
  • LeetCode Hot100 刷题笔记(2)—— 子串、普通数组、矩阵
  • Ubuntu22.04——YOLOv8模型训练到RK3588设备部署和推理
  • 实现抗隐私泄漏的AI人工智能推理
  • Linux进程控制:fork、exit与waitpid的江湖恩怨
  • C# 根据指定路径、文件格式、创建日期清理文件夹内文件,包括子目录
  • 从Transformer到世界模型:AGI核心架构演进
  • 微信小程序 -- 原生封装table
  • UV安装与使用
  • asp.net core 项目发布到 IIS 服务器
  • 场外期权只适合上涨行情吗?
  • CSS语言的游戏AI
  • ResNet改进(18):添加 CPCA通道先验卷积注意力机制
  • 从个人博客到电商中台:EdgeOne Pages的MCP Server弹性架构×DeepSeek多场景模板实战解析
  • 1.VTK 使用CMakeLists
  • Linux 编程中的 I/O 复用
  • Element UI 设置 el-table-column 宽度 width 为百分比无效
  • React九案例中
  • 敏捷迭代实战经验分享
  • leetcode_数组 189. 轮转数组
  • Odrive0.5.1-FOC电机控制 arm_cos_f32.cpp arm_sin_f32.cpp代码实现(一)
  • 中科岩创基坑自动化监测解决方案
  • 【11】数据结构之基于线性表的查找算法