【C++】学习笔记——C++入门_1

简介: 【C++】学习笔记——C++入门_1

一、C++入门

1. 新建一个C++项目

  首先,在学习C++之前,我们需要新建一个C++的项目。我们打开 Visual Studio(我在这里使用的是VS2022版本,用什么版本都没关系)。

  我们选择 创建新项目

  接着选择 空项目 ,然后点击 下一步

  接着给项目命名,并选择把项目放到哪个目录下,最后点击 创建

  然后在右侧(可能是左侧)找到 解决方案资源管理器 ,在此下面右击 源文件 ,然后按顺序选择 添加新建项

  最后,选择 C++文件 ,并给将要生成的源文件命名(后缀需要是.cpp哦)。

  这样就有了一个C++的文件了,接下来就可以学习各种C++的知识啦。

2. C++关键字

  在C++98版本中,总共有 63 个关键字。

  在初学阶段,并不是所有的关键字我们都需要知道,而且很多关键字都是我们在学习C语言的时候就已经学过了的。我们只需要学到哪用到哪,需要什么学什么。久而久之,只要经常地去写C++程序,那么常用关键字是可能没问题的,不常用的关键字到时候查阅一下就行。

3. 命名空间

  学习过程中,与实践相结合肯定会事半功倍的,我们先来执行一个C++程序。

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

结果:

  其中,被include包含 iostream 就是用于在控制台或文件之间进行输入和输出操作的头文件, cout 就是输出,类似于 printf ,先不展开细讲, endl 就是换行符。我们主要讲的就是第二行,using namespace std; 这行代码与命名空间的关系密不可分。

  在C++中,为什么有命名空间呢?他的作用是什么?我们先来看一个C语言程序:

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

  学过C语言,或者说对C语言有一定理解的应该都知道这段代码的含义,让我们来看看结果:

  答案是10,嗯,没有问题。那假如啊,我在上面代码的基础上再包含一个 stdlib.h 头文件呢?

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

  让我们再来看看结果:

  欸~?怎么回事,咋就报错了?加上了 stdlib.h 头文件就报错了?我们知道,头文件在预处理阶段是会被展开的,而在刚刚新加的头文件当中,是存在一个叫做 rand 的函数,在定义全局变量 rand 时,与函数 rand 发生了命名冲突的,所以编译失败。

命名冲突的问题主要发生在

  1. 程序员 与 库
  2. 程序员 与 程序员

  C语言并不能解决这种命名冲突的问题,唯一的解决方法就是。。。其中一个程序员重新取个名字。那问题来了,在同一个域当中不能定义同名变量(或其他),不同的域当中能不能定义同名变量呢?

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

  结果是:

  当然是可以的,第一个 x 是全局域,第二个 x 是局部域。在调用的时候也是遵循 局部优先,就近原则 。我又双叒叕有问题了,假如哈,我想调用那个全局的 x ,有什么办法吗?

变量的调用遵循 局部优先 就近原则 。即先去调用局部域的变量,局部域找不到再去全局域找。

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

  来看看结果:

  嚯~,还真是 0 ,真的访问到全局变量了,那个 :: 又是什么?其实这个由两个冒号组成的符号叫做 作用域限定符 。这个符号左边部分就是限定的作用域,如果不写,则默认为全局域。

:: 是作用域限定符,该符号左边则是被限定的作用域,调用也只在被限定的作用域内查找,如若不写,则默认为全局域。


C++中域的种类

  1. 全局域
  2. 局部域
  3. 命名空间域
  4. 类域

  OK,咱们回到C++的命名空间部分。既然说,在同一个域内定义两个同名变量会报重定义的错,那假如我们真的需要定义两个全局变量 x ,怎么办呢?我们来学习一个关键字 namespace ,这个关键字的意思就是命名空间,用法有一点点向结构体,但他定义的不是结构体名称,而是命名空间的名称。

#include<stdio.h>
namespace space1
{
  int x = 1;
}
namespace space2
{
  int x = 2;
}
int main()
{
  printf("%d\n", space2::x);
  printf("%d\n", space1::x);
  return 0;
}

  我们使用 namespace 关键字创建两个个命名空间域,分别包住两个创建的变量 x ,我们看看结果:

  结果还是一如既往的没毛病。那我问个问题,既然被命名空间域给包含了,那这俩 x ,还是全局变量吗?答案当然是还是全局变量,我们通过分析生命周期就知道,被命名空间包含了后并不会改变他的生命周期,改变的仅仅是 调用/访问

全局域 改变 生命周期 和 访问

局部域 改变 生命周期 和 访问

命名空间域 改变 访问

  如果我们不去使用作用于限定符,还访问得到被命名空间域给包含的变量吗?

#include<stdio.h>
namespace space1
{
  int x = 1;
}
namespace space2
{
  int x = 2;
}
int main()
{
  printf("%d\n", x);
  printf("%d\n", x);
  return 0;
}

  来看看结果:

  好像不行,为什么呢?那是因为编译器只会访问 当前局部域 和 全局域,访问不到就会报错。

编译器搜索原则 :

如果没有指定作用域:1. 当前局部域 -> 2. 全局域 两个都没搜索到则报错。

如果指定了作用域,则直接去作用域搜索,没搜索到则报错。

  到这里,大家应该就知道了前面遇到的 rand 命名冲突的问题——我们只需要将 rand 放到一个命名空间域里面就可以了。至于命名空间名称冲突了怎么办,会发生什么问题,大家可以自己去尝试一下。

命名空间名重复的,编译器会将重复的命名空间给合并。

  再来看看这个:

#include<stdio.h>
namespace space1
{
  int x = 1;
  int ADD(int a, int b)
  {
    return a + b;
  }
}
namespace space1
{
  //int x = 2;
  struct Node
  {
    struct Node* next;
    int val;
  };
}
int main()
{
  printf("%d\n", space1::x);
  printf("%d\n", space1::ADD(1, 2));
  struct space1::Node phead;
  return 0;
}

  OK,已经可以灵活运用啦。

命名空间内不仅仅可以定义变量,还可以定义函数,结构等等,只要是你能定义的,都能在命名空间内定义。


使用命名空间域内的结构体并不是space1::struct Node phead;

而是struct space1::Node phead;

结构体关键字在前面。

  咱们继续回~,上次说到 using namespace std; 这,这句代码的作用是什么?我先说一种情景,比如说在某个文件下,非常频繁的使用某个命名空间域内的变量或者函数或者其他等等,我们每次访问和调用都需要加上命名空间名和作用域限定符,这也太麻烦了吧,于是乎,==using namespace == 这种方式就是展开命名空间,意思就是把访问权限打开,访问的时候就不需要指定作用域,直接访问就可以访问到。后面的 std 就是展开的命名空间是 std 这个命名空间。

using namespace:展开命名空间

用法:using namespace space1;

作用:使展开的命名空间的访问权限打开,不使用作用域限定符就可以访问。

*由于命名空间域包含的都是一些全局的东西,所以展开也就相当于恢复成全局。

  嘛,至于为啥要展开 std 这个命名空间呢。原因是这个 std 大有来头,他是所有C++库的命名空间。也就是说,不加这个,你使用的所有C++库内的东西都需要加上 std:: 这样的东西,可谓是超级麻烦。演示一下:

#include<iostream>
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}

  结果:

   coutendl 是C++标准输入输出库 iostream 的东西,要使用必须加上作用域限定符,代码短的还好,长的就会复杂很多了。

std是所有C++库的命名空间。

展开命名空间后仍然可以使用 std::

展开命名空间还是有弊端的,所以在日常练习中可以随意展开,在做项目的时候不建议展开。


未完待续

  关于C++的知识还是非常非常多的,一篇是肯定不能介绍完的,要是对后续部分感兴趣可以关注我哦,我会尽快完成下一篇的。

目录
相关文章
|
3天前
|
C++
【C++】学习笔记——继承_2
【C++】学习笔记——继承_2
11 1
|
1天前
|
存储 算法 编译器
程序与技术分享:C++模板元编程学习笔记
程序与技术分享:C++模板元编程学习笔记
|
3天前
|
存储 C++ 容器
【C++】学习笔记——map和set
【C++】学习笔记——map和set
7 0
|
3天前
|
C++
【C++】学习笔记——二叉搜索树
【C++】学习笔记——二叉搜索树
6 0
|
3天前
|
编译器 C++
【C++】学习笔记——多态_2
【C++】学习笔记——多态_2
5 0
|
3天前
|
编译器 C++
【C++】学习笔记——多态_1
【C++】学习笔记——多态_1
5 0
|
3天前
|
程序员 编译器 C++
【C++】学习笔记——继承_1
【C++】学习笔记——继承_1
5 0
|
3天前
|
编译器 C++
【C++】学习笔记——模板进阶
【C++】学习笔记——模板进阶
6 0
|
3天前
|
C++ 容器
【C++】学习笔记——优先级队列
【C++】学习笔记——优先级队列
5 0
|
3天前
|
C++ 容器
【C++】学习笔记——stack和queue
【C++】学习笔记——stack和queue
6 0

相关实验场景

更多