【C++】初识C++

目录

  • 命名空间
    • 域的概念
    • 命名空间的概念
      • 示例1
      • 示例2
    • 命名空间的嵌套定义
    • 命名空间的访问
      • 指定命名空间访问
      • using访问命名空间
      • 对于嵌套命名空间的访问
  • 输入&输出
    • 输入
    • 输出
    • 输入输出的特性
    • 换行

命名空间

在C/C++中,变量、函数和类的定义很多,在某些方面我们难免要使用库文件中的对象,但在一个比较庞大的项目中我们人为的去创建对象这些难免有可能与我们库文件中对象名字相同而发生冲突。这时候为了解决这个冲突问题,我们C++就推出了命名空间。用namespace关键字来定义命名空间

下列我们看一个经典的对象名冲突的代码:

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

我们stdlib.h库文件中有一个rand()随机值函数,这个函数在预编译的时候就进行了头文件展开(把头文件中的内容拷贝过来),这时候我们定义一个全局变量就会和rand()函数的名字发生冲突。

  • 不光是在包含头文件的时候会发生命名冲突,假设我们在公司完成一个项目,我们需要把自己的代码传送到一个指定的头文件中,这时候同事如果跟我们用了一样的对象名也会发生命名冲突

那要怎么去解决这个冲突呢?此时就可以使用到【namespace】命名空间了

域的概念

搞清楚作用域运算符之前我们需要知道什么是域

: :是作用域限定符,下面例子介绍他的作用
C++中域有函数局部域,全局域,命名空间域,类域;就是因为有了域,我们在每个域中定义所需要的变量,函数这些,又因为每个域中的作用域不同,函数、变量这些在各个域的生命周期就不同。
注意:

  • 局部域和全局域除了会影响编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期
int a = 0;
void f1()
{int a = 1;printf("a = %d\n", a);
}void f2()
{int a = 2;printf("a = %d\n", a);
}int main(void)
{f1();return 0;
}

这里就分为3个域,main函数的局部域,f2函数的局部域,f1函数的局部域

  • 这里f1,f2函数中都有a这个变量,但是这两个不是同一个a,在f1函数中的a他的生命周期就是f1函数这个局部域
  • 对于f2函数中的a他的生命周期也只限于f2这个函数这个局部域。但是对于所以函数之外定义的a这个对象,他就是在全局域中定义的这个对象,所以他的生命周期是全局域。

注意:这里我们C/C++中如果有同名的对象,那么我们优先访问局部域中的对象

如上面,我们调用f1函数打印a
在这里插入图片描述
但是如果我们非要强行先访问全局域中的变量a,这时我们就要用到: :这个运算符
【域作用限定符】在这里插入图片描述

  • 可以看到,直接在对象a左边用: : 运算符,因为这个运算符左边是空的,所以他代表的是全局域,就会全全局域中找这个对象a

基本了解后,我们回到原来的问题来解决了

命名空间的概念

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的

  • 定义命名空间的格式:namespace 命名空间名{ …}

例如:

namespace ljj
{int rand = 0;
}

示例1

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

如果我们要解决这个问题,我们就可以使用:

namespace ljj
{int rand = 0;
}

这时候我们的rand这个对象就定义在命名空间域里面,如果想要使用就必须通过域限定符来访问.。

  • 这时候我们就可以直接去打印这个rand的话出来的结果就不是0了,而是一个随机数,此时它使用的其实就是库中的rand()

不过有同学会疑惑函数不是要加上()吗,为何这里的rand就可以直接调用这个函数了呢❓

我们看一下vs的警告
在这里插入图片描述

  • 对于int(__cdecl *)(void)而言其实是一个函数指针,它指向了这个函数的地址,又刚好因为这个函数我们不需要传入参数,void表示无参,所以也相当于是调用了这个库函数【__cdecl是VS函数名修饰规则,函数重载会讲到】

示例2

  • 我这里定义了两个.h的头文件,里面分别有队列和单链表的结构体,不过对于它们来说我都将结点的结构体名称定义成了Node,此时我若是在.cpp的源文件中同时包含了这两个头文件就会出现问题
    在这里插入图片描述
#include "Queue.h"
#include "List.h"int main(void)
{struct Node* qu;struct Node* l;return 0;
}
  • 通过运行代码可以看到,编译器报出了【类型重定义】的错误
    在这里插入图片描述
  • 那这个时候应该怎么办呢?此时【命名空间】它又可以派上用场了
namespace Queue
{//队列结构体...
}
namespace SingleList
{//单链表结构体...
}
  • 可以说他们封装在各自的命名命名空间中由于他们的作用域不同就不会发生冲突了

命名空间的嵌套定义

命名空间里面也可以嵌套命名空间。就像结构体里面也可以嵌套结构体

这时候我们对于:
在这里插入图片描述
是不是也可以封装在一个命名空间里面在嵌套定义两个命名空间

namespace ljj
{namespace Queue{//队列代码{namespace SList{//单链表代码}
}

命名空间的访问

指定命名空间访问

指定命名空间访问(适用环境是【做项目】)
【使用格式】:命名空间名称::成员
注意:如果要访问命名空间中的结构体成员,struct关键字要放在命名空间名称的前面
在这里插入图片描述

  • 若是要去访问命名空间内部的其他函数和普通变量的话,也可以这么去用
Queue::InitQueue(&qu);
Queue::Push(&qu, 1);
Queue::max = 200;SList::PushBack(&sl, 1);
SList::PopBack(&sl);
SList::max = 300;

但是这只样一次次的去使用作用域限定符去访问很繁琐,有可能我们要频繁的去使用这个对象每次都要这样写,这时候就请出我们的using关键字

using访问命名空间

第一种:

  • using 命名空间名(全部展开)

这样我们就相当于把命名空间的变量移到全局域中,我们就不用指定命名空间来访问命名空间中点变量

namespace ljj
{int b = 1;int a = 0;
}
using namespace ljj;
int main()
{printf("%d %d\n", a, b);return 0;
}

注意:但是这种用法仅仅限于我们平常练习中的用法,在做项目时还是老老实实去用指定命名空间来访问。
不然:

namespace ljj
{int b = 1;int a = 0;
}
using namespace ljj;
int main()
{int a = 3;printf("%d %d\n", a, b);return 0;
}

在这里插入图片描述
像这种在局部域中定义一个相同的,就会直接优先访问局部的。诸如各种此类问题

第二种:

  • using 命名空间名::命名空间对象名(部分展开)

这种就是一个折中的办法,像调用初始化栈和队列这些函数一般只需要使用一次,我们就可以使用这种方法来频繁使用一个命名空间中的对象

using Queue::Push;
using SList::PushBack;
using SList::PopBack;

在这里插入图片描述

  • 在面对C++中std标准库里的【cout】和【endl】时,我们就需要使用到using namespace std;,因为他们都定义在了标准库中,只是包含头文件是不够的

注意:这里cout和endl是c++的printf和换行
但是前面说了,这样直接
全部展开很容易发生冲突*

我们就使用部分展开

using std::cout;
using std::endl;

在这里插入图片描述

对于嵌套命名空间的访问

这里就想到我们的结构体嵌套假如有

struct S1
{struct S2{int a;}p;
}ps;
ps.p.a = 1;
printf("%d\n", ps.p.a );

我就就是先找到外层结构体变量ps,再找到内层结构体变量p,再找到内层结构体变量a。

对于嵌套的命名空间访问也差不多

  • using版本是这样
using namespace ljj::hg;
using namespace ljj::pg;
printf("%d %d\n", a, b);

注意:不能直接展开ljj命名空间来访问被嵌套在这个空间的命名空间对象,就像不能直接找到结构体ps变量访问a的变量一样。

  • printf(“%d %d\n”, ljj::pg::a, ljj::hg::b);

指定命名空间访问就是这样

输入&输出

在C语言中我们使用printf和scanf进行输入和输出,但是C++中不再使用这种函数来输入和输出。
< iostream> 是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输
出对象

输入

std::cin 是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输
⼊流。

我们想要进行输入还得使用:>>流提取运算符,

namespace ljj
{int a;int b;int c;
}using namespace ljj;
using std::cin;
using std::cout;
int main()
{cin >> a;cout << a;return 0;
}

在这里插入图片描述
注意:使用cin和cout要打开std命名空间;

  • std命名空间是C++标准类和对象这些定义的空间

输出

```cpp
namespace ljj
{int a;int b;int c;
}using namespace ljj;
using std::cin;
using std::cout;
int main()
{cin >> a;cout << a;return 0;
}

输出就是cout语句,要配合<<是插⼊运算符使用、

输入输出的特性

namespace ljj
{int a;float b;char c;
}using namespace ljj;
using std::cin;
using std::cout;
int main()
{cin >> a >> b >> c;cout << a << ' ' << b << ' ' << c;return 0;

输入和输出都不用像C语言那样加格式转化符来进行不同类型的输入输出,他会自动转换类型进行输入输出。
在这里插入图片描述
注意:c++输出浮点型数据不会像c语言一样保留6位小数而是输入的是几位就是几位

换行

std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。

如图:在这里插入图片描述
他会刷新缓冲区的数据。
与cout和cin一样需要指定命名空间:using std::endl

using std::cin;
using std::cout;
using std::endl;
int main()
{cin >> a >> b >> c;cout << a << ' ' << b << ' ' << c<< endl;cout << "hello world\n" << endl;return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/388987.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一刷代码随想录(贪心5)

56. 合并区间 题意&#xff1a; 给出一个区间的集合&#xff0c;请合并所有重叠的区间。 示例 1: 输入: intervals [[1,3],[2,6],[8,10],[15,18]]输出: [[1,6],[8,10],[15,18]]解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. 示例 2: 输入: intervals [[1,4],[4…

windows子系统wsl完成本地化设置locale,LC_ALL

在 Windows 的子系统 Linux&#xff08;WSL&#xff09;环境中&#xff0c;解决本地化设置问题可以采取以下步骤&#xff1a; 1. **检查本地化设置**&#xff1a; 打开你的 WSL 终端&#xff08;比如 Ubuntu、Debian 等&#xff09;&#xff0c;运行以下命令来查看当前的本…

51单片机和STM32区别

51单片机和 STM32 区别 51单片机和 STM32 是两种常见的微控制器&#xff0c;它们在架构、性能、外设接口、功耗和开发环境等方面有所不同。 1. 架构差异 51单片机基于传统的哈佛总线结构&#xff0c;采用 CISC 架构&#xff0c;而 STM32 基于 ARM Cortex-M 系列的32位处理器核…

CRMEB-众邦科技 使用笔记

1.启动项目报错 Unable to load authentication plugin ‘caching_sha2_password’. 参考&#xff1a;http://t.csdnimg.cn/5EqaE 解决办法&#xff1a;升级mysql驱动 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</ar…

【天机学堂】面试总结

写在前面&#xff0c;首先要将天机学堂包装一下&#xff0c;智慧教育平台》&#xff0c;暂时就想到这个。天机学堂文档 1.包装简历 待更新。。。

【iOS】iOS内存五大分区

iOS内存五大分区 总揽 iOS中&#xff0c;内存主要分为五大区域&#xff1a;栈区&#xff0c;堆区&#xff0c;全局区/静态区&#xff0c;常量区和代码区。总览图如下。 这个图我觉得更好记&#xff0c;因为下面是低地址&#xff0c;上面是高地址&#xff0c;是比较符合日常…

堆的实现-向上调整算法-向下调整算法-堆排序-TopK问题 C语言

一、堆的概念及结构 二、 向上调整算法 注意:循环条件不可写parent > 0 //向上调整算法 //child为下标 void adjustup(int* a, int child) {int parent (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){swap(&a[child], &a[parent]);child pa…

CoderGuide

CoderGuide是一个针对同学们前后端求职面试的开源项目&#xff0c;作为一名互联网/IT从业人员&#xff0c;经常需要搜索一些书籍、面试题等资源&#xff0c;在这个过程中踩过很多坑、浪费过很多时间。欢迎大家 Watch、Star&#xff0c;供各位同学免费使用&#xff0c;永不收费&…

Spring框架 配置Gateway网关/spring cloud gateway 基础入门案例教程

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 网关作为微服务集群唯一的对外入口,可以实现很多功能. 例如: 统一的解决跨域(一个ajax请求 origin域名和请求目标url中域名不同,ip不同,域名不同,端口不同,都会引发的问题)问题. 统一的身份认证.认证解…

C++ 关键字与库函数 学习总结

sizeof与strlen 含义 sizeof&#xff1a;是一个操作符&#xff0c;用于计算数据类型或变量的大小&#xff08;以字节为单位&#xff09;。在编译时求值strlen&#xff1a; 是一个函数&#xff0c;用于计算字符串的长度&#xff08;不包括终止符 \0&#xff09;。在运行时求值不…

考研数学|保100冲130暑假强化保姆级规划

只做这些的话还不够&#xff0c;还要加上真题、模拟题。而且必须确保自己完全掌握上面的内容。 只看30讲和做1000题考90分是比较有困难的。如果刷完知能行1000题&#xff0c;90分应该很稳。 张宇1000题是考研数学难度较大一些的题集&#xff0c;题目难&#xff0c;计算量大&a…

机器学习笔记 - RAFT 光流简读

一、光流 光流是图像序列中像素的表观运动。为了估计光流,场景中物体的移动必须具有相应的亮度位移。这意味着一个图像中移动的红球在下一个图像中应该具有相同的亮度和颜色,这使我们能够确定它以像素为单位移动了多少。下图显示了光流示例,其中一系列图像捕获了逆时针旋转的…

增加一个按钮,批量获取凭证号

create PROCEDURE Cux_Ar_ServiceLedger_Voucher_ProcOrgId Int ,result Int output AS BEGIN SET NOCOUNT ONDECLARE Date DATETIME IF OrgId 0 or OrgIdBEGIN RAISERROR(N获取当前组织ID失败&#xff01;, 16, 1) RETURNEND SET Date GETDATE()BEGIN TRANSACTION BEGIN…

微调(一)

微调有两种办法&#xff0c; 一是模型全部参数的微调&#xff0c;二是少量参数高效的微调。前者由于参数多&#xff0c;需要的GPU多&#xff0c;并且全参数微调可能把模型带偏&#xff0c;后者只需要微调少量参数&#xff0c;需要的GPU少&#xff0c;还可能达到不错的效果&…

秒懂Linux之自动化构建工具-make/Makefile

目录 一.前文摘要 二.make/Makefile 一.前文摘要 在学习自动化构建工具前我们先来补充一下动静态库的相关指令 动态库指令 gcc -o 文件&#xff08;重命名&#xff09; 源文件 静态库指令 gcc -o 文件&#xff08;重命名&#xff09; 源文件 -static 二.make/Makefile 怎么形…

MATLAB(14)预处理

一、前言 在MATLAB中进行插值拟合、主成分分析&#xff08;PCA&#xff09;和小波分析之前&#xff0c;通常需要对数据进行一些预处理。这些预处理步骤可能包括数据清洗、缺失值处理、标准化或归一化等。下面我将分别为这三种分析方法提供预处理模型的示例代码。 二、实现 1.…

校园点餐系统

1 项目介绍 1.1 摘要 在这个被海量信息淹没的数字化时代&#xff0c;互联网技术以惊人的速度迭代&#xff0c;信息的触角无处不在&#xff0c;社会的脉动随之加速。每一天&#xff0c;我们都被汹涌而至的数据浪潮包裹&#xff0c;生活在一个全方位的数字信息矩阵中。互联网的…

大模型微调实战项目总结(非常详细)零基础入门到精通,收藏这一篇就够了

写在前面 不知不觉之间&#xff0c;距开源ChatGLM-Finetuning项目已经过去了8个月。大模型也在飞速的发展&#xff0c;开源社区也是越来越活跃&#xff0c;开源模型越来越多。 中间更新过一次&#xff0c;将代码重构让大家更容易理解&#xff0c;本次更新主要增加ChatGLM3模型…

JavaScript (十)——JavaScript 比较 和 逻辑运算符

目录 JavaScript 比较 和 逻辑运算符 比较运算符 如何使用 逻辑运算符 条件运算符 语法 JavaScript 比较 和 逻辑运算符 比较和逻辑运算符用于测试 true 或者 false 比较运算符 比较运算符在逻辑语句中使用&#xff0c;以测定变量或值是否相等。 如何使用 可以在条件语…