首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【C语言】预处理(预编译)详解(上)(C语言最终篇)

比如: #define MAX 100; #define MAX 100    我们首先要知道#define定义常量时是怎么工作的,它会直接把常量名替换为对应的值,在第一条语句中,MAX就代表了100...; ,而在第二条语句中,MAX就只代表100    所以很明显我们在使用#define定义常量时,最好不要在后面加上分号,那么为什么有时候加上分号也没有问题呢?...我们一起来学习一下:    带有副作用的宏参数就是:当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可能出现危险,导致不可预测的后果,其中副作⽤就是表达式求值的时候出现的永久性效果...如果是,就重复上述处理过程 注意: 宏参数和#define定义中可以出现其他#define定义的符号,比如先使用#define定义一个常量N,值为100,那么这个N就可以在另一个#define中出现,但是对于宏...,这个时候就要使用函数 宏可能会带来运算符优先级的问题,导致程序容易出错,比如忘记对参数加上(),或者忘了给整个式子加上()都可能出现预期以外的结果 3.宏和函数的命名约定    ⼀般来讲函数的宏的使⽤

12910

预处理详解

a + 1) ); 这⾥还有⼀个宏定义: 1 #define DOUBLE(x) (x) + (x) 定义中我们使⽤了括号,想避免之前的问题,但是这个宏可能会出现新的错误。...带有副作⽤的宏参数 当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可能出现危险,导致不可预测的后果。副作⽤就是表达式求值的时候出现的永久性效果。...注意: 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。 6....宏可能会带来运算符优先级的问题,导致程容易出现错。 宏有时候可以做函数做不到的事情。⽐如:宏的参数可以出现类型,但是函数做不到。...其他预处理指令 #error #pragma #line ... 不做介绍,⾃⼰去了解。 #pragma pack()在结构体部分介绍。 参考《C语⾔深度解剖》学习 完

10510
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【C语言】变长数组,二分查找和数组之间自动替换的实现

    一、C99中的变⻓数组 在C99标准之前,C语⾔在创建数组的时候,数组⼤⼩的指定只能使⽤常量、常量表达式,或者如果我们初始化数据的话,可以省略数组⼤⼩。...()里面的单位,是以毫秒为单位,所以如果想让函数滞留1秒的话,应该是Sleep(1000);需要带上头文件#include windows.h>, system()函数原型包含在头文件 “stdlib.h...# define _CRT_SECURE_NO_WARNINGS 1 #include #includewindows.h> #include int main...⼆分查找 / 折半查找 在⼀个升序的数组中查找指定的数字n,很容易想到的⽅法就是遍历数组,但是这种⽅法效率⽐较低。 ⽐如我买了⼀双鞋,你好奇问我多少钱,我说不超过300元。...显然很慢;不过⼀般你会随机猜大的数,会猜中间数字,⽐如:150,然后看⼤了还是⼩了,大了往上走,小了往下猜,这就是⼆分查找,也叫折半查找。

    11410

    总结c++ primer中的notes

    添加代码到程序的一些不相关的位置,会导致我们认为是正确的程序产生错误的结果。 问题出在未初始化的变量事实上都有一个值。...都是合法的值——虽然这个值不可能是程序员想要的。因为这个值合法,所以使用它也不可能会导致程序崩溃。可能的结果是导致程序错误执行和/或错误计算。...(条款26:尽可能延后变量定义式的出现时间) 定义 const 对象 因为常量在定义后就不能被修改,所以定义时必须初始化。...(因为程序中定义只能出现一次,如果含有定义头文件包含在多个源文件之中,就会出现重复定义) 一些 const 对象定义在头文件中 如果 const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义...const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝

    1.6K90

    C语言:预处理详解

    一、预定义符号 C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。...再外部再加一个大括号,来保证宏定义的加法在乘法运算之前!...四、带有副作用的宏参数 当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可 能出现危险,导致不可预测的后果。副作⽤就是表达式求值的时候出现的永久性效果。...宏可能会带来运算符优先级的问题,导致程容易出现错。 6.3 宏有时可以做到函数做不到的事情 宏的参数可以出现类型,但是函数做不到!!...3、作用域不同 #define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而typedef有自己的作用域。

    35110

    C语言预处理详解

    预定义符号 C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。...1) ); 这⾥还有⼀个宏定义: #define DOUBLE(x) (x) + (x) 定义中我们使⽤了括号,想避免之前的问题,但是这个宏可能会出现新的错误。...带有副作⽤的宏参数 当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可 能出现危险,导致不可预测的后果。副作⽤就是表达式求值的时候出现的永久性效果。...宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。 6....宏可能会带来运算符优先级的问题,导致程容易出现错 宏有时候可以做函数做不到的事情。⽐如:宏的参数可以出现类型,但是函数做不到。

    8410

    C语言——R预处理详解

    一、预定义符号 C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。...⼀个宏定义: #define DOUBLE(x) (x) + (x) 定义中我们使⽤了括号,想避免之前的问题,但是这个宏可能会出现新的错误。...四、带有副作用的宏参数 当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可能出现危险,导致不可预测的后果。副作⽤就是表达式求值的时候出现的永久性效果。...但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。 六、 宏函数的对比 宏通常被应⽤于执⾏简单的运算。...宏可能会带来运算符优先级的问题,导致程容易出现错。 宏有时候可以做函数做不到的事情。⽐如:宏的参数可以出现类型,但是函数做不到。

    13910

    【C++篇】迈入C++的大门——初识C++(下篇)

    ⽐如:⽔壶传中李逵,宋江叫"铁⽜",江湖上⼈称"⿊旋 ⻛";林冲,外号豹⼦头; 引用方式:类型& 引用别名=引用对象 C++中为了避免引⼊太多的运算符,会复⽤C语⾔的⼀些符号,⽐如前⾯的<<...⼤ //int& ra = a; // 这样才可以 const int& ra = a; // 编译报错:error C3892: “ra”: 不能给常量赋值 //ra++; // 这⾥的引⽤是对b访问权限的缩...// 为什么要加外⾯的括号? // 为什么要加⾥⾯的括号?...• inline不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。...根本原因: 在这之前C/C++标准规定的NULL既是整数常量,也是空指针常量 • C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换

    3900

    从零开始学习c++全套通关系列(第一章)万字总结,建议收藏~

    二、标识符和关键字标识符(Identifiers)标识符是程序员定义的名称,用来标识变量、函数、类、对象等各种实体。标识符的命名规则如下:组成规则:可以包含字母(大小写敏感)、数字和下划线 _。...必须以字母或下划线开头,不能以数字开头。不能使用C++中的关键字作为标识符。标识符中不允许出现空格或标点符号。命名规范:命名要有意义,能够反映出其所代表的内容。...类型安全:#define 是简单的文本替换,不具有类型信息,容易导致意外的副作用。const 常量具有明确的类型信息,编译器可以进行类型检查。...调试和可读性:const 常量会保留其名称和类型信息,有助于提高代码的可读性和可维护性。#define 宏常量只是简单的文本替换,在调试时可能会导致一些困难。...三元运算符在一些情况下可以使代码更简洁和清晰,特别是在赋值语句中,可以代替一些简单的 if-else 结构。尽管三元运算符具有简洁的语法,但过度使用可能会降低代码的可读性,因此应适度使用。

    9810

    C中的预编译宏定义

    这一步骤是由预处理器(preprocessor)来完成的. 在源流程序被编译器处理之前, 预处理器首先对源程序中的"宏(macro)"进行处理....应该避免重新定义函数宏, 不管是在预处理命令中还是C语句中, 最好对某个对象只有单一的定义. 在gcc中, 若宏出现了重定义, gcc会给出警告....使用这些条件编译命令可以方便地实现对源代码内容的控制. else之后不带常量表达式, 但若包含了常量表达式, gcc只是给出警告信息....#if 0 {     一大段代码; } #endif 常量表达式可以是包含宏, 算术运算, 逻辑运算等等的合法C常量表达式, 如果常量表达式为一个未定义的宏, 那么它的值被视为0....(在gcc中, 如果给出了warning, 编译继续进行, 但若给出了error, 则编译停止.

    2.9K40

    C语言---预处理详解

    1.预定义符号 C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。...//有时候加上也不会有太大的问题,但是不建议加 //加上可能会导致问题 //#define M 100; //int main() //{ // int a = M;//如果在上面对M进行定义的时候在后面加上了分号的话...⼀次的时候,如果参数带有副作⽤,那么你在使⽤这个宏的时候就可 能出现危险,导致不可预测的后果。...除⾮宏⽐较短,否则可能⼤幅度增加程序的⻓度。 宏是没法调试的。 宏由于类型⽆关,也就不够严谨。 宏可能会带来运算符优先级的问题,导致程容易出现错。...size 10 #ifndef size #error 没有定义error #endif //#error确保再编译之前,满足某些条件 12.头文件的包含 头文件的两种形式: 1.

    8910

    C语言中的宏定义

    一个认真选择的名字可以帮助读者理解常量的意义。否则,程序将包含大量的“魔法数”,使读者难以理解。 2) 、 程序会更易于修改。我们仅需要改变一个宏定义,就可以改变整个程序中出现的所有该常量的值。...“硬编码的”常量会更难于修改,特别是有时候当他们以稍微不同的形式出现时。(例如,如果一个程序包含一个长度为100的数组,它可能会包含一个从0到99的循环。...假如数值常量3.14159在程序中大量出现,它可能会被意外地写成3.1416或3.14195。 虽然简单的宏常用于定义常量名,但是它们还有其他应用。 4) 、可以对C语法做小的修改。...这些参数可以在替换列表中根据需要出现任意次。 在宏的名字和左括号之间必须没有空格。如果有空格,预处理器会认为是在定义一个简单的宏,其中(x1,x2,…,xn)是替换列表的一部分。...2) 、预处理器只会替换完整的记号,而不会替换记号的片断。因此,预处理器会忽略嵌在标识符名、字符常量、字符串字面量之中的宏名。

    6.5K10

    【C语言】分支与循环

    ,可以加上⼤括号 else 语句2 // 如果想包含更多的语句,可以加上⼤括号 1.3嵌套if 在if else语句中if可与else连用,构成多种判断 #include 0) //这⾥的if 相当于嵌套在else语句中,形成了嵌套结构 printf("输⼊的数字是正数\n"); else printf("输...while ( 表达式 )      语句 ; // 如果循环体想包含更多的语句,可以加上⼤括号 ⾸先上来就是执行判断表达式,表达式的值为0,循环直接结束;表达式的值不为0,则执行循环语...所以在 do while 语句中循环体是至少执行⼀次的,这是 do while 循环比较特殊的地方。...;                 }         } } error:…… 有什么问题,各位大佬麻烦在评论区说一下

    9810

    C语言入门(循环和分支语句、goto语句)

    switch语句的形式 语句项 switch(整形表达式) 语句项一般是case语句 { 语句项; case (整形常量表达式...语句中,没办法直接实现分支,搭配break使用时才能实现真正的分支 case 2: printf("星期二\n"); break; case 3: printf("星期三\n");...: 输出结果为:m=5,n=3 需要说明的是break跳出的是自己所在的switch  二、while循环 在屏幕上打印1-10的数字                                 ...=15,由此可以看出程序不正确,经过分析得出:mul在计算完2的阶乘后,并没有把保留下来的返回值2重置为1,导致3!的算法变成了2*1*2*3=12,所以导致最终运行结果出错。...3.在一个有序数组中查找某个数字 #include int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int left =

    11410

    【C语言】预处理(预编译)详解(下)(C语言最终篇)

    #运算符    这里的#不是#include和#define前面的那个#,它是一个运算符,这个运算符将宏的⼀个参数转换为字符串字⾯量,它仅允许出现在带参数的宏的替换列表中,#运算符所执⾏的操作可以理解为...这个时候就要请出我们的#运算符了,它可以使得宏的参数字符串化,只需要将x左右的字符串分开,然后在它前面加上#即可,如下: #define PRINT(x , format) printf("the value...   现在我们来看看这段代码的运行结果:    现在我们再回到之前的那个问题,为什么#if后面必须跟一个常量表达式,不能是变量呢?...这是因为#if是在预处理阶段进行处理的预处理指令,在预处理阶段还没有给变量分配空间,也就是变量在这个阶段都不存在,自然不能使用变量了,只能使用常量 2.多分支条件编译    多分支条件编译也与分支语句中的多分支语句原理差不多...,一创建头文件,这条语句就出现了,这就是今天要介绍的第二个方法,在头文件开头写下预处理指令#pragma once,那么就可以解决头文件嵌套包含的问题,是不是特别简单呢?

    16810

    我与C语言二周目邂逅vlog——7.预处理

    常见的预处理指令有: 文件包含(#include) 宏定义(#define) 条件编译(#if、#ifdef、#ifndef、#else、#elif、#endif) 行控制(#line) 错误生成(#error...通常,我们会使用“预处理包围”的技术来解决这个问题,避免头文件被重复包含而导致编译错误。...在实际应用中,带参数的宏可以用于简单的数值计算,但要注意它只进行文本替换,容易出现优先级问题。因此,在宏体内通常使用括号来防止出现错误。...宏缺乏类型检查:宏在替换过程中不进行类型检查,这可能导致运行时错误,而不是编译期错误。例如,带参数的宏在使用不当时可能会导致未定义行为。...预处理器在这一过程中充当“代码整理员”的角色,它确保代码在进入正式编译阶段之前符合预期。 编译过程可以划分为以下几个阶段: 预处理:处理宏定义、文件包含、条件编译等。

    8810

    C语言——B数据类型和变量

    堆区是⽤来动态内存管理的(后期会介绍); 其实内存区域的划分会更加细致,以后在操作系统的相关知识的时候会介绍。 局部变量:包含在代码块中的变量叫做局部变量。局部变量具有临时性。...• %f :小数(包含 float 类型和 double 类型)。 • %g :6个有效数字的浮点数。整数部分⼀旦超过6位,就会⾃动转为科学计数法,指数部分的 e 为⼩写。...输出的值默认是右对齐,如果希望改为左对齐,则可以在%后添加 - 符号。对于小数,这个限定符会限制所有数字的最小显示宽度。...如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量EOF。...所以,储存字符串时, 很可能会超过数组的边界,导致预想不到的结果。

    16610

    C语言编程规范 clean code

    规则4.1 禁止头文件循环依赖 头文件循环依赖,指 a.h 包含 b.h,b.h 包含 c.h,c.h 包含 a.h, 导致任何一个头文件修改,都导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍...规则4.4 禁止在 extern "C" 中包含头文件 在 extern "C" 中包含头文件,有可能会导致 extern "C" 嵌套,部分编译器对 extern "C" 嵌套层次有限制,嵌套层次太多会编译错误...extern "C" 通常出现在 C,C++ 混合编程的情况下,在 extern "C" 中包含头文件,可能会导致被包含头文件的原有意图遭到破坏,比如链接规范被不正确地更改。...文本替换后,宏包含的语句跟调用点代码合并。 合并后的表达式因为操作符的优先级和结合律,可能会导致计算结果跟期望的不同,尤其是当宏参数在一个表达式中时。...禁止出现下列情况: 没有通过符号来解释数字含义,如 #define ZERO 0 符号命名限制了其取值,如 #define XX_TIMER_INTERVAL_300MS 300 8 编程实践 表达式

    5.6K10
    领券