【常问基础】03.预处理

【嵌入式八股】一、语言篇(本专栏)https://www.nowcoder.com/creation/manager/columnDetail/mwQPeM

【嵌入式八股】二、计算机基础篇https://www.nowcoder.com/creation/manager/columnDetail/Mg5Lym

【嵌入式八股】三、硬件篇https://www.nowcoder.com/creation/manager/columnDetail/MRVDlM

【嵌入式八股】四、嵌入式Linux篇https://www.nowcoder.com/creation/manager/columnDetail/MQ2bb0

03.预处理

头文件

51.# include< filename. h>和# include" filename. h"有什么区别?

对于 include< filename. h>,编译器先从标准库路径开始搜索 filename.h,使得系统文件调用较快。而 对于# include“ filename.h"”,编译器先从用户的工作路径开始搜索 filename.h,然后去寻找系统路径,使得自定义文件较快。

52.头文件的作用有哪些?

C头文件是包含函数原型、宏、类型定义等C语言程序元素的文本文件,可以被其他源代码文件引用。头文件通常包含在一个源代码文件中,以便其他源代码文件可以使用其中定义的函数和变量。

头文件的主要作用如下:

  1. 声明和定义函数:头文件可以包含函数原型和定义,以便其他源代码文件可以使用这些函数。
  2. 定义常量和宏:头文件可以包含常量和宏的定义,以便其他源代码文件可以使用这些常量和宏。
  3. 定义结构和类型:头文件可以包含结构和类型的定义,以便其他源代码文件可以使用这些结构和类型。
  4. 保护代码:头文件可以使用预处理指令#ifndef#define#endif来防止头文件被重复包含。
  5. 模块化:头文件可以帮助将程序分成逻辑上独立的模块,提高代码的可读性和可维护性。
  6. 跨平台移植:头文件可以根据不同的平台和操作系统提供不同的实现,以便在不同的系统上运行。

C标准库中的头文件包括stdio.hstdlib.hstring.h等等。除了C标准库的头文件之外,还有许多其他的头文件,比如math.htime.hctype.h等等。

53.在头文件中定义静态变量是否可行,为什么?

可以通过编译,但是使用static定义变量证明该变量的作用域范围仅在该源文件内,其他源文件不能访问。如果在头文件中定义static变量,证明包含了所有这个头文件的源文件都定义了该变量,会造成变量多次定义浪费内存,而且不是真正的全局变量。

54.如何避免头文件重复引入和重复定义

防止头文件重复引入

使用预编译指令

//条件编译
     #define        //  宏定义 
     #undef         //  取消宏 
     #include       //  文本包含 
     #ifdef         //  如果宏被定义就进行编译 
     #if defined    //  与ifdefine的区别在于可以组成复杂的判别条件
     #ifndef        //  如果宏未被定义就进行编译 
     #if !defined   //  与if !define的区别在于可以可以组成复杂的判别条件
     #endif         //  结束编译块的控制 
     #if   defined  //  表达式非零就对代码进行编译 
     #else          //  作为其他预处理的剩余选项进行编译 
     #elif          //  这是一种#else和#if的组合选项 
     #elif defined  //  与ifdefine的区别在于可以可以组成复杂的判别条件
	 #elif !defined //  与ifdefine的区别在于可以可以组成复杂的判别条件
//编译指令
     #line          //  改变当前的行数和文件名称 
     #error         //  输出一个错误信息 
     #pragma        //  为编译程序提供非常规的控制流信息,可跟once,message等许多参数。
  • 使用条件编译指令
#ifndef  XXXX_H
#define  XXXX_H

......

#endif

优点:

不光可以保证同一个文件不被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不被同时引入。 受C/C++语言标准的支持,不受编译器的任何限制

缺点:

如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。 由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,条件编译指令会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。

  • 使用pragma once指令
#pragma once

pragma once编译指令使得同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。

优点:

你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。

遇到已经引入过的头文件时会直接跳过,而不需要打开。因此大型项目的编译速度也因此提高了一些。

缺点:

#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。

如果某个头文件有多份拷贝或者被多个.c或.h文件引入,pragma once不能保证他们不被重复引入。当然,相比宏名碰撞引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

  • 两者混用
#pragma once

#ifndef  XXXX_H
#define  XXXX_H
……
#endif

防止

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

【嵌入式八股】一、语言篇 文章被收录于专栏

查阅整理上千份嵌入式面经,将相关资料汇集于此,主要包括: 0.简历面试 1.语言篇【本专栏】 2.计算机基础 3.硬件篇 4.嵌入式Linux (建议PC端查看)

全部评论
mark
点赞 回复 分享
发布于 2023-03-31 11:32 辽宁
我只想知道嵌入式开发岗位应该怎么准备🤔
点赞 回复 分享
发布于 2023-03-31 21:54 湖南
写的很详细啊~~
点赞 回复 分享
发布于 2023-04-04 19:41 江苏
很好用的东西,和你一起上岸
点赞 回复 分享
发布于 2023-04-04 19:42 湖南
期待更新
点赞 回复 分享
发布于 2023-04-09 10:25 湖南
mark
点赞 回复 分享
发布于 2023-04-10 11:02 江苏

相关推荐

头像
11-07 01:12
重庆大学 Java
精致的小松鼠人狠话不多:签哪了哥
点赞 评论 收藏
分享
5 3 评论
分享
牛客网
牛客企业服务