【C++修炼之路】C++入门(上)

简介: 【C++修炼之路】C++入门(上)

一、前言


大家好呀,我是 a n d u i n anduin anduin 。今天为大家带来了第一篇 C++ 文章,接下来 a n d u i n anduin anduin 会和大家一起学习 C++ ,共同进步,共同成长!


ba66f6b3493a4928a8028ab9df7cdada.png

C++语言建立在C的基础之上。C++ 容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。这些使得 C++ 更加强大。


所以我们在 C++ 入门时,会学习很多琐碎的语法,这些实际上就是在对 C 添砖加瓦,和填 “坑”。

对于 C++ 的重点,其实有两方面,一块是我们入门结束后要学习的类和对象,还有一部分就是 stl 标准模板库。这些我在以后都会重点讲解。


而 C++ 的历史我也就不多说了,我们今天的重点是讲解知识,所以对历史有兴趣的小伙伴可以去查阅一下资料。


说了这么多,其实就是因为是 C++ 开篇哈哈哈,得把之后的内容交待一下,相信有的小伙伴已经迫不及待了,所以我们这就开始学习 C++ 入门第一篇 。



二、第一个 C++ 程序


在学习一门语言时,我们总是会先使用该语言编写 “hello world” 程序,意味着打开了新世界,所以在开始我们的 C++ 之旅前,我们也写个程序:

#include <iostream>
using namespace std;
int main()
{
  cout << "hello world" << endl;
  return 0;
}


这就是 C++ 的 hello world 写法,但是我们有没有考虑过他为什么能打印出 “hello world” ?


这里的 namespace 是什么,打印内容的那一句代码又是什么意思?这些可能我们可能都没想过。如果你对这些还不太了解,或是比较生疏,那么恭喜你,本文非常适合像你我这样的初学者,学习完这篇文章后,就可以大致想清楚这个程序的意思了。



三、C++ 关键字(C++98)



C++一共有63个关键字,其中包含 C语言的32个关键字。


接下来我们就来认识一下它们:

image.png


数量大约是我们学习 C 语言时的两倍。

我们这边就是见一见,之后文章中都会讲到~


四、命名空间


接下来我们讲解的就是 namespace 命名空间。


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


对于 C 语言,是无法解决命名冲突的,举个例子:


rand 是 c 语言中取随机数的一个库函数名,在没有引头文件:#include <stdlib.h> 的情况下,我们可以使用 rand 来定义变量。



e90401aa7b78ba1f850d2903f81dfc24.png

但是一旦引了头文件,就会发生报错:

37de92d84af0cc0ad4156adbd9838fa7.png


这就是 命名冲突 。这种情况实际上很常见,比如定义变量时可能会和库里的名字冲突;在与他人合作时,可能多个人定义的名字之间也会冲突。


而通过命名空间,就可以轻松解决这个问题。


1、命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对 {} 即可,{} 中即为命名空间的成员。


我们定义出的命名空间就像一个域,就像局部域和全局域一样,每个域之间不相互影响,我们可以把命名空间叫做命名空间域。


命名空间域只影响使用,不影响生命周期。


所以在不同的 namespace 中的成员就不会互相冲突。


命名空间有 四个特点 :


   命名空间名字不受限定,可以随机取。


   命名空间中可以定义变量/函数/类型,十分自由


   命名空间可以嵌套定义


   若同一工程中,命名空间名字相同,最终会被合并为一个命名空间,此时就几乎丧失了命名空间的作用,因为在这里面命名冲突存在的话依然会报错


下面逐个演示一下:


1、2特点:

namespace anduin // 名字就是我
{
  int val = 10;
  int solve()
  {
    int returnvalue = 20;
    return returnvalue;
  }
}


3特点:

namespace anduin
{
  int foo = 100;
  namespace guldan
  {
    int fooo = 1000;
  }
}



4特点:

在工程中,用定义同样的命名空间:


d9bfd00573f239a5390d39097c0fbd9d.png


.c 文件中包含头文件,编译运行时,两个命名空间就会合并:

aa39ec56ebfa3cc01648d9d56dfa8578.png


这里就相当于用 tool.h 中的 print 函数将 test.h 中的 max 打印了出来。



2、命名空间的使用


命名空间的使用的关键为 域作用限定符 :: ,就是我们上面 4 特点中像个骰子一样的 ::


:: 的左边为域,如果有命名空间域,则限定访问命名空间域中的内容,如果域左边为空,访问的就是全局域,会直接到全局范围内找 :: 右边的变量或其他。


举个 :: 访问全局域的例子

52a547ad6db85fe64af0b505b9140c9a.png



我们知道,C/C++ 为局部优先原则,默认先从局部找,但是 :: 就直接将域限定到了全局域,找到就使用,找不到就报错。所以打印的为全局的 a = 2 。


如果在命名冲突的情况下,就可以将冲突的部分放到不同的域,通过域作用限定符来访问命名空间,:: 左边就放命名空间,右边就是命名空间中的成员,通过这种方式来解决问题 ,我们再举个例子:

我们之前学过数据结构,知道链式队列中是要使用到链表的,假如此刻我们有两个头文件:


a901dd6901d9dd4598bb27860c916b84.png

如果同时包含头文件,且定义相同类型名字 Node 的节点,通过命名空间就可以成功定义:

eb08323048ead24ed6033958e2a58478.png


我们看到是可以成功定义的。

这里 struct 放命名空间的前面是因为冲突的是 Nodestruct 是一个前缀,:: 修饰的是冲突的部分。

嵌套命名空间的使用

174db8e7a9c85cf93f5360001134e2de.png


通过 :: 不断访问命名空间,找到 print 函数和 a 完成对数据的打印。



3、命名空间的三种展开方式


通过我们上面了解了命名空间的使用,其实发现有时使用很繁琐,需要不停的 :: 展开,所以命名空间还有别的展开方式。


命名空间一共有三种展开方式:


   指定命名空间访问(就是我们上方的,使用一次展开一次)

   全局展开

   部分展开


对于这块的讲解呢,就可以回归我们第一个 C++ 程序的代码了。这就既能解决我们的疑惑,又能讲解知识点。


#include <iostream>
using namespace std;
int main()
{
  cout << "hello world" << endl;
  return 0;
}


实际上通过上面的学习我们可以知道:其实 std 就是一个命名空间,为了防止命名冲突,C++ 之父在发明是就给它包好了一个空间,就是 std

指定命名空间访问

指定命名空间就是一个个展开嘛,直接上代码:


79e67501ea81efbe057036f041212125.png


全局展开 :


全局展开就是 using namespace std ,直接将 std 在全局展开了,所以使用的时候就无须使用 :: 进行逐个展开,可以直接使用。


打个比方,比如没展开,就会直接在全局找这个变量;但是如果展开,就不仅在全局找,还会到命名空间找。展开相当于影响了编译时的查找规则。


0b0828ce599a82c65d631022dbfdef3b.png


但是实际上这种展开方式并不好,因为命名空间,就是为了防止冲突而建立。这边就相当于直接把命名空间拆开来了。


所以对于这种展开我认为在平常练习代码,或者是刷题时很好用,但是对于写工程就不适合了。所以在之后的讲解知识点的时候,我大多还是全局展开,但是小伙伴们需要注意区分一下使用场景。

部分展开 :


综合上面两种方案,还有一种就是部分展开,对命名空间某个常用成员进行展开,比如:



01804b358f0e08ad4179a35815c469db.png



假如 cout 常用,我就部分展开 cout ;对于 endl 我就不进行展开,还是指定访问。


总结 :


命名空间的展开就是为了使用的方便,对于不同的情况有不同的展开方式:


   写工程,写项目:常用的部分展开,不常用的局部展开,两者混搭,一切为了安全和严谨。

   练习,刷题:用全局展开更加方便,一切为了效率和方便。






相关文章
|
1月前
|
安全 编译器 程序员
【C++初阶】C++简单入门
【C++初阶】C++简单入门
|
2月前
|
程序员 C++
C++模板元编程入门
【7月更文挑战第9天】C++模板元编程是一项强大而复杂的技术,它允许程序员在编译时进行复杂的计算和操作,从而提高了程序的性能和灵活性。然而,模板元编程的复杂性和抽象性也使其难以掌握和应用。通过本文的介绍,希望能够帮助你初步了解C++模板元编程的基本概念和技术要点,为进一步深入学习和应用打下坚实的基础。在实际开发中,合理运用模板元编程技术,可以极大地提升程序的性能和可维护性。
|
16天前
|
编译器 Linux C语言
C++基础入门
C++基础入门
|
1月前
|
安全 编译器 C++
C++入门 | 函数重载、引用、内联函数
C++入门 | 函数重载、引用、内联函数
25 5
|
1月前
|
存储 安全 编译器
C++入门 | auto关键字、范围for、指针空值nullptr
C++入门 | auto关键字、范围for、指针空值nullptr
49 4
|
1月前
|
编译器 C语言 C++
C++入门 | 命名空间、输入输出、缺省参数
C++入门 | 命名空间、输入输出、缺省参数
33 4
|
1月前
|
编译器 程序员 C语言
C++入门
C++入门
31 5
|
1月前
|
安全 编译器 C语言
C++入门-数组
C++入门-数组
|
1月前
|
存储 编译器 程序员
C++从遗忘到入门
本文主要面向的是曾经学过、了解过C++的同学,旨在帮助这些同学唤醒C++的记忆,提升下自身的技术储备。如果之前完全没接触过C++,也可以整体了解下这门语言。
|
2月前
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)