《c语言深度剖析》整理--预处理

C语言深度解剖 PDF 分享 链接:https://pan.baidu.com/s/1U-8L7ZY5_sLpk4p0J302Mg           提取码:d8nu 相关推荐 [Objective-c程序设计] 中文编程·学习进阶_易语言 Windows API开发详解 函数、接口、编程实例 Programming in ... 阅读详情
 

一、宏定义

     1. 宏定义的作用域

        宏定义开始,到文件结束(其他的文件包含宏定义的文件也可引用)。

     2. 宏定义可增加代码的可读性

         #define ERROR_POWEROFF -1

         若不采用宏定义的方式,代码中出现-1 时,程序的可读性变差,代码中出现有具体的含义的单独的数字(比如上面-1) 称为魔鬼数,别人阅读代码的时候会抓狂,恐怕自己阅读的时候,也不知具体的含义

     3. 宏预编译阶段宏定义替换代码中具体的定义

        这点代码中定义比较容易出错,比如

        (1)#define SQR (x)   x * x

                  当表达式 x = 10+1, SQR(x) * SQR(x)   替换为 10+1*10+1,显然这不是我们想要的结果,导致出错

        (2)#define ADD (x)  (x)+(x)

                  当表达式 x=5, ADD(x)*ADD(x) 替换为 (5)+(5)*(5)+5,显然这不是我们想要的结果,导致出错

         解析:避免这种错误,当宏定义的时候,每部分都加上括号:(1))#define SQR (x)    ((x) *( x)) (2)#define ADD (x)   ((x)+(x))

       4. 当宏出现在字符串中的时候,宏不会被替换

           比如 printf("ADD(x)");  打印的结果为 ADD(x) 而不是 (x)+(x)

       5. 宏定义函数的时候,函数标识符和参数之间不能有空格

          比如   #define SQR   (x)   x * x   , 宏将变成代码中用(x)   x * x   替换代码中的SQR  ;

         但引用宏的时候可以有空格,比如 #define ADD (x)   ((x)+(x)), 应用的时候 ADD       (3)  和 ADD(3) 都是正确的

        6. 取消宏定义的符号 #undef,此符号之后的宏的定义将不再起作用

 二、条件编译

        条件编译的形式之一:

      (1)     #ifdef 标识符
                              程序段1
                      #else
                             程序段2
                      #endif

      (2)    #if 常量表达式
                              程序段1
                    #else
                             程序段2
                    #endif

         条件编译应用于场景之一,比如当在windows平台下编写代码调试,而程序又是可以运行在linux或者aix平台下,这样可以进行条件编译;

         条件编译和 if--else if---else if .....else 语句一样可以有不同的引申

三、文件包含#include   

       1.  文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。C语言提供#include 命令来实现文件包含的操作,它实际是宏定义的延伸;

        (1)#include <filename>

                  C 编译系统所提供的并存放在指定的子目录下的头文件。找到文件后,用文件内容替换该语句;

       (2)#include “filename”

                 预处理应在当前目录中查找文件名为filename 的文件,若没有找到,则按系统指定的路径信息,搜索其他目录。找到文件后,用文件内容替换该语句。

         #include 是将已存在文件的内容嵌入到当前文件中

      2. #include 支持相对路径

          比如,#include "./filename" (当前目录下的文件filename) #include "./icp/filename"(上层路径文件icp目录下的文件filename)

四、#pragma comment(...)

         该指令将一个注释记录放入一个对象文件或可执行文件中。常用的lib 关键字,可以帮我们连入一个库文件。比如:

         #pragma comment(lib, "user32.lib")

        该指令用来将user32.lib 库文件加入到本工程中。

        linker:将一个链接选项放入目标文件中,你可以使用这个指令来代替由命令行传入的或 者在开发环境中设置的链接选项,你可以指定/include 选项来强制包含某个对象,

        例如:#pragma comment(linker, "/include:__mySymbol")

五、#pragma warning

       #pragma warning( disable : 4507 34; once : 4385; error : 164 )

      等价于:

      #pragma warning(disable:4507 34) // 不显示4507 和34 号警告信息

      #pragma warning(once:4385) // 4385 号警告信息仅报告一次

      #pragma warning(error:164) // 把164 号警告信息作为一个错误。

      不过程序设计的时候,尽量少用disable,尽量在编码的时候,将warning问题解决掉,有的时候warning 也是潜在的bug

六、#pragma once

       在头文件的最开始加入这条指令就能够保证头文件被编译一次

       另外保证头文件只编译一次的方法: 

       #ifndef  _FILENAME_H

       #define _FILENAME_H

       #endif

七、#pragma code_seg

       另一个使用得比较多的pragma 参数是code_seg。格式如:

       #pragma code_seg( ["section-name"[,"section-class"] ] )

      它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它

八、#pragma message

        能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:

       #pragma message(“消息文本")

       当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。 这对于我们进行源码控制,代码调试有帮助。

九、内存对齐 #pragma pack

        1. 内存对齐的原理:

          字,双字,和四字在自然边界上不需要在内存中对齐。(对字,双字,和四字来说,自然边界分别是偶数地址,可以被4 整除的地址,和可以被8 整除的地址)无论如

何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存

访问仅需要一次访问。减少内存地址总线访问未对齐的地址的周期。

          2. 内存对齐例子

          (1)struct TestStruct1
                   {
                           char c1;
                           short s;
                           char c2;
                           int i;
                    };

            解析:此结构体在内存中的布局为  1*,11,1*******,1111    (1  代表占用内存,* 代表为内存对齐补的内存空间)

           所以 sizeof(TestStruct1)  为12

         3. 内存对齐的避免

           可以在程序设计的时候,尽量避免内存对齐的情况,尽量自然对齐节省占用内存空间,比如上例

           struct TestStruct2
           {
                   char c1;
                   char c2;
                   short s;
                   int i;
            };

          sizeof(TestStruct2) 为 8

         4. #pragma pack

          #pragma pack (n),编译器将按照n 个字节对齐

          #pragma pack (),编译器将取消自定义字节对齐方式

          例如

           #pragma pack(8)
           struct TestStruct4
           {
                     char a;
                     long b;
           };
          struct TestStruct5
          {
                    char c;
                    TestStruct4 d;
                    long long e;
           };
         #pragma pack()

        解析:

        TestStruct4 内存布局: 1***,1111

        TestStruct5 内存布局:  1***,1***,1111****,11111111

        所以 sizeof(TestStruct4) 为 8,sizeof(TestStruct5)为 24

       5. 内存对齐的规则

         (1)每个成员分别按自己的方式对齐,并能最小化长度

         (2)复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度

         (3)对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐

         (4)对于数组,比如:char a[3];它的对齐方式和分别写3 个char 是一样的.也就是说它还是按1 个字节对齐,即数组按照数组中的每个成员的类型对齐

                   如果写: typedef char Array3[3];Array3 这种类型的对齐方式还是按1 个字节对齐,而不是按它的长度

         (5)不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个

十、#预算符

       1. # 符号的用处之一: 将宏中字符串中的变量,以变量值的形式打印

          (1)比如:

          #define SQR(x) printf("The square of x is %d.\n", ((x)*(x)));

         如果这样使用宏:SQR(8);

         则输出为:

         The square of x is 64.

         (2) 修改上面的宏为:

          #define SQR(x) printf("The square of "#x" is %d.\n", ((x)*(x)));

         再使用:

         SQR(8);

         则输出的是:

        The square of 8 is 64.

十一、##预算符

          ##预算符作用:粘合剂

         #define DISPLAY(n) x ## n

         如果这样使用宏:

         DISPLAY(8)

        则会被展开成这样:

        x8

C语言学习路线图PDF2021版 一、C语言学习路线前言 随着互联网及互联网+深入蓬勃的发展,经过多年的时间洗礼,C/C++语言俨然已成为“第一”语言,出色的性能使之成为高级语言中的性能王者。 这么牛的语言,你是不是想知道怎样学习和掌握它呢?接下来请看经过小编整理过C/C++学习路线思维导图。 博主已汇总成了一个十万字PDF版的C语言学习路线教程关注博主的微 信 公 众号 “C和C加加” 回复“PDF”即可获取!需要C/C++入门、进阶教程的回复“ZXC”即可获取! 二、C语言学习路线思维导图 1、环境篇(ubuntu.. 阅读详情

相关推荐

2022精心整理的C语言学习宝藏,值得收藏~

C 语言可以零基础入门,它的语法是很多高级编程语言的基础,比如说 Java、C++;并且起到承上启下的作用,向上可以学习高级编程语言,向下可以学习计算机组成原理、操作系统等等偏基础的计算机基础知识。 C语言相关电子书: 推荐书籍: 第一本书《阿哈C语言》的写书风格个人认为比较风趣幽默,对于培养兴趣,基础学习还是很不错的 《C程序设计语言》,机械工业出版社,作者Brian W. Kernighan / (美)Dennis M. Ritchie。C 语言之父写的,入门经典书籍。 《

编程与实战的博客 2473

C语言-struct内存分布

因为结构体的内存分配是连续的,所以从数组a的首地址开始拷贝,“hello” 加上'\0'总共6个字节,是没有超过结构体总的长度的(28Byte),所以该程序不会报错,且能正常运行。看结构体中的a,b变量,其内存分布是连续的,那也就是,当我从b的首地址先拷贝“hello world!这里有点离谱,在linux中编译的,竟然没有报错,且能正常运行,可能是gcc版本有点低。a[4] 可以理解为:以a的首地址,也就是c0开始偏移4Byte,也就是*(t1.a+4);答案是可以,输出:o。

weixin_47011594的博客 588

2022 精心整理的 C语言/C++ 语言学习宝藏,值得收藏~

知名大学计算机系开源课程收录: 浙江大学课程攻略共享计划 清华大学计算机系课程攻略 上海交通大学课程资料分享 北京航空航天大学(北航)课程作业资料共享计划 华北电力大学计算机系课程攻略 北京邮电大学计算机考研信息汇总 C++从入门到“精通“,我踩过的坑希望你可以绕着走_程序员编程指南的博客-优快云博客1 c++ 发展方向实验室开发C++绝对是工科生中的第一大语言,C++兼具面向过程以及面向对象的特性,既拥有比较优秀的运行速度,又有良好的大型项目开发能力,那简直可以制霸高校实验室了。后端开发学了

编程与实战的博客 9021

C语言:#include <filename.h> 和 #include “filename.h“的作用

#include <filename.h> 查找头文件直接去标准路径下去查找,如果找不到就提示编译错误。 #include "filename" 先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。 如果找不到就提示编译错误。 对于库文件也可以使用 “” 的形式包含但是这样做查找的效率就低些,当然这样也不容易区分是库文件还是本地文件了 ...

It's You--MXL 1303

上下文工程深度剖析:提示工程架构师详解提升AI理解能力的「三阶模型」

在大语言模型(LLM)主导的AI时代,上下文理解能力是决定模型实用性的核心瓶颈。尽管GPT-4、Claude 3等模型的上下文窗口已扩展至128k+ tokens,但信息过载、意图漂移、多轮交互断裂等问题仍未解决。本文从提示工程架构师的视角,提出一套提升AI理解能力的三阶模型预处理阶:通过降噪、结构化与浓缩,解决“上下文质量低”的问题;建模阶:通过意图提取、关联强化与对齐,解决“意图理解浅”的问题;动态更新阶:通过缓存、修剪与增量更新,解决“多轮交互断”的问题。本文结合第一性原理推导、数学形式化。

AI开发架构师 805

树莓派驱动步进电机

步进电机一般由电机、驱动器构成,树莓派连接驱动器控制电机。 一、接线 DIR+/- 用于控制方向,PUL+/- 用于控制转动; 正极DIR+ 和 PUL+ 接到GPIO口,两个负极接到GPIO口或地线均可,控制的时候不使用。 实验中,DIR+ 接35口,PUL+ 接38口。 树莓派4B GPIO口如图所示 远离树莓派USB的一侧 是 1、2、3号口 二、驱动 DIR控制方向,使用高电平或低电平控制; PUL控制转动,使用脉冲驱动。 三、代码 import RPi.GPI.

weixin_42337765的博客 1万+

数据结构与算法分析(排序,递归,链表)

1.C提供形如#include 的语句,它读入文件filename并将其插到include语句处,include语句可以嵌套,换句话说,文件filename本身还可以包含include语句,但是显然一个文件在任何链接中不能包含它自己,编写一个程序,使它读入被include语句修饰的一个文件,并输出这个文件。为什么递归调用要求不能包含它自己?

tugouxp的专栏 1601

Geant4 案例分析(一): B1

本文是对Geant4 B1的案例分析,其中特定的功能不做介绍,而注重于各个文件的主要功能,以及它们组织的方式。

m0_51809467的博客 1582

matlab 将一维数组保存为txt文件 之 命令行格式

dlmwrite('t2_median.txt',x2,'precision','%6.2f','delimiter','\t');  %将滤波后的数据x2保存为D:\matlab file\t2_median.txt   详见 D:\NIAOT\开题报告\matlab\read_txt\original_median.m  ...

xyk801的博客 2517

Synopsys的CoreConsultant使用简析

CoreConsultant使用简析

weixin_58165606的博客 1万+

鸿蒙OS开机动画背后的秘密:从代码到视觉的完整解析(附源码分析)

本文深入解析了鸿蒙OS开机动画的系统级实现原理。从bootanimation服务的启动配置、与Render Service的协同,到基于VSync信号的帧率同步与绘制流水线,结合OpenHarmony源码进行了逐行解读。文章揭示了其事件驱动的优雅退出机制,并探讨了视频支持、多屏适配等高级特性与定制化可能,为开发者理解鸿蒙图形子系统提供了硬核技术视角。

sony5的博客 972

《c语言深度剖析》整理--符号

一、注释符号       c语言的注释符号有两种 /*...*/ 和 //     1.   以下几种注释的形式:       A)int/*...*/i;       B)char* s="abcdefgh //hijklmn";       C)in/*…*/t i;       解析:       A 正确,编译器再编译代码之前将注释符号替换为空格 ,等价于 int

xyk_code的专栏 1082

9.23华为OD机试真题 新系统 - 小菊的寻宝之旅 (Java/Py/C/C++/Js/Go)

9.23华为OD机试真题 新系统 - 小菊的寻宝之旅 (Java/Py/C/C++/Js/Go)

算法大师! 994

C语言深度剖析-读书简记

陈正冲的《C语言深度剖析. 第2版》这本书确实不错,对C语言中的一些易错和重要的知识点进行了深度剖析,碰巧在网上看到这篇博客,对这本书中的关于C语言的一些易错的和重要的知识点做了一些整理,故转载过来,以便后续查阅。

hijack00的博客 2985

【软件测试】- 公有云、私有云、混合云简介以及如何在公有云与私有云上分别搭建测试环境

公有云、私有云以及混合云是目前云计算领域的三种主要模式。它们之间的区别主要在于部署方式、数据访问和管理控制的不同。在阿里云或腾讯云上使用 Kubernetes 和 Docker 搭建测试环境可以提供高度的可伸缩性和灵活性。这样的环境非常适合于需要在多种配置和条件下进行测试的复杂应用。通过云服务提供的工具和服务,可以轻松管理和监控整个测试过程。在云服务上搭建测试环境涉及选择合适的云提供商、配置云资源、安装和设置所需软件等步骤。### 1. 选择云服务提供商。

weixin_46453070的博客 2342

结构光相移法-多频外差原理与实践

结构光相移法是一种常用的三维形貌测量技术,它通过对投射到目标物体上的结构光进行相位调制和解调,实现对物体表面的三维重建。其中,多频外差原理是结构光相移法的核心原理之一,通过使用不同频率的结构光来实现相位测量,并可以提高测量精度和抗干扰性能。结构光相移法的多频外差原理是一种常用的三维形貌测量技术,它通过使用多个不同频率的结构光进行相位调制和解调,实现对物体表面的三维重建。本文介绍了多频外差原理的原理和实践应用,并提供了相应的Python源代码,希望对读者理解和应用结构光相移法有所帮助。

CodeByte的博客 737

推荐C语言有关的书籍

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.youkuaiyun.com/k666668/article/details/51510139 推荐几本学习c语言比较好的材料 《征服c指针》 《c和指针》 《c语言深度剖析》 《彻底搞定c指针》 《攻破C语言笔试与机试难点V0.3》(这个是别人整理的pdf文档,我在参...

yakan2333的博客 589

CNN+LSTM+Attention+DNN模型实战:pytorch搭建CNN+LSTM+Attention+DNN行车速度预测

CNN+LSTM+Attention+DNN模型实战:pytorch搭建CNN+LSTM+Attention+DNN行车速度预测

6045

C语言编译处理深度剖析

C语言编译处理是一个复杂但精巧的系统工程, 它像一座精心设计的工厂流水线, 将人类可读的高级语言代码转化为机器能高效执行的指令. 从预处理器的文本处理, 到编译器的深度分析和优化, 再到汇编器和链接器的精密装配, 每个阶段都有其独特的数据结构、算法和设计哲学正如计算机科学家Niklaus Wirth所言: “程序 = 算法 + 数据结构”, 而编译器正是将这一公式转化为可执行现实的关键桥梁. 掌握编译原理, 你将在软件开发的殿堂中拥有更深刻的洞察力和更强大的解决问题的能力。

X 530

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C语言数组分析

定义二维数组的时候,行可以省略,列绝对不能省略。int a[][4];// 合法写法int a[3][];// 编译报错静态数组内存连续,空间固定;malloc 动态内存不一定连续。C99 变长数组不能动态扩容。,所有下标底层都是指针解引用运算。多维数组拆解思路:二维数组 = 存放多个一维数组的数组;三维数组 = 存放多个二维数组的数组。分清两个极易混淆概念:→ 数组指针(指针,接收多维数组)int *p[n]→ 指针数组(数组,存放一堆指针)

W_32600的博客 574

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C陷阱与缺陷学习笔记

N年读过这本书,当时读的时候囫囵吞枣,加上时间久远,90%的内容都忘记了。昨天在整理书籍的时候翻出来了,这本书短小精悍却不失为经典之作。抽出时间再拜读一遍,顺便做做笔记,记录精华。

zfs2008zfs的博客 3607

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

嵌入式C语言面试核心要点与实战技巧

C语言作为嵌入式开发的核心技术栈,其底层机制与硬件交互能力是开发者必须掌握的关键技能。从预处理器指令到内存操作,类型系统到中断处理,深入理解这些基础概念是编写高效可靠嵌入式代码的前提。本文重点解析#error指令的工程应用、volatile关键字的三大使用场景、以及防御性编程中的位操作技巧,通过寄存器查看宏等实战案例,展示如何避免隐式类型转换等常见陷阱。这些技术不仅对面试准备至关重要,更是实际开发中保证系统稳定性的必备知识。

weixin_28840811的博客 531

2024年自学C语言:从环境搭建到核心概念的系统指南

C语言作为计算机系统的基石,其核心价值在于提供对内存、硬件和底层运行机制的精细控制。理解其工作原理,如指针、内存管理和编译链接过程,是掌握系统级编程和高性能计算的关键。这种底层控制能力,使得C语言在操作系统内核、嵌入式系统、数据库和编译器开发等对性能与资源敏感的场景中不可替代。通过搭建现代开发环境(如VSCode与Clang/GCC工具链),并结合动态内存管理、数据结构实现等工程实践,学习者能够构建坚实的计算机系统认知,为深入物联网、自动驾驶等前沿领域奠定基础。

weixin_30239339的博客 870

C语言考研真题精解:从指针内存到实战调试的编程进阶指南

C语言作为编程的基石,其核心在于对计算机内存的直接操作与高效管理。理解指针与内存管理原理,是掌握C语言的关键,这直接关系到程序的性能、安全性与资源效率。在工程实践中,无论是嵌入式开发、系统编程还是算法实现,扎实的C语言基础都至关重要。通过分析字符串处理、数组遍历、动态内存分配等高频应用场景,可以深入巩固指针运算、内存布局及数据结构基础等核心概念。本文聚焦于考研真题这一高浓度实践样本,精选涉及指针、内存管理与调试技巧的经典题目,通过深度剖析与代码实现,帮助学习者构建系统化的知识网络,有效提升解决实际编程问题的

weixin_32932149的博客 258
上一篇: 《c语言深度剖析》整理--关键字
下一篇: 《C语言深度刨析》整理--指针和数组
xyk_code
博客等级 码龄15年 3粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值