[Cherno C++ 笔记 P1~P10]安装、链接器、变量、函数、头文件

    • 系列博客
  • 前言
    • 视频链接
    • P1~P4 安装部分
    • P5 C++是如何工作的
      • 第一个C++程序
      • 代码如何编译为二进制文件
      • 第一个函数
      • 将函数放在其他文件中
    • P6 C++编译器是如何工作的
      • C++编译器实际上负责什么?
    • P7 C++链接器是如何工作的
      • 什么是链接
      • 链接错误
        • 未解决的外部符号
        • 有重复的符号
    • P8 C++变量
    • P9 C++函数
    • P10 C++头文件
      • VS中的文件夹
      • 第一个头文件
      • #pragma once
      • "" 和 <>

系列博客

[Cherno C++ 笔记 P1~P10]安装、链接器、变量、函数、头文件
[Cherno C++ 笔记 P11~P20]判断,循环,指针,引用,类
[Cherno C++ 笔记 P21~P30]static,枚举,构造函数,析构函数,继承,虚函数,接口,可见性
[Cherno C++ 笔记 P31~P40]数组、字符串、CONST、mutable、成员初始化列表、三元操作符、创建初始化对象、new关键字、隐式转换与explicit
[Cherno C++ 笔记 P41~P50]运算符重载、this、生存期、智能指针、复制与拷贝构造函数、箭头操作符、动态数组、std::vector、静态链接、动态库

前言

这个系列的视频需要一些基础,最好是学过C。

视频链接

P1 欢迎来到C++
P2 Windows 上安装C++
P3 Mac上安装C++
P4 Linux上安装C++
P5 C++是如何工作的
P6 C++编译器是如何工作的
P7 C++链接器是如何工作的
P8 C++变量
P9 C++函数
P10 C++头文件

P1~P4 安装部分

安装部分网上也有很多,安装也简单。
现在又很多工具可以用来写C++,这里推荐使用vs。

P5 C++是如何工作的

第一个C++程序

#include<iostream>int main()
{std::cout << "Hello world!" << std::endl;std::cin.get();
}

#include<iostream> 叫做预处理语句编译器收到源文件后,会预先处理,找到<>中的文件,然后拷贝到这个位置。

main是程序的入口,计算机从这个函数开始执行代码。在这里,main函数的返回类型是int,但是代码中没有返回任何东西,这是因为main函数是特殊的,它不一定需要返回值。没有写return进行返回的话,它会默认返回了0。

<< 符号叫做重载运算符,可以理解为一个函数。

视频有很大一段在讲vs的相关设置,感兴趣的话可以观看视频。

代码如何编译为二进制文件

项目中的每一个cpp文件都会被编译,但是头文件不会被编译,头文件的内容在预处理时包含到了cpp中。
每一个cpp文件都被编译为object file(目标文件)vs生成的文件后缀为.obj,我们需要将这些文件合并成一个执行文件,链接(Link)会将所有的obj文件黏合在一起,合并成一个.exe文件。

第一个函数

void Log(const char* message) {std::cout << message << std::endl;
}int main()
{std::cout << "Hello world!" << std::endl;Log("Hello World!");std::cin.get();
}

将函数放在其他文件中

在源文件中新建一个Log.cpp

#include<iostream>void Log(const char* message) {std::cout << message << std::endl;
}

将Log函数放在其他地方后,main并不知道发生了这样的改变,它找不到叫做Log的函数,这时进行编译会报错。
我们需要在main所在的文件中声明Log函数存在

#include<iostream>void Log(const char* message);int main()
{std::cout << "Hello world!" << std::endl;Log("Hello World!");std::cin.get();
}

声明:
声明表示这个符号、函数是存在的。void Log(const char* message);就是一个声明,它没有函数体。
定义:
定义是说明这个函数到底是什么,是函数的函数体。

在构建整个项目时,所有.cpp文件都会被编译,链接器会找到正确的Log函数的定义在哪里,如果找不到定义,会报链接错误。

P6 C++编译器是如何工作的

C++编译器实际上负责什么?

C++编译器只负责一件事,将文本文件(我们写的代码)转换成称为目标文件的中间格式。
这些obj文件可以传递到链接,链接可以做它所有要链接的事情。
编译器在生成这些obj时:

  1. 预处理代码。这意味着所有的预处理器语句都会先处理。
  2. 记号化和解析。将文本转换为编译器真正能够理解和推理的格式。这创建了所谓的抽象语法树。语法树一旦被创建,编译器就可以开始实际生成代码

与java不同的是,c++并不关心文件,文件只是提供给编译器源代码的一种方式。 可以随便创建一个文件(如xxx.hello_world),只要告诉编译器这是一个c++文件,就可以进行编译。
我们提供给编译器的每个c++文件,编译器都将把文件变成翻译单元(一个cpp文件并不一定对应一个翻译单元),翻译单元生成一个obj文件。

obj文件中都是机器码,我们可以在vs中查看汇编语句。

  1. 首先,我们在这里打一个断点
  2. 进行调试
  3. 右键,转到反汇编
  4. 可以看到相应语句转换为的汇编语句

可以在属性中开启优化、关闭优化, 对比一下生成的汇编语句

P7 C++链接器是如何工作的

什么是链接

链接时一个过程,当我们编译好源文件,我们需要通过一个叫做链接的过程,现在链接的主要任务时找到每个符号和函数所在的地方,并把它们链接起来。
多个翻译单元之间并不互通,我们需要一种方法把这些文件连接起来成一个项目。即使只有一个翻译单元,也需要将main函数连接起来,这就是链接器的主要目的和要做的事情。

链接错误

未解决的外部符号

当链接器找不到确切定义时发生。

我们写一个死代码,它没有被任何函数调用,其中Log函数虽然被定义但并不存在。在这里依然会报错。

虽然我们没有使用Multiply函数,但是在技术上来讲,我们有可能会用到这个函数,所以链接器需要链接到它,所以会报错。

我们使用static将Multiply函数限制在该文件中使用,由于我们没有使用该函数,所以不再报错。

在这里,我们并没有真正导入我们所写的返回void的Log,这里返回为int的函数由于没有明确的定义,所以会引发报错。

有重复的符号

如果我们的函数或变量具有相同的名字或签名,链接器会不知道该链接哪一个。

在下面这个例子中,我们可以看到,即使没有申明,两个相同的函数放在不同的文件中,依然会报错。

P8 C++变量

P9 C++函数

P10 C++头文件

VS中的文件夹


VS中的文件夹并不是真正的文件夹,你可以在资源管理器中看到并没有这些文件夹。这些文件夹实质上是过滤器。

第一个头文件

Log.cpp

#include<iostream>void Log(const char* message) {std::cout << message << std::endl;
}

Log.h

#pragma once
void Log(const char* message);

Main.cpp

#include<iostream>
#include"Log.h"int main()
{Log("Hello world!");std::cin.get();
}

通过#include"Log.h"导入头文件,将头文件中的文本粘贴到该位置。

#pragma once

progma once: 只包括这个文件一次

#pragma once监督这个头文件,阻止我们单个头文件被多次包含,并转换为单个翻译单元。

这里我想用集合来举例说明:
我们现在有两个集合A{a,b,c,d}和B{c,d,e,f}(a,b,c,d,e,f均为.h文件),当我们同时需要调取A和B时,#pragma once的作用就是将A和B取并集为{a,b,c,d,e,f}而不是简单的合并成{a,b,c,d,c,d,e,f}。

可是使用另一种方法实现相同的功能

#ifndef _LOG_H
#define _LOG_Hvoid Log(const char* message);#endif

#ifndef检查看是否有一个叫做_LOG_H的符号被定义了,如果没有被定义,则继续,如果被定义,则禁止。

“” 和 <>

在编译程序时,<>和""表示两种不同含义。

“”用来包含相对于当前文件的文件

<>用来搜索包含路径中的文件

“”也具有<>的功能

[未完待续]

[Cherno C++ 笔记 P1~P10]安装、链接器、变量、函数、头文件相关推荐

  1. 【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数

    上一篇文章,大概了解了链接器的工作内容就是:符号解析和重定位.点击上一篇文章查看:点击查看. 本片文章其实还是围绕链接器来学习.只不过不是很明显,当你学到下一篇文章时,就明白了. 本篇文章来弄明白一个 ...

  2. 【软件开发底层知识修炼】九 链接器-可重定位文件与可执行文件

    上几篇文章学习了Binutils辅助工具里面的几个实用的工具,那些工具对于以后的学习都是非常有帮助的,尤其是C语.C++语言的学习以及调试是非常有帮助的.点击链接查看上一篇文章:点击查看 本篇文章开始 ...

  3. C++ 笔记(25)— 理解 C++ 中的头文件和源文件的作用

    1. C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件: .cpp 文件,被称作 C++ 源文件,里面放的都是 C++ 的源代码 .h 文件,被称作 C++ 头文件,里面放的也是 C++ ...

  4. noi linux下如何安装视频播放器 和 播放swf文件的工具

    因为考试需要,孩子们必须要在赛前掌握使用noilinux了,可是使用起来诸多不方便,这不,在linux里用什么看视频和swf教程呢. 下面提供我搜集到的方法: 1.用noilinux自带的smplay ...

  5. 学习笔记15-C语言-预处理指令、条件编译、头文件

    预处理指令: 程序猿编写的代码不是标准C代码,并不能被真正的编译器索编译,需要一段程序把代码翻译一下. 翻译的过程叫做预处理,被翻译的代码叫做预处理指令,以#开头的都是预处理指令查看预处理的过程:gc ...

  6. 《Python数据分析基础教程:NumPy学习指南(第2版)》笔记5:第三章 常用函数1——文件读写、算术平均值、最大值最小值、极值

    本章将介绍NumPy的常用函数.具体来说,我们将以分析历史股价为例,介绍怎样从文件中载入数据,以及怎样使用NumPy的基本数学和统计分析函数.这里还将学习读写文件的方法,并尝试函数式编程和NumPy线 ...

  7. 解决方案资源管理器中没有头文件源文件

    转自:http://blog.csdn.net/wsj998689aa/article/details/40051287 我们操作VS的时候,正常情况下,解决方案窗口中,项目内文件的布局如下: 可是, ...

  8. 易语言静态连接器提取_易语言静态编译链接器切换工具

    使用说明 将exe程序和"链接器目录配置.ini"文件,复制到易语言安装目录的"tools"文件夹下 并且对"链接器目录配置.ini"进行修 ...

  9. C++链接器工具错误:LNK2001, LNK2019

    这是归属于链接器工具错误 这一类. 无法解析的外部符号"symbol" 代码引用了链接器无法在库和对象文件中找到的内容(如函数.变量或标签). 可能的原因 代码请求的内容不存在(例 ...

最新文章

  1. java extjs如何使用_ExtJS初探:在项目中使用ExtJS
  2. parted磁盘分区与GPT
  3. python在匿名函数作和_跟光磊学Python开发-匿名函数函数和高阶函数
  4. (7) hibernate之级联cascade和关系维持inverse
  5. easyui 排序实现
  6. 世界公认的第一商人——成就犹太商人的15个信条
  7. android jar包 权限,Android系统启动执行jar程序
  8. mac apache php.ini,Mac自带的Apache使用详解
  9. oracle高效分页存储过程(百万数据级)
  10. 1811114每日一句
  11. 【自动驾驶】ROS机器人操作系统总结
  12. R语言绘图—一键添加显著性
  13. markdown学习笔记(1):如何将.md文件转换为pdf
  14. 百度为手游盛世添把火
  15. 虹科Linux远程桌面服务器助力工业生产管理
  16. input 表单的type属性
  17. 数字信号处理总结之共轭对称性_复变函数积分的共轭=共轭的积分
  18. 2019年最值得期待的区块链项目:PlusFo到底行不行?
  19. RDKit | 子结构搜索和MCS算法
  20. web前端期末大作业——基于Bootstrap响应式汽车经销商4S店官网21页

热门文章

  1. bzoj 3521: [Poi2014]Salad Bar
  2. Foehn Phenomena
  3. MAE源代码理解 part1 : 调试理解法
  4. 蓝牙扫描枪直连蓝牙打印机
  5. 2021年中国物联网通信板块现状及重点企业对比分析(移远通信VS广和通VS和而泰VS拓邦股份VS移为通信)[图]
  6. videobuf2相关的videobuf-vmalloc.c 中内存分配kmalloc使用
  7. 项脊轩志(明 归有光)
  8. Meting-JS APlayer丨网页音乐播放器
  9. HPC 网络技术 — Overview
  10. 【mmaction2 slowfast 行为分析(商用级别)】总目录