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

【C++】踏上C++学习之旅(一):初识C++和命名空间

动图

文章目录

  • 前言
  • 1. 初识C++
  • 2. C++的发展阶段
  • 2. 命名空间
    • 2.1 为什么要有命名空间?
    • 2.2 命名空间的语法
    • 2.3 命名空间的原理
    • 2.4 使用命名空间的三种方式
      • 2.4.1 加命名空间名称及作用域限定符( :: )
      • 2.4.2 使用using关键字将命名空间中某个成员 引入
      • 2.4.3 使用using namespace 命名空间名 引入
  • 3. 简单了解C++的输入和输出

前言

本文是正式踏上C++学习之旅的第一篇文章,也是我分享C++笔记的第一篇文章。在这篇文章中,我会给大家介绍C++的发展历史,让大家更好从C语言过渡到C++,也会让大家认识到为什么C++能够兼容C语言的语法。

光是讲解C++的历史那可就太无趣了,所以在本文中我还会给大家加一点料 —— “命名空间”,以及如何高效的使用C++中命名空间。

还会教大家如何用C++的方式,输出"Hello World"。

哈哈哈

1. 初识C++

C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机界提出了OOP(objectoriented programming:面向对象)思想,支持面向对象的程序设计语言应运而生。所以我们经常说到C++是面向对象的语言,而C语言是面向过程的语言。

1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

请大家记住C++诞生的时间(1982年)以及发明C++的大佬 —— “本贾尼”!

2. C++的发展阶段

作为了解就好,但是也要知道我们现在是在用C++版本是多少。

阶段内容
C with classes类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符重载等
C++1.0添加虚函数概念,函数和运算符重载,引用、常量等
C++2.0更加完善支持面向对象,新增保护成员、多重继承、对象的初始化、抽象类、静态成员以及const成员函数
C++3.0进一步完善,引入模板,解决多重继承产生的二义性问题和相应构造和析构的处理
C++98C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写C++标准库,引入了STL(标准模板库)
C++03C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性
C++05C++标准委员会发布了一份计数报告(Technical Report,TR1),正式更名C++0x,即:计划在本世纪第一个10年的某个时间发布
C++11增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等
C++14对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式,auto的返回值类型推导,二进制字面常量等
C++17在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文本信息可选,Fold表达式用于可变的模板,if和switch语句中的初始化器等
C++20自C++11以来最大的发行版,引入了许多新的特性,比如:模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有特性的更新:比如Lambda支持模板、范围for支持初始化等
C++23明确的对象参数(Deducing this)、if consteval、多维下标运算符、内建衰减复制支持、标记不可达代码(std::unreachable)、平台无关的假设([[assume]])、命名通用字符转义、扩展基于范围的 for 循环中临时变量的生命周期、constexpr 增强、简化的隐式移动、静态运算符 static operator[] 以及类模板参数推导

C++还在不断地向后发展。但是现在公司主流的是用的还是C++98和C++11,等大家以后工作时可以慢慢钻研C++的新特性,现在这需要我们熟练的掌握C++98和C++11这两个标准即可。

我们现在学习阶段大都接触到的也就是这两种标准(C++11和C++98)。

哈哈哈

2. 命名空间

2.1 为什么要有命名空间?

请大家看一下下面的代码:

#include<stdio.h>int rand = 0;
int main()
{int rand = 10;printf("%d\n",rand);return 0;
}

上面的代码会不会报错?相信掌握C语言语法的读者就会说,上面的代码是可以正常编译通过的。没错,上面的代码的确是没有任何问题的。

那如果我将上述的代码做了一点改变,代码还能正常编译过去吗?

#include<stdio.h>
#include<stdlib.h>
int rand = 0;
int main()
{int rand = 10;printf("%d\n",rand);return 0;
}

如果你们自己去测试的话,显然会出现编译错误。
编译错误

这是什么原因呢?
编译器说rand重定义,而且错误是我们在引用stdlib.h的头文件之后才出现的。到这里我们就意识到了有个rand的变量名或者时函数名,而我们知道一个.c/.cpp的源文件在编译阶段的预处理阶段会把头文件的内容给展开,所以就会出现rand重定义了。

这个问题在C语言上只能是要你改变这个变量名了。C++就能够解决这个问题,即使你不更改变量名,编译器也不会报错,这个C++的利器就是命名空间

为了让大家对命名空间的这个新事物引起更高的重视,我来给大家举个生活中实际例子:

比如现在有一个互联网公司,这个公司最近准备研发一个项目,老板就把项目就分配给了一个小组,而小组里面有两人小明和小刚负责分别负责这个项目的两个模块。他们两个写啊写啊,终于有一天他们俩将各自写的项目都提交了上去,编译一下却出现错误,经过检查发现他们两个项目的变量名有很多是重叠了,这个会出现命名冲突的问题。如果他们是用C语言来写的话,那必定有一方得是改变变量命名,那两个人肯定都不愿意改的。如果用C++的命名空间的话,就可以完美避开这个问题了。

好了,在讲完命名空间的重要性之后,我们就得认识一下命名空间的用法以及底层的原理!

2.2 命名空间的语法

namespace 命名空间名
{内容
}

下面我来一遍做展示,一遍拓展:

  1. 这个是我们进行正常的命名空间定义:
namespace test
{int rand = 10;int Add(int x, int y){return x+y;}struct Node{int data;struct Node* next;}
}

🍉我们不仅可以在命名空间定义并初始化变量,还可以进行对函数的定义,结构体的定义等。

  1. 命名空间可以嵌套:
namespace N1
{int a;int b;int Add(int left, int right){return left + right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}

🍉可以看到我们中命名空间去嵌套另一个命名空间。

  1. 同一个工程中允许不同的文件出现名称相同的命名空间,但是最后编译器会将不同文件相同名称的命名空间给合并到一起:
//这个是test.h文件里面的命名空间
namespace N1
{int Mul(int left, int right){return left * right;}
}//这个是test.cpp文件里面的命名空间
namespace N1
{int a;int b;int Add(int left, int right){return left + right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}

经过编译器的编译之后,最后的合并的结果就是:

namespace N1
{int Mul(int left, int right){return left * right;}int a;int b;int Add(int left, int right){return left + right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}

2.3 命名空间的原理

提到命名空间,我们就不得不提另一个概念"域"。

想必大家或多或少都会在C语言中听过"作用域"(全局域、局部域)这个名词。这个就是"域"中的一种,在C++中还有命名空间域、类域等等。而我们现在说讲的命名空间,它的实质就是一种命名空间域。

那可能有的读者会问,"域"是个什么东西?
那我们可以先从我们熟悉的入手,全局域和局部域。我们都知道在给全局变量和局部变量去相同的变量名时,程序是不会报错的,这个就是"域"的作用。我们可以把"域"想象成一面墙,被这面的墙隔开的事物互不干扰,你干你的事,我刚我的事。
讲到这里,我相信你已经对命名空间域已经有感觉了。我们也可以把命名空间域看作是一面墙,将局部域与全局域给隔开了。在这个域里面有自己独自维护的变量。

🍉所以我们可以总结一下:命名空间是解决全局变量与头文件的命名冲突问题,或者是解决同一个工程项目中不同模块之间的命名冲突问题。

2.4 使用命名空间的三种方式

我们讲解了命名空间的原理,那命名空间里面的成员我们该怎么引用呢?比如:

namespace test
{// 命名空间中可以定义变量/函数/类型int a = 0;int b = 1;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}
int main()
{// 编译报错:error C2065: “a”: 未声明的标识符printf("%d\n", a);return 0;
}

2.4.1 加命名空间名称及作用域限定符( :: )

int main()
{printf("%d\n", test::a);return 0;
}

2.4.2 使用using关键字将命名空间中某个成员 引入

using  test::b;
int main()
{printf("%d\n", test::a);printf("%d\n", b);return 0;
}

这种方式建议使用!!!

2.4.3 使用using namespace 命名空间名 引入

using  namespace test;
int main()
{printf("%d\n", test::a);printf("%d\n", b);Add(10,20);return 0;
}

🍉注意:使用这个方法时是有风险的(这个命名空间里面有着和全局变量一样的变量名),所以我们在平时进行练习或比赛的时候使用即可。


3. 简单了解C++的输入和输出

我们再学一门新的语言时,往往会都会干一件事,就是在屏幕上输出"Hello World"。
所以这里我们就简单认识一下C++的输入和输出。

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{cout<<"Hello world!!!"<<endl;return 0;
}

说明:
1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出他们都包含在包含< iostream >头文件中。
3. <<是流插入运算符,>>是流提取运算符。
4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
C++的输入输出可以自动识别变量类型。
5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应
头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,
规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因
此推荐使用+std的方式。

#include <iostream>
using namespace std;
int main()
{int a = 10;double b = 3.1415;char c = 'l';// 可以自动识别变量的类型cin>>a;cin>>b>>c;cout<<a<<endl;cout<<b<<" "<<c<<endl;return 0;
}

🍉最后在声明一点,std命名空间的使用惯例:
std是C++标准库的命名空间,如何展开std使用更合理呢?

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
  2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。

到这里本文就结束了,如果觉得文章写得还不错的话,麻烦给偶点个赞吧!!!

hahaha

相关文章:

【C++】踏上C++学习之旅(一):初识C++和命名空间

文章目录 前言1. 初识C2. C的发展阶段2. 命名空间2.1 为什么要有命名空间&#xff1f;2.2 命名空间的语法2.3 命名空间的原理2.4 使用命名空间的三种方式2.4.1 加命名空间名称及作用域限定符( :: )2.4.2 使用using关键字将命名空间中某个成员 引入2.4.3 使用using namespace 命…...

tensorflow入门案例手写数字识别人工智能界的helloworld项目落地1

参考 https://tensorflow.google.cn/?hlzh-cn https://tensorflow.google.cn/tutorials/keras/classification?hlzh-cn 项目资源 https://download.csdn.net/download/AnalogElectronic/89872174 文章目录 一、案例学习1、导入测试和训练数据集&#xff0c;定义模型&#xff…...

深度学习——线性神经网络(三、线性回归的简洁实现)

目录 3.1 生成数据集3.2 读取数据集3.3 定义模型3.4 初始化模型参数3.5 定义损失函数3.6 定义优化算法3.7 训练 在上一节中&#xff0c;我们通过张量来自定义式地进行数据存储和线性代数运算&#xff0c;并通过自动微分来计算梯度。实际上&#xff0c;由于数据迭代器、损失函数…...

本地部署 Milvus

本地部署 Milvus 1. Install Milvus in Docker2. Install Attu, an open-source GUI tool 1. Install Milvus in Docker curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.shbash standalone_embed.sh …...

Git基础-配置http链接的免密登录

问题描述 当我们在使用 git pull 或者 git push 进行代码拉取或代码提交时&#xff0c; 若我们的远程代码仓库是 http协议的链接时&#xff0c;就是就会提示我们进行账号密码的登录。 每次都要登录&#xff0c;这未免有些麻烦。 本文介绍一下免密登录的配置。解决方案 1 执行…...

华为OD机试真题-编码能力提升-2024年OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,持续跟新。 题目描述 为了提升软件编码能力,小…...

高被引算法GOA优化VMD,结合Transformer-SVM的轴承诊断,保姆级教程!

本期采用2023年瞪羚优化算法优化VMD&#xff0c;并结合Transformer-SVM实现轴承诊断&#xff0c;算是一个小创新方法了。需要水论文的童鞋尽快&#xff01; 瞪羚优化算法之前推荐过&#xff0c;该成果于2023年发表在计算机领域三区SCI期刊“Neural Computing and Applications”…...

半小时速通RHCSA

1-7章: #01创建以上目录和文件结构&#xff0c;并将/yasuo目录拷贝4份到/目录下 #02查看系统合法shell #03查看系统发行版版本 #04查看系统内核版本 #05临时修改主机名 #06查看系统指令的查找路径 #07查看passwd指令的执行路径 #08为/yasuo/ssh_config文件在/mulu目录下创建软链…...

人工智能和机器学习之线性代数(一)

人工智能和机器学习之线性代数&#xff08;一&#xff09; 人工智能和机器学习之线性代数一将介绍向量和矩阵的基础知识以及开源的机器学习框架PyTorch。 文章目录 人工智能和机器学习之线性代数&#xff08;一&#xff09;基本定义标量&#xff08;Scalar&#xff09;向量&a…...

STM32外设应用详解

STM32外设应用详解 STM32微控制器是意法半导体&#xff08;STMicroelectronics&#xff09;推出的一系列基于ARM Cortex-M内核的高性能、低功耗32位微控制器。它们拥有丰富的外设接口和功能模块&#xff0c;可以满足各种嵌入式应用需求。本文将详细介绍STM32的外设及其应用&am…...

docker详解介绍+基础操作 (三)优化配置

1.docker 存储引擎 Overlay&#xff1a; 一种Union FS文件系统&#xff0c;Linux 内核3.18后支持 Overlay2&#xff1a;Overlay的升级版&#xff0c;docker的默认存储引擎&#xff0c;需要磁盘分区支持d-type功能&#xff0c;因此需要系统磁盘的额外支持。 关于 d-type 传送…...

细说Qt的状态机框架及其用法

文章目录 使用场景基本用法状态定义添加转换历史状态QStateMachine是Qt框架中用于构建状态机的一个类,它属于Qt的状态机框架(State Machine Framework)。这个框架提供了一种模型,用于设计响应不同事件(如用户输入、文件I/O或网络活动)的应用程序的行为。通过使用状态机,开发…...

Oracle-表空间与数据文件操作

目录 1、表空间创建 2、表空间修改 3、数据文件可用性切换操作 4、数据文件和表空间删除 1、表空间创建 &#xff08;1&#xff09;为 ORCL 数据库创建一个名为 BOOKTBS1 的永久表空间&#xff0c;数据文件为d:\bt01.dbf &#xff0c;大小为100M&#xff0c;区采用自动扩展…...

C# WinForm实现画笔签名及解决MemoryBmp格式问题

目录 需求 实现效果 开发运行环境 设计实现 界面布局 初始化 画笔绘图 清空画布 导出位图数据 小结 需求 我的文章 《C# 结合JavaScript实现手写板签名并上传到服务器》主要介绍了 web 版的需求实现&#xff0c;本文应项目需求介绍如何通过 C# WinForm 通过画布画笔…...

GC1272替代APX9172/茂达中可应用于电脑散热风扇应用分析

在电脑散热风扇应用中&#xff0c;选择合适的驱动器件对于风扇的性能和效率至关重要。以下是对GC1272替代APX9172/茂达在此类应用中的分析&#xff1a; 1. 功能比较 GC1272&#xff1a; 主要用于驱动直流风扇&#xff0c;具有高效的电流控制和调速功能。支持PWM调速&#xff0…...

《Linux从小白到高手》综合应用篇:详解Linux系统调优之服务器硬件优化

List item 本篇介绍Linux服务器硬件调优。硬件调优主要包括CPU、内存、磁盘、网络等关键硬件组。 1. CPU优化 选择适合的CPU&#xff1a; –根据应用需求选择多核、高频的CPU&#xff0c;以满足高并发和计算密集型任务的需求。CPU缓存优化&#xff1a; –确保CPU缓存&#x…...

PHP政务招商系统——高效连接共筑发展蓝图

政务招商系统——高效连接&#xff0c;共筑发展蓝图 &#x1f3db;️ 一、政务招商系统&#xff1a;开启智慧招商新篇章 在当今经济全球化的背景下&#xff0c;政务招商成为了推动地方经济发展的重要引擎。而政务招商系统的出现&#xff0c;更是为这一进程注入了新的活力。它…...

Linux 命令行

这学期是我第一次正式学习 linux &#xff0c;是在 VMware 里创建了 openEuler 的虚拟机练习 linux 的常用命令。 目前主要在学习 linux 的常用命令&#xff0c;因此这篇博客主要介绍一些常用的命令。 本文将持续更新… 阅读建议 Linux 是一个倒置的树结构&#xff08;文件系…...

每日一题:单例模式

每日一题&#xff1a;单例模式 ❝ 单例模式是确保一个类只有一个实例&#xff0c;并提供一个全局访问点 1.饿汉式&#xff08;静态常量&#xff09; 特点&#xff1a;在类加载时就创建了实例。优点&#xff1a;简单易懂&#xff0c;线程安全。缺点&#xff1a;无论是否使用&…...

前端_001_html扫盲

文章目录 概念标签及属性常用全局属性head里常用标签body里常用标签表情符号 url编码 概念 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body></bod…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...