怎么制作网站的二维码,中国免费企业建站,建设一个大型电影网站,做app开发#x1f680; 优质资源分享 #x1f680;
学习路线指引#xff08;点击解锁#xff09;知识定位人群定位#x1f9e1; Python实战微信订餐小程序 #x1f9e1;进阶级本课程是python flask微信小程序的完美结合#xff0c;从项目搭建到腾讯云部署上线#xff0c;打造一… 优质资源分享
学习路线指引点击解锁知识定位人群定位 Python实战微信订餐小程序 进阶级本课程是python flask微信小程序的完美结合从项目搭建到腾讯云部署上线打造一个全栈订餐系统。Python量化交易实战入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
1. 前言
从语言的分类角度而言C是一种非常特殊的存在。属于高级语言范畴但又具有低级语言的直接访问硬件的能力这也成就了C语言的另类性因保留有其原始特性其语法并不象其它高级语言一样易理解但处理能力却比其它语言高很多。
从语言的处理能力和速度而言让人爱从语法体系角度而言对于学习者并不友好。
但对于专业开发者建议学好C语言C的底层特性对于理解其它语言的高级封装原理有很大的帮助。
本文将从一个简单的Hello world C程序开始以此程序中出现的基础知识为导入点深入探讨这些知识的底层逻辑。
好现在开始C之旅……
2. 基本结构语法
先从下面的Hello World程序开始逐一解释这几行代码中所包含的程序微观世界中的结构逻辑。
#include using namespace std;
int main(int argc, char** argv) {coutHello Worldendl; return 0;
}
所谓 “一叶而知秋” 上述的Hello World程序虽然只是简单的寥寥几行代码但是却完整地诠释了一个标准的C程序所需要具备的基础逻辑结构。 几行代码和多行代码的程序的区别在于所要实现的功能不同其核心的组织结构都有同工异曲之地。 当规模较大时程序结构无非在遵循基本结构的主导思想上进行分、再分、继续分…… 如同一个大家庭分成几个小家庭但每一个家庭的基本结构相似。 2.1 预处理指令
Hello World程序中的第一行代码
#include
语法解释
#是C预处理指令标识符号表示后面紧跟着的是 预处理指令。不同的**预处理指令**有不同的功能。
预处理指令在编写C程序时是否是必须的
答案不是必须那么什么时候需要预处理指令
要了解什么时候需要添加预处理指令则需要理解此行代码的语法用意。
高级语言与机品语言的区别之一是高级语言会提供大量的已经编好的功能代码这些功能性代码统称为API(应用程序调用接口)。
对于不同语言而讲其提供的名称略有不同如 JAVA 中以类库方式提供PYTHON语言中以模块方式提供C则是以头文件方式提供……其本质一样。
编写程序时如果需要用到语言提供的功能代码时则需要遵循不同语言的调用语法导入后方能使用。
#include 指令的作用指定程序中需要包含的头文件。欲在程序中使用C提供的API因API庞大繁复C对其API以分类方式存储在不同的文件中这些文件称为**头文件#include 后需要指定头文件**名称。 理论上讲在程序中可以不使用 #include指令。但在实际程序中几乎是不可能的否则并不能发挥高级语言的优势请直接使用机器语言便可。 #include 语法
include是一个导入或包含头文件的指令还有另一个语义默认情况下C运行系统会建立一个名为include的目录存放所有的自带头文件。此目录也称为预定义目录。
#include 头文件名
在导入C语言的头文件名时需要指定头文件的扩展名h导入c标准中的头文件时可以不指定扩展名。
//导入 C 语言的头文件需要指定扩展名
#include
//导入 C 标准中的头文件时可以不指定扩展名
#include
#include还有另外一种使用语法
#include 头文件名
使用双引号和使用尖括号包含头文件的区别
使用#include 文件名指令时编译器会直接从include目录中查找对应的头文件。使用#include 文件名 指令时则是先在当前文件所在的目录搜索没有则到Include目录里去找对应的文件。 在导入系统提供的头文件时建议使用尖括号 。 在导入自定义头文件时建议使用双引号。 在Hello World程序中导入了iostream文件则意味着程序需要iostream文件中提供的API那么又是什么有什么作用
这个问题稍后回答。
2.2 主函数
C是面向过程的编程语言所谓过程指代码以函数为基本单位进行组织当然函数还有更多特性关于函数的细节另行文再聊。
这里聊聊主函数的功能和语法结构。
int main(int argc, char** argv) {//自己的代码return 0;
}
主函数功能描述
主函数是整个程序的入口。当执行程序时C运行系统会查找程序中是否有一个符合系统要求的主函数语法结构。如果找到则从此函数的第一行代码进行指令解析。如果没有找到则调用失败。 类似于要去某一个小区拜访朋友首先第一步要找到小区的入口大门。 小区也许会有多个入口大门但C只有主函数这么一个入口。 主函数的语法结构
虽然上文的主函数中包含较多的组成元素如返回类型、参数……因C有向下兼容性。只要保证函数名为 main其它元素都可以省略对于C运行系统而言可以只认**main 函数名**。
如下去头剔尾之后的主函数C运行系统依然认识。
main() {
//自己的代码
} C可理解为C语言的plus版本C在发展过程中有很多标准所以C新标准都会向后兼容。 编写代码时主函数尽可能遵循当前C的新标准。 2.3 逻辑结构
麻雀虽小五脏俱全。Hello World程序虽然看似简陋但缩影了任何其它功能强大程序的基本逻辑结构。
无论程序的规模大小程序的本质都是用来处理数据。从全局角度来讲任何程序的逻辑结构都是如下几部分组件
数据。可以说程序开拔数据先行无数据无程序。数据的来源有多种如已知数据、交互数据、外部存储设备中的数据、网络数据……对于Hello World程序而言功能是输出Hello worldHello World便是程序中的数据已知数据。逻辑处理。Hello World程序只是演示程序没有数据处理这一环节但是在开发实际可用的程序时必须有数据处理环节否则吃进去又直接吐出来是没有意义和营养的程序。输出或展示数据。程序总是通过处理数据生成结果数据。结果数据需要通过某一种途径告诉使用者从而指导使用者的行为和认知。这便是输出的意义。 可以说编写程序就是如何掌控数据的轮回和重生。 coutHello Worldendl;
如上代码Hello World数据的存在形态在C语法中称为常量或字面值数据。
cout 是c提供的专用于输出的指令其包含在iostream文件中如此应该明白为何要在程序的第一行添加
#include
cout 语法
cout数据;
cout是一个输出指令但其语义是指代一个标准的输出设备其底层是以一个抽象名的方式连接到了一个具体的输出硬件设备资源这个设备往往指的就是显示器。或称其为标准输出设备。
在 cout 和数据之间有一个这是一个重定向运算符表示数据通过 流向标准输出设备。至于怎么流的可能就要查阅源代码其实现过程非一言二语能说清。这也是高级语言的特性之一屏蔽底层逻辑让开发者只关注于自身的高级业务逻辑。
在使用 cout指令时还有一个命名空间的概念。再回头查看上文最初给出的完整的Hello Wolrd 程序中其中有一行代码
using namespace std;
如果没有这一行代码不好意思cout不能工作或者说根本找不到cout。可以打开iostream的源代码看一看。
#define \_GLIBCXX\_IOSTREAM 1#pragma GCC system\_header#include
#include
#include namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION//{extern istream cin; /// Linked to standard inputextern ostream cout; /// Linked to standard outputextern ostream cerr; /// Linked to standard error (unbuffered)extern ostream clog; /// Linked to standard error (buffered)#ifdef \_GLIBCXX\_USE\_WCHAR\_Textern wistream wcin; /// Linked to standard inputextern wostream wcout; /// Linked to standard outputextern wostream wcerr; /// Linked to standard error (unbuffered)extern wostream wclog; /// Linked to standard error (buffered)
#endif//}// For construction of filebuffers for cout, cin, cerr, clog et. al.static ios_base::Init __ioinit;_GLIBCXX_END_NAMESPACE_VERSION
} // namespace#endif /* \_GLIBCXX\_IOSTREAM */
源代码中有一行
namespace std _GLIBCXX_VISIBILITY(default)
C引入了命名空间这一概念。
什么是命名空间?
就是起到一个逻辑分类的作用。 一个班上如果有 2 个同姓名的学生怎么办 在姓名前面再添加一个标识就可以了如大张三小张三这里的有大和 小就类似于命名空间。 在C可以使用命名空间作为附加信息来区分不同库中相同名称的函数、类、变量等。 也就是说为了避免其它的头文件中有 coutiosteam 为自己的cout前面添加了前缀 std。当然除了使用如下的语法。
using namespace std;
也可以直接在cout前面添加 std命名空间描述符。
#include
int main(int argc, char** argv) {std::coutHello Worldstd::endl; return 0;
} 注意使用语法命名空间后面有::。 endl是一个换行指令。也是定义在iostream文件中的std命名空间中。 3. 运行程序
遵循C语法编写的代码称为源代码源代码以标准扩展名cpp的文件存储称此文件为源代码文件。 Tip 源代码文件的扩展名不一定是cpp。不同的平台上的C扩展名可能不一样如果扩展名不是cpp只要文件内容符合C语法标准此文件依然是C源代码文件。 源代码并不能直接被计算机识别需要请一个专业翻译员把源代码翻译成计算机能理解的二进制指令和数据翻译后的代码称为目标代码。
翻译员在翻译时有 2 种可选的翻译模式
解释模式逐行翻译源代码。显然其速度较慢但易于调试和找出程序中的逻辑错误。编译模式把源代码一次性翻译成目标代码。显然其速度较快。现代编译系统已经具备很好的调试功能。
所以运行C程序之前需要安装C运行系统此系统中至少要包含C提供的API和翻译员C选择的编译模式。 安装C运行系统最简单的方式直接安装类似于带有运行环境的 dev-c IDE开发工具。 如何安装本文不做赘述。 编译器的执行流程
编译成目标文件检查源代码中是否存在语法错误然后把源程序编译成扩展名为 obj目标文件目标文件并不是最终编译产物也不能执行。链接头文件因程序中会使用到C的各种 API会包含各种头文件则需要将目标文件和各种必须的库头文件的集合链接在一起生成最终的可执行文件。可执行文件在windows平台中可执行文件的扩展名为exe源代码被编译后的最终执行文件名默认为 a.exe。
本文使用dev-c编辑和编译程序。 4.总结
本文从一个简单的C程序入手讲解C程序的基本逻辑结构。程序虽小却是所有可运行程序的缩影。
当然规模不同其要使用到的C相关知识会更多但全局宏观结构是相似的。