随笔一

本文探讨了代码分文件的必要性,如模块化、复用和协作。讲解了预处理、编译、汇编和链接的过程,强调了extern关键字在访问跨文件全局变量中的作用。同时,讨论了头文件的声明与定义,以及#ifndef和#pragma once在防止头文件重复包含中的差异和优劣。
摘要由CSDN通过智能技术生成

1.为什么编写代码需要分多文件

这是为了代码的模块化
模块化的优点:
1.便于复用代码:通用性强的代码只需要写一遍,下次在其它程序需要用时,只需要更改很小的部分
2.便于多人协作:软件设计的任务并不是一个人完成的,因此分模块进行合作
3.便于维护和修改:确定问题可以只修改一部分模块,而不是牵一发而动全身

2.多源文件是如何进行访问的

代码的编译过程分为:
预处理:去注释,宏替换,条件编译,头文件包含、抛错(人为操作等)
编译:检查语法错误,生成汇编代码
汇编:将汇编代码转换成机器识别的二进制代码
链接:将.o文件进行链接,建立起联系关系,生成可执行文件

不同的模块就是在链接阶段产生了联系,通过头文件中的声明,去查找对应的函数,进行调用,如果查找不到,则在链接的时候会出现链接错误
函数或变量在声明时,并没有给它实际的物理内存空间,它有时候可以保证你的程序编译通过, 但是当函数或变量定义的时候,它就在内存中有了实际的物理空间,如果你在编译模块中引用的外部变量没有在整个工程中任何一个地方定义的话, 那么即使它在编译时可以通过,在连接时也会报错,因为程序在内存中找不到这个变量!你也可以这样理解, 对同一个变量或函数的声明可以有多次,而定义只能有一次!

3.extern

我们在一个文件去访问另外一个文件的全局变量的时候,需要用extern 声明变量,告诉当前文件夹,我存在这个变量,不需要报错;
在链接的时候就会去另外一个文件寻找对应的变量

4.头文件不能定义全局变量

头文件不能定义全局变量,因为你的头文件可能会被多个c文件包含,这样一来多个c文件中就会有同一个全局变量的定义(强符号),链接器就会不知道该使用哪个符号来链接从而出错(重定义)。声明会被认为是弱符号所以头文件中一般只写声明。

5.ifndef和pragma once的区别

5.1检测方式比较

为了避免同一个文件被include多次
1 #ifndef方式
2 #pragma once方式

在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。

#ifndef是C/C++语言特性,依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心"撞车",可能就会导致头文件明明存在,编译器却硬说找不到声明的状况

#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的"同一个文件"是指物理上的一个文件(存储位置),而不是指内容相同的两个文件。带来的好处 是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。
对应的缺点就是如果某个头文件有多份拷贝(不同位置,相同的文件),本方法不能保证他们不被重复包含。当 然,相比宏名碰撞引发的"找不到声明"的问题,重复包含更容易被发现并修正。

5.2可移植性和效率比较

#pragma依赖于编译器,所以一些老的编译器不提供(比如说vc6之前),而#ifndef可移植性非常好。

ifndef方式 由语言支持所以移植性好,但是在包含一个文件的时候,只有打开这个文件,根据文件的保护宏是否已经被定义来判断此文件是否已经被包含过,所以效率相对较低。当然在#include的时候,程序员也可以自己判断所要包含的文件的保护宏是否已经被定义,来决定是否要包含这个文件。类似下面的代码:

#ifndef FILE_H(通常头文件的宏,就是自身文件名的大写)
#include “file.h”
#endif
这样做可以得到较高的效率,而且保证可移植性。但是文件之间的依赖性较高,如果一个文件的保护宏改变的话,所有使用如上形式包含这个文件的文件都要修改,有悖于模块化的思想。

#pragma once方式可以避免名字冲突,但是是平台相关的所以可移植性比较差,但是它效率更高:因为不需要去打开包含的文件,就可以判断这个文件有没有被包含,当然这个工作是系统帮我们完成的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值