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\n",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\n",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\n"
#define F "%f\n"

#define INT1 int *
typedef int* PINT;  //typedef要加分号

struct Car{

    int lunzi;
};

void test(){
    printf("%f\n",ZC);
}
//取消宏定义
#undef ZC

void test2(){

    //printf("%f\n",ZC);

}
int main(int argc, const char * argv[])
{
    //1、宏的基本用法
    printf("%d,%d\n",COLS,ROWS);

    //2、宏出现在字符串中
    char *str="Hello world!,COlS\n";
    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\n",s);   //284

    //4、使用的宏,其中又包含了其他的宏
    test();

    //5、用宏可以定义新的变量
    //int a
    INT a;
    a = 10;
    printf("a = %d\n",a);

    //struct Car car1={4};
    CAR car1 ={4};
    printf("lunzi  = %d\n",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\n");

}

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

    Log("xxxxx\n");
    return 0;
}

四:static 和extern的区别

一   extern对函数的作用
1> 完整的定义一个外部函数
2> 完整的声明一个外部函数
    (默认情况下函数都是外部函数所有extern可以省略)

static对函数的作用
1> 完整的定义一个内部函数
2> 完整的声明一个内部函数

二   static对全局变量的作用
static修饰的全局变量是内部变量  ,只能被本文件使用

三  static对局部变量的作用
而static修饰的局部变量会延长局部变量的生命周期,程序结束才会销毁,同时局部变量的作用域不会改变

四   static性能问题
static修饰的局部变量延长了它的生命周期,因此当一个函数被不断调用的话,其内部的局部常量内存中不会被不断分配销毁五:static修饰的局部变量或全局变量在初始化前存在bss段,初始化后存放在数据段,
时间: 2024-11-16 21:24:52

c语言预处理指令、typedef、static和extern相关介绍的相关文章

黑马程序员————C语言(预处理指令、static与extern、typedef)

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 第一讲  预处理指令 预处理指令的概述 C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释,比如之前使用的#include文件包含指令,产生一个新的源程序,这个过程称为编译预处理,之后再进行通常的编译 为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号 预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾.习惯上我们尽

黑马程序员--C语言--预处理指令、枚举、Typedef、递归函数、变量作用域

一.预处理指令 1>所有的预处理指令都是以#号开头; 2>预处理指令是在代码翻译成0,1之前执行: 3>预处理指令最后没有分号: 4>预处理指令的位置可以随便写: 5>预处理指令有作用域,从编写指令的那一行开始,一直到文件结尾,可以用#undef取消宏定义的作用: 预处理指令分3种 1> 宏定义 2> 条件编译 3> 文件包含 二.宏定义 1. 宏定义命名规则: 1>大写字母 1 #define COUNT 2>k开头首字母大写 #define 

17-C语言预处理指令3-文件包含

说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略 这讲介绍最后一个预处理指令---文件包含 一.基本概念 其实我们早就有接触文件包含这个指令了, 就是#include,它可以将一个文件的全部内容拷贝另一个文件中. 二.一般形式 1.第1种形式#include <文件名> 直接到C语言库函数头文件所在的目录中寻找文件 2.第2种形式 #include "文件名&quo

15-C语言预处理指令1-宏定义

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

typedef , static和 extern

typedef 1.作用:给已经存在的类型起一个新的名称 2.使用场合: 1> 基本数据类型 2> 指针 3> 结构体 4> 枚举 5> 指向函数的指针 #include <stdio.h> typedef int MyInt; typedef MyInt MyInt2; // 给指针类型char *起一个新的类型名称String typedef char * String; /* struct Student { int age; }; typedef stru

16-C语言预处理指令2-条件编译

条件编译的概念 在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译. 一.基本用法 #if 条件1 ...code1... #elif 条件2 ...code2... #else ...code3... #endif 1> 如果条件1成立,那么编译器就会把#if 与 #elif之间的code1代码编译进去(注意:是编译进去,不是执行,很平时用的if-else是不一样的)2> 如果条件1不成立.条件2成立,

c/c++中static与extern关键字介绍

一.C语言中的static关键字 在C语言中,static可以用来修饰局部变量,全局变量以及函数.在不同的情况下static的作用不尽相同. (1)修饰局部变量 一般情况下,对于局部变量是存放在栈区的,并且局部变量的生命周期在该语句块执行结束时便结束了.但是如果用static进行修饰的话,该变量便存放在静态数据区,其生命周期一直持续到整个程序执行结束.但是在这里要注意的是,虽然用static对局部变量进行修饰过后,其生命周期以及存储空间发生了变化,但是其作用域并没有改变,其仍然是一个局部变量,作

黑马程序员— C语言基础之结构体、枚举、预处理、typedef的使用

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 本章我们主要来学习之前所学的复杂数据类型中的同样也很重要的结构体和枚举的知识,以及C语言中的预处理,typedef的使用,简单介绍一下static和extern等一些比较杂的知识.在开始本章的新知识学习之前首先我们来学习一下根据变量的作用域的不同C语言一般把变量分为两种,局部变量和全局变量.下面我们来分别比较和体会一下这两种不同的变量类型: 根据变量的作用域,可以分为: 1. 局部变量: a.

预处理指令、typedef、static和extern

1.预处理指令 C编译器在对源程序进行编译之前,会进行编译预处理.这一步骤由C预处理器(C Preprocessor)完成.所有的预处理器命令都以#开头.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到取消它的预处理出现位置或文件末尾. 指令 描述 #define 定义一个预处理宏 #undef 取消宏定义 #ifdef 判断某个宏是否已定义,若已定义,则执行后续语句 #ifndef 判断某个宏是否未定义,若未定义,则执行后续语句 #if 条件判断,同C语句中的if #elif