c 预处理的宏定义

概念

以“#”号开头的都是预处理命令

例如 #include <stdio.h>宏定义

宏定义
无参数的宏名后不带参数
# 表示这是一条预处理命令, define 为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数,表达式、格式串等

举例:

#define PI 3.1415926

作用:

就是用指定标识符PI来代替数3.1415926
对源程序作编译时, 将先由预处理程序进行宏代换,
即用3.1415926表达式去置换所有的宏名PI, 然后编译

#include <stdio.h>

# define PI 3.1415

int main(int argc, char const *argv[]) {
  printf("%f\n", PI);
  return 0;
}

注意:

1. 预处理程序对宏定义不做任何检查,如果有错误,只能在编译已被宏展开后的源程序是发现

2. 宏定义不是说明或语句,在行末不必加分好,如加上分好则连分号也一起置换 容易出错的地方

3. 宏定义必须写在函数之外, 其作用域为宏定义命令起到源程序结束。如要终止其作用域可
使用# undef命令

4. 宏定义用双引号括起来的都是常量字符串 例如“PI” 则打印PI

5. 宏定义允许嵌套, 在宏定义的字符串中,可以使用已定义的宏名。在宏展开时由预处理程序层层代换。

6. 习惯上宏定义用大写字母表示, 以便区分

      #include <stdio.h>

      # define PI 3.1415
      # define S PI*r*r

      int main(int argc, char const *argv[]) {
        double s;
        int r;
        scanf("%d", &r);
        s = S;
        printf("%d\n", s);
        return 0;
      }

7. 可用宏定义表示数据类型, 是书写方便

# define INTEGER int 

8. 对“输出格式”作宏定义, 可以缩减书写麻烦

#include <stdio.h>

# define P printf
# define D "%d\n"

int main(int argc, char const *argv[])
{
    p(D, 1);

}

define 和typeof的区别

宏定义      只是简单的字符串代换, 是预处理完成的。
typedef    是在编译时处理的, 它不是作简单的代换, 而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。
typedef    相当于类型重命名

#include <stdio.h>

#define  PIN1 char*
typedef char* PIN2;

int main(int argc, char const *argv[]) {

  PIN1 x, y; // char* x, y;也就是   char *x, y
  PIN2 a, b; // char* a, b;   char *a, *b;
  printf("%d %d\n", sizeof(x), sizeof(y));
  printf("%d %d\n", sizeof(a), sizeof(b));
  //结果:
  // 8 1
  //8  8
}

带参数宏定义

c语言允许宏带有参数, 在宏定义中的参数成为形式参数, 在宏调用中的参数成为实际参数。

对带参数的红,在调用中, 不仅要展开,而且要用实参去代替形参

带参宏定义的一般形式为:

# define 宏名(形参表) 字符串带参宏调用的一般形式为: 宏名(实参表)

例如:

	#define M(y) y*y+3*y /*宏定义*/

	。。
	k=M(5);   /*宏调用*/
	相当于k = 5*5 + 3*5  会直接替换,没有预处理的过程

  

看例子

#include <stdio.h>

#define MAX(a, b) (a, b)?a:b

int main(int argc, char const *argv[])
{
    int x, y, max;

    scanf("%d %d", &x, &y);
    max = MAX(x, y);
    printf("%d\n", max);
    return 0;
}

注意:

首先win编程里面都是宏定义

1. 带参宏定义中,宏名和形参表之间不能有空格出现
例如:

正确:
#define MAX(a, b) (a>b)?a:b
错误:
#define MAX (a, b) (a>b)?a:b

2. 在带参宏定义中,形式参数不分配内存单元, 因此不必作类型定义。
而宏调用中的实参有具体的值。要用他们去代换形参, 因此必须作类型说明

3. 在宏定义中的形参是标识符, 而宏调用中的实参可以是表达式

4. 在宏定义中, 字符串内的形参通常要用括号括起来以避免出错。
例如 # define M(y) (y)^(y)表达式的y都用括号括起来, 因此结果是正确的。
如果去掉括号, 把程序改成一下形式,那么程序的结果不是你想要的结果

注意:

#define S(y) (y)*(y)

.....
sq = 160 / S(3) //等于160 / (y)*(y)
需要更改成 #define S(y) ((y)*(y))

5. 带参宏和带参函数很相似, 但有本质上的不同, 除上面已谈到的各点外,
把同一表达式用函数处理与用宏处理两者的结果有可能是不同的。

稍等例子,明天测试

6. 宏定义也可以定义多个语句, 在宏调用时, 把这些语句又代换到源程序内
#include <string.h>
# define S(s1, s2) strcat(s1, s2) //strcat 类似连接,或合并

宏定义的if

条件编译三种形式:
1. #ifdef 标识符
    程序段1
  #else
    程序段2
  #endif

2. #ifndef 标识符
    程序段1
  #else
    程序段2
  #endif

3.#if 常量表达式
    程序段1
  #else
    程序段2
  #endif

时间: 2024-10-22 21:44:02

c 预处理的宏定义的相关文章

《黑马程序员》预处理指令(宏定义、条件编译、文件包含)(C语言)

宏定义的基本概念 ●  预处理指令都是以#开头 ●  预处理指令分为三种 1.宏定义 定义格式:#define  宏名   参数 2.条件编译 #if 条件语句     statement1; #elif 条件语句     statement2; #else     statement3; #endif       //条件编译结束必须加上此条语句,否则statement3以下的所有语句都将默认为不编译 3.文件包含 ●  预处理指令在代码翻译成0和1之前进行 ●  预处理指令的位置是可以写的

预处理指令--宏定义

预处理指令简介 •C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 •为了区分预处理指令和一般的C语句,所有预处理指令都以符号“#”开头,并且结尾不用分号 •预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾.习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件 •C语言提供的预处理指令主要有:宏定义.文件包含.条

C++面试常见问题——01预处理与宏定义

C++面试常见问题--------01预编译和宏的使用 C++预处理器 预处理器是一些指令,它将指示编译器在实际编译之前需要完成的预处理.预处理必须要在对程序进行词法与语义分析.代码生成与优化等通常的编译过程之前进行,经过预处理的程序不再包含之前的预处理命令. 所有的预处理器指令都以#号开始,并且前面不可以出现除了空白字符以外的字符.预处理器指令不是C++指令,所以不需要以 :结尾.所有的C++程序实例都有预处理器指令 #include,这个宏用于把头文件包含在源文件中. 预处理器指令是C++统

VC中预处理指令与宏定义详解

刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个经典的例子 使用预处理与宏定义最经典的例子莫过于加在一个头文件中以避免头文件被两次编译.试想这种的情况,有一个文件headerfile.h 它被包含在headerfile1.h中,同时在headerfile2.h 中也被包含了,现在有一个CPP文件,implement.cpp 包含了headerfi

unity平台的预处理(宏的定义)

在unity的跨平台中,我们常常会在各个平台游走,如安卓版,苹果版,PC版.在不同的平台上,我们要做不同的操作.然而我们可以使用unity的自带的宏定义来做平台的判断.Unity帮我们定义了例如以下平台预处理.(还有一些版本号的宏定义,这里没有写出来.) 我们使用#if #elif #endif进行宏命令的判断,unity会自己判断哪些条件成立,然后执行指定的代码.例子如下: 此外,我们还可以自己对宏命令进行定义:在edit-project settings-player中的设定栏可以添加属于自

黑马程序员----预处理指令(宏定义、条件编译、文件包含)

预处理指令共有三种: 宏定义: 条件编译: 文件包含: 一.预处理指令的执行时刻: 在代码翻译成0和1之前 二.预处理指令的特点: 1.预处理指令都是以#号开头: 2.预处理指令的位置可以随便写的: 3.预处理指令的作用域:从编写指令的哪一行代码开始,一直到文件结尾,或者遇到相应的#undef.... 三.宏定义(#define) 1.不带参数的宏定义: 例: #define COUNT 4      //  注意:这里没有分号 ....... #undef COUNT 注意: 1.宏名一般用大

预处理命令(宏定义,条件编译,头文件)

宏定义 <1>不带参数宏定义:#define PI 3.1415926 <2>带参数的宏定义: #define PI  3.1415926 #define S(r)  (PI*(r)*(r)) void main(){float  a=2,area;area=S(a); } 用宏可以得到几个结果: #define CIRCLE(R,L,S,V)  L=2*PI*(R);S=PI*(R)*(R);V=4.0/3.0*PI*(R)*(R)*(R) void main(){float r

C语言 预处理二(宏定义--#define)

//#define 宏定义(宏定义一般大写) //知识点一-->#define的作用域:从#define开始,从上往下,如果遇到#undef就到#undef处结束,如果没有就是作用于当前整个文件 #include<stdio.h> #include<stdlib.h> //知识点二-->宏定义作用 //宏定义作用1:起到替换作用,可以定义常量 #define X 10 //宏定义作用2:替换代码的任意部分(一般用于易语言,或者加密代码) #define 水乃万物之源 m

C 语言 之 预处理-------- 宏定义

1 概述 使用过以"#"号开头的预处理命令.如包含命令# include,宏定义命令# define等.在源程序中这些命令都放在函数之外, 而且一般都放在源文件的前面,它们称为预处理部分. 所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作.预处理是C语言的一个重要功能, 它由预处理程序负责完成.当对一个源文件进行编译时, 系统将自动引用预处理程序对源程序中的预处理部分作处理, 处理完毕自动进入对源程序的编译. C语言提供了多种预处理功能,如宏定义.文件包含. 条