zoukankan      html  css  js  c++  java
  • #ifndef#define#endif的用法

    #ifndef 标示1 //判断"标示1"是否定义,如果被定义则返回假,如果没有被定义则返回真

      /**********************************/

      语句1 #ifndef 标示1

        语句2 #define 标示1

      语句3 #endif

      语句4 ……

      语句5 ……

    该段代码意思是:如果标示1没有被定义,则重定义标示1,即执行语句2、语句3、语句4、……;如果标示1已经被定义,则直接跳过语句2、语句3,直接执行语句4、语句5、……

    备注:#ifndef 和 #endif 要一起使用,如果丢失#endif,可能会报错。

      千万不要忽略了头文件中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

      还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:

      #ifndef <标识>

        #define <标识>

        ......

        ......

      #endif

      <标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

      #ifndef _STDIO_H_

      #define _STDIO_H_

      ......

      #endif

    一般是用来防止重复包含头文件第一次包含头文件时 XXX没有被定义 第二次再用时 XXX 已经被定义拉就不在包含这个头文件。

    深入:条件编译

           预处理程序提供了条件编译的功能。 可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。 条件编译有三种形式,下面分别介绍:

       1. 第一种形式: 

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

                 它的功能是,如果标识符已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else可以没有,即可以写为: 
                 #ifdef 标识符 
                   程序段

                 #endif 

     举例如下:
           #define NUM ok
           void  main()
    
           {
                 struct stu
                 {
                       int num;
                       char *name;
                       char sex;
                       float score;
                 } *ps;
                 ps=(struct stu*)malloc(sizeof(struct stu));
                 ps->num=102;
                 ps->name="Zhang ping";
                 ps->sex='M';
                 ps->score=62.5;
                 #ifdef NUM
                       printf("Number=%d\nScore=%f\n",ps->num,ps->score);
                 #else
                       printf("Name=%s\nSex=%c\n",ps->name,ps->sex);
                 #endif
                 free(ps);
           }  

            由于在程序的第16行插入了条件编译预处理命令,因此要根据NUM是否被定义过来决定编译那一个printf语句。而在程序的第一行已对NUM作过宏定义,因此应对第一个printf语句作编译故运行结果是输出了学号和成绩。在程序的第一行宏定义中,定义NUM表示字符串OK,其实也可以为任何字符串,甚至不给出任何字符串,写为: #define NUM 也具有同样的意义。 只有取消程序的第一行才会去编译第二个printf语句。读者可上机试作。
                  2. 第二种形式: 
                  #ifndef 标识符 
                    程序段1 
                  #else 
                    程序段2 
                  #endif  
                  与第一种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。这与第一种形式的功能正相反。 
                  3. 第三种形式: 
                  #if 常量表达式 
                    程序段1 
                  #else 
                    程序段2 
                  #endif  
                  它的功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能
                  举例如下:
           #define R 1
           void  main()

           {
                 float c,r,s;
                 printf ("input a number: ");
                 scanf("%f",&c);
                 #if R
                 r=3.14159*c*c;
                 printf("area of round is: %f\n",r);
                 #else
                 s=c*c;
                 printf("area of square is: %f\n",s);
                 #endif
           } 
            本例中采用了第三种形式的条件编译。在程序第一行宏定义中,定义R为1,因此在条件编译时,常量表达式的值为真,故计算并输出圆面积。上面介绍的条件编译当然也可以用条件语句来实现。但是用条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目标程序较短。如果条件选择的程序段很长, 采用条件编译的方法是十分必要的。

      单片机项目中,可能包含多个.C文件和.h文件,其中变量的定义最好放在.c文件中,其中在其他.c文件中引用此变量,就必须使用extern+变量,即可。

  • 相关阅读:
    Leetcode: Word Ladder II
    Leetcode: Triangle
    Leetcode: Best Time to Buy and Sell Stock II
    Leetcode: Best Time to Buy and Sell Stock
    Leetcode: Pascal's Triangle II
    Leetcode: Pascal's Triangle
    Leetcode: Path Sum II
    Leetcode: Convert Sorted Array to Binary Search Tree
    Leetcode: Merge Sorted Array
    Leetcode: Word Search
  • 原文地址:https://www.cnblogs.com/wangh0802PositiveANDupward/p/2595678.html
Copyright © 2011-2022 走看看