zoukankan      html  css  js  c++  java
  • c语言预处理指令、typedef、static和extern相关介绍

    一:typedef 

       作用:可以给一个已经存在的数据类型取一个别名

     格式:typedef 原数据类型  新类型   例如:typedef   int  INT;

     预处理指令#define 也可以给数据类型取别用用法:  #define  INT  int;

    //1、用在基本数据类型上
        int a = 10;
        typedef int TNT;
        typedef char CHAR;
        CHAR c='A';   //65
        TNT b = 100;
        
        //2、给数组起别名
        char ch[5];
        typedef char NAME[20];
        //用新的类型定义数组
        NAME a1,a2;  //char a1[20]  char a2[20]
        
        
        //3、用在结构体上
        //1)先定义结构,然后在定义新的类型
        struct iPhone iphone5;
        struct iPhone *p;
        
        typedef struct iPhone IPHONE;
        IPHONE iphone6;
        IPHONE *p1;
        
        
        //2)定义结构体的时候,重新定义为一个新的类型
        typedef  struct Car{
            int lunzi;
        }CAR;
        CAR car1;
        car1.lunzi = 80;
        printf("%d
    ",car1.lunzi);
        
        //3)给一个匿名的结构体定义一个新的类型
        typedef struct{
        
            char *head;
            int data;
            char *next;
        
        }NODE;
        
        NODE h;
        
        
        //4、用在枚举类型上
        //1)给一个枚举类型定义一个新的名称
        typedef enum weekday{
           one,
            two
        }WEEK;
        
        WEEK day;
        day = one;
        
        //2)给一个匿名的枚举类型,定义一个新的名称
        typedef enum {
            three,
            four
        }WEEK1;
        
        WEEK1 day2;
        day2 = three;
        
        //3)用一个已经存在的枚举类型,定义一个新的类型
        enum iColor{jin,bai,hei};
        enum iColor c1;
        typedef enum iColor ICOLOR;
        ICOLOR c2;
        c2 = jin;
        
        
        //5、给函数指针起别名
        int (*p8)(int a,int b);
        p8 = sum;
        int s1 = p8(56,23);
        
        
        typedef int (*ADD)(int a,int b);
        ADD p9;
        p9 = max;
        s1 = p9(34,88);
        
        printf("%d
    ",s1);
        
        gets(a2);
        puts(a2);

    二 :预处理指令 

        1)以 “#”开头

        2)在编译之前做的一些处理 

      1>#include   文件包含指令    

        1)#include  <系统头文件>

        2) #include  "自定义头文件"   

      作用:包含了系统或者用户自己定义的函数的声明,程序编译不会报错或警告,跟程序链接没有关系

      完成了函数声明的拷贝。OC中不用#include因为它的头文件比较繁琐,还需要写条件编译指令(未来防止头文件的重复拷贝)

      

      2>#define 宏定义

        1】无参的宏定义:   #define 宏名  字符串

      注意:

       1)宏定义,后面不用加分号

       2) 当宏出现在字符串中的时候,不进行替换

       3) 宏替换:在源程序中所有出现宏名的地方都替换成 宏定义的字符串

       4) 宏定义的时候,注意一般情况下为了区分它和变量,一般是大写(棕色)

       5)宏定义一般写到文件的开头,作用域从定义开始,到文件结束

          如果提前碰到了 #undef 则宏就被取消了,下面的函数不能在使用宏了

      

    #include <stdio.h>
    //无参数的宏
    #define COLS 5
    #define ROWS 10
    #define M 3*y+y*y
    #define PI 3.14
    #define ZC 2*PI*COLS
    
    #define INT int
    #define CAR struct Car
    
    #define P printf
    #define D "%d
    "
    #define F "%f
    "
    
    #define INT1 int *
    typedef int* PINT;  //typedef要加分号
    
    struct Car{
    
        int lunzi;
    };
    
    void test(){
        printf("%f
    ",ZC);
    }
    //取消宏定义
    #undef ZC
    
    void test2(){
    
        //printf("%f
    ",ZC);
    
    }
    int main(int argc, const char * argv[])
    {
        //1、宏的基本用法
        printf("%d,%d
    ",COLS,ROWS);
        
        //2、宏出现在字符串中
        char *str="Hello world!,COlS
    ";
        printf(str);
        
        //3、宏替换
        int y = 4;
        //         28*3    +       28*28         -28
        //  s = 3*y+y*y*3+3*y+y*y*3*y+y*y-3*y+y*y;
        int s=0;
        s = (3*y+y*y)*3+(3*y+y*y)*(3*y+y*y)-(3*y+y*y);  //840
        s = M*3+M*M-M;
        printf("%d
    ",s);   //284
        
        //4、使用的宏,其中又包含了其他的宏
        test();
        
        //5、用宏可以定义新的变量
        //int a
        INT a;
        a = 10;
        printf("a = %d
    ",a);
        
        //struct Car car1={4};
        CAR car1 ={4};
        printf("lunzi  = %d
    ",car1.lunzi);
        
        //6、可以妙用宏,简化输出的代码
        float f1 = 12.0f;
        P(D,a);
        P(F,f1);
        
        
        //7、关于typedef和#define的区别
        int c=2,d=5;
        
        //int *p,q;
        //p指针,q就是一个int型
        INT1 p,q;
        p = &c;
        q = &d;  //q是整型的
        
        //int *m;int *n;
        //int *m,*n;
        PINT m,n;
        m = &c;
        n = &d;

      2】有参的宏定义

      #define 宏名(形参列表) 字符串

         注意:

         1)在有参宏定义中,形参不需要指定类型

         2)多个参数使用逗号分隔

         3)有参宏定义的时候,注意宏名和括号之间不能有空格

     宏定义都是完成了替换工作,不参与运算

      3> 条件编译: 只编译满足条件的代码块条件编译:

        形式一:

        #if                 if

        #elif               else if

        #else               else

        #endif              }

        形式二:

        #ifdef M     //如果定义了  M 就编译语句块1,否则编译语句块2

            语句块1;

        #else

            语句块2;

        #endif

        形式三    

        #

    三:利用条件编译打印调试信息

    #include <stdio.h>
    #define DEBUG1 1   //0 程序上线,不能打印调试信息,1 开发模式
    
    #if DEBUG1==0
    //          format 表示这是一个参数      ..可以多个参数
    //                                    ##表示可以没有参数
    #define Log(format,...) printf(format,## __VA_ARGS__)
    #else
    #define Log(format,...)
    #endif
    
    void test(){
    
        int a=10;
        Log("ssssss
    ");
    
    }
    
    
    int main(int argc, const char * argv[])
    {
        test();
    
        Log("xxxxx
    ");
        return 0;
    }

    四:static 和extern的区别

    一   extern对函数的作用
    1> 完整的定义一个外部函数
    2> 完整的声明一个外部函数
        (默认情况下函数都是外部函数所有extern可以省略)
    
    static对函数的作用
    1> 完整的定义一个内部函数
    2> 完整的声明一个内部函数
    
    二   static对全局变量的作用
    static修饰的全局变量是内部变量  ,只能被本文件使用
    
    三  static对局部变量的作用
    而static修饰的局部变量会延长局部变量的生命周期,程序结束才会销毁,同时局部变量的作用域不会改变
    
    四   static性能问题
    static修饰的局部变量延长了它的生命周期,因此当一个函数被不断调用的话,其内部的局部常量内存中不会被不断分配销毁
    五:static修饰的局部变量或全局变量在初始化前存在bss段,初始化后存放在数据段,
  • 相关阅读:
    Beta冲刺
    Beta冲刺总结随笔
    用户使用调查报告
    Beta冲刺测试随笔
    WeChair项目Beta冲刺(10/10)
    WeChair项目Beta冲刺(9/10)
    WeChair项目Beta冲刺(8/10)
    WeChair项目Beta冲刺(7/10)
    WeChair项目Beta冲刺(6/10)
    WeChair项目Beta冲刺(5/10)
  • 原文地址:https://www.cnblogs.com/-boy/p/4052879.html
Copyright © 2011-2022 走看看