C嘎嘎~~【初识C++ 上篇】

初识C++ 上篇

  • 1. C++关键字
  • 2.命名空间
    • ‍♂️2.1命名空间的定义
    • ‍♂️2.2命名空间的使用
  • 3.C++输入 & 输出

转眼间, 就进入C++这个新的篇章啦!
我带着些许心悸 和 激动:
心悸的是, 时间过的是如此之快, 上个学期咋们还在一起谈着C语言, 数据结构, 现在又要一起学习C++啦; 心悸的是, 我在上个半年, 耽误了很多时间, 遗漏了许多博客没写。。。
激动的是, 我们终于要爽起来了, 相信我们在学习C++之后, 尤其是学习了C++的STL, 模板之后, 就不想写C语言了(当然, C语言也有自己的优势哎)


C++是在C语言的基础之上, 容纳进去了面向对象编程思想, 并增加了许多有用的库, 以及编程范式等等。

接下来, 我们初识C++(主要是C++98)章节的主要任务是:

  • 了解C语言语法的不足, 以及C++是如何对C语言设计不合理的地方进行优化的
  • 为后续的类和对象学习打基础

1. C++关键字

  • C++ 总共有63 个 关键字, C语言有32个关键字。 在这个阶段, 我们对关键字只是起着了解作用, 以后碰到会进行详解的。

2.命名空间

应该不少萌新有些疑问: 啥是命名空间? 命名空间有啥用? 初学者有些疑问是一件好事, 我们可以带着疑问, 去有重点地学习。

让我们先来看看下面的一串代码:

#include

int size = 4;
int size = 5;

int main()
{
	printf("%d\n", size);
	return 0;

}

*****
error : size 重定义
******

看到上面的代码, 有人就会说: 老陈, 你怎么写出这么挫的代码? 怎么定义了 size 两次?
嘿嘿一笑, 这么写有它的实际意义啊:你想啊, 你以后参加工作, 肯定是分项目给你和你的同事做啊, 最后把你们的代码合并起来。 如果最后你的代码中的变量名 和 张三的变量名 冲突了?怎么办?打一架、、、
这时候, 我们的祖师爷 - 本贾尼就想出了一个办法:能不能在每个人的代码之间起一堵 “墙” , 你的变量和函数 在你的区域内部起作用, 出了你的区域就不会起作用了。
这一堵墙的专业名词 就叫做 命名空间

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


    那么问题来了: 这个namespace 是怎么用的?

‍♂️2.1命名空间的定义

// 1.命名空间内可以定义变量, 函数, 类型
namespace mu
{
	int rand = 5;
	
	int Sub(int a, int b)
	{
		return a - b;
	}

}

// 2.命名空间可以嵌套
namespace N1
{
	int a;
	int b;

	struct SLTNode
	{
		int val;
		struct SLTNode* next;
	};

	namespace N2
	{
		int a;
		int b;

		struct SLTNode
		{
			int val;
			struct SLTNode* next;
		};

	}

}

// 3.同一个工程中允许多个相同的命名空间, 编译器最终会合并成一个命名空间中
// eg: 如果一个工程中, 存在着 test.cpp , CSDN.cpp 两个文件, 
// 这两个文件都存在着 N1 这个命名空间, 最终会合并成一个N1的命名空间

总结:

  1. 命名空间的构成: 关键字 namespace, 命名空间名(自己定), {}(注意跟结构体区分开, 后面没有 逗号 ;)
  2. 一个命名空间就定义了一个新的作用域(但是这个不影响生命周期),命名空间内的内容都局限于改命名空间中
  3. 命名空间的作用: 解决全局的命名冲突问题
    这里有人就会十万个为什么: 为什么不解决局限的命名冲突问题啊?
    首先, 我们都知道局部变量是不能重定义的, 它重定义 一是 语法问题, 二是 没啥用。
    其次, 我们应该明确,我们现在学的知识是为了后面的类、 对象学习打基础。 这些玩意都是存在于全局作用域中的, 解决的是他们的命名冲突问题

‍♂️2.2命名空间的使用

学到这里, 有些人又有些疑问: 老陈, 我把我写的代码用命名空间包了起来, 那我们在工程中又怎么使用自己写的代码??
好问题! 这就是我们即将要讲的命名空间的使用。
系好安全带, 我们发车了!!

我们先了解一下编译器对域(墙)的搜索顺序:
C嘎嘎~~【初识C++ 上篇】_第1张图片
那我们如何突破局部域 和 全局域 , 从而访问到我们的命名空间域呢??
一共有三种方式:

  1. 用作用域限定符(::)去访问
namespace N
{
	int a = 10;
	int b = 8;

	struct SLTNode
	{
		int val;
		struct SLTNode* next;

	};
}

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

}
  1. 使用 using 展开某命名空间的成员
namespace N
{
	int a = 10;
	int b = 8;

	struct SLTNode
	{
		int val;
		struct SLTNode* next;

	};
}

using N::b;

int main()
{

	printf("%d\n", b);

	return 0;

}
  1. 使用using namespace 展开某个命名空间域
namespace N
{
	int a = 10;
	int b = 8;

	struct SLTNode
	{
		int val;
		struct SLTNode* next;

	};
}

using namespace N;

int main()
{
	printf("%d\n", a);
	printf("%d\n", b);

	return 0;

}

总结一下上面的几种情形:
C嘎嘎~~【初识C++ 上篇】_第2张图片

3.C++输入 & 输出

有些老铁, 到了这里就想问: 老陈, 我们搞了这么多东西, 还不知道 C++ 是如何输入 和 输出的?你这搞得不行啊, 赶快来讲一讲!!

由于C++ 兼容 C语言, 那么scanf 和 printf 还是照常能用的, 不过需要引用 头文件 cstdio , 不过好像在最新的C++语法里, 引用头文件 iostream 就能照用 这两个函数 。

#include
// #include

int main()
{
	int a = 0;
	scanf("%d", &a);
	printf("%d\n", a);

	return 0;

}

*****
5
5

*****

有些老铁又要问了: 那C++有么有自己专用的输入 和 输出 函数啊?cin 和 cout 就是你们要的答案
先别发问, 我先给你们看一下例子:

#include

using namespace std;

int main()
{
	int n;
	cin >> n;
	cout << n << endl;

	return 0;
}

*****
5
5

*****

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
  3. << 是流插入运算符,>> 是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。
  5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有一个章节更深入的学习IO流用法及原理。
  • 注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持格式,后续编译器已不支持,因此推荐使用+std的方式。


std是C++标准库的命名空间,如何展开std使用更合理呢?

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

自是汝才难用世,岂真吾相不当侯?
须知少日拏云志,曾许人间第一流

你可能感兴趣的:(c++,c语言,数据结构)