码迷,mamicode.com
首页 > 其他好文 > 详细

008-预处理

时间:2015-06-04 22:19:29      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

预处理
 1、宏定义

 2、条件编译

 3、文件包含

注意:

  1、所有预处理都是以#开头,并且结尾不用分号.

  2、宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误

  3、作用域也是从定义到代码块结束

  4、定义一个宏时可以引用已经定义的宏名

  5、在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查


一、宏定义
  1、不带参数的宏定义

  #define 宏名 字符串

  #define COUNT 6  

  2、带参数的宏定义

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

  #define sum(va,vb) ((va)+(vb))

  注意:每个参数都要加括号,运算结果也要加括号

若需要提前取消宏定义可用 #undef COUNT实现。

     代码示例:

1 //宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
 2 //1、宏定义1,不带参数的宏定义,常用来定义常量
 3 #define COUNT 6//后面么有‘;‘
 4 
 5 #include <stdio.h>
 6 //1、宏定义2,带参数的宏定义,每个参数都要加括号,运算结果也要加括号
 7 #define sum(v1,v2) ((v1)+(v2))
 8 
 9 
10 int main()
11 {
12     //1、宏定义使用
13     int array[COUNT] = {1,2,3,4,5,6};
14     for (int i = 0; i < COUNT; i++)
15     {
16         printf("%d ",array[i]);
17     }
18 #undef COUNT    //提前取消宏定义
19     //带参数的宏
20     printf("\n%d\n",sum(10,20));
21     printf("%d\n",sum(3,3)*sum(4,4));//这样实际运行效果是3+3*4+4=19,因为宏只是简单的文本替换,所以定义时加()比较好
22 
23     //2、条件编译
24     
25     
26     return 0;
27 }

二、条件编译

满足条件就对代码进行编译,否则不编译。

#if 条件1

 .....

#elif 条件

  ......

#else

  .....

#endif//不可缺少

1 #define COUNT 6//后面么有‘;‘
2   //2、条件编译,一般判断宏的值,不能对变量进行操作
3 #if(COUNT  == 6)
4     printf("条件编译:%d\n",COUNT);
5 #elif (COUNT  == 4)
6     
7 #else
8     
9 #endif//不可缺少

#if defined()和#if !defined()的使用
#if defined(COUNT)//COUNT是一个宏,如果定义这个宏就执行下面的代码
...code...
#endif
#if !defined(COUNT)//COUNT是一个宏,如果没有定义这个宏就执行下面的代码
...code...
#endif
代码:

1 //#if defined()和#if !defined()的用法
2 #if defined (COUNT)//如果定义宏就编译下面代码,否则不编译
3     printf("defined:%d\n",COUNT);
4 #endif
5     
6 #if !defined (COUNT1)//如果定义宏就编译下面代码,否则不编译
7     printf("! defined\n");
8 #endif

#ifdef和#ifndef的使用
#ifdef COUNT//COUNT是一个宏,如果定义这个宏就编译下面的代码
...code...
#endif

#ifndef COUNT//COUNT是一个宏,如果没有定义这个宏就编译下面的代码
...code...
#endif
代码:

1 //#ifdef和#ifndef的使用
2 #ifdef COUNT//如果定义宏就编译下面代码,否则不编译
3      printf("ifdef:%d\n",COUNT);
4 #endif
5  
6 #ifndef COUNT1//如果定义宏就编译下面代码,否则不编译
7     printf("ifndef\n");
8 #endif

三、文件包含
#include

#include <>//系统头文件

#include ""//自定义的头文件

文件包含可能会重复包含同一个文件,这是可以再要包含的文件中添加一个宏定义,用于消除重复包含。

格式如下  

  #ifndef A_H

  #def A_H

    ..........

  #endif

这样即使多次#include同一个头文件也不会产生文件的重复性包含

四、typedef 
 typedef的用法:

   1、为各种数据类型定义一个新名字(别名)

   2、typedef与指针

   3、typedef与结构体

   4、typedef与指向结构体的指针

   5、typedef与枚举类型

   6、typedef与指向函数的指针

   7、typedef与#define

代码示例

1 #include <stdio.h>
 2 /*
 3  typedef的用法:
 4  1、为各种数据类型定义一个新名字(别名)
 5  2、typedef与指针
 6  3、typedef与结构体
 7  4、typedef与指向结构体的指针
 8  5、typedef与枚举类型
 9  6、typedef与指向函数的指针
10  7、typedef与#define
11 */
12 
13 //3、typedef与结构体
14 struct Point
15 {
16     int x;
17     int y;
18 };
19 
20 //也可以直接在定义时使用typedef
21 typedef struct Point1{}point1;
22 
23 //起别名,下面可以直接使用,而不用每次都写struct
24 typedef struct Point MyPoint;
25 
26 //自定义结构体指针,起别名
27 typedef MyPoint *pp;
28 
29 
30 
31 // 5、typedef与枚举类型
32 enum Sex{male,female,notSure};
33 typedef enum Sex Sex;//起别名
34 
35 // 6、typedef与指向函数的指针
36 int Sum(int a,int b)
37 {
38     int c = a + b;
39     printf("%d + %d = %d\n",a,b,c);
40     return c;
41 }
42 
43 
44 
45 int main()
46 {
47     //1、为各种数据类型定义一个新名字(别名)
48     typedef int Integer;
49     
50     Integer i = 10;
51     printf("%d\n",i);
52     
53     //1、typedef与指针
54     typedef char *String;
55     String name = "this is a typedef struct";
56     printf("%s\n",name);
57     
58     //3、typedef与结构体
59     MyPoint p1;
60     p1.x = 1;
61     p1.y = 2;
62     printf("%d,%d\n",p1.x,p1.y);
63     
64     //4、typedef与指向结构体的指针
65     pp p = &p1;
66     p->x = 10;
67     p->y = 20;
68     printf("%d,%d\n",p->x,p->y);
69 
70     // 5、typedef与枚举类型
71     Sex s1 = male;//使用别名进行变量声明,不用带关键字enum
72     printf("%d\n",s1);
73     
74     // 6、typedef与指向函数的指针
75     //普通函数指针使用方式
76     int (*pSum)(int ,int );//普通函数指针定义
77     pSum = &Sum;
78     (*pSum)(19,20);
79     
80     typedef int (*pS)(int ,int );//使用typedef给函数指针起别名
81     pS ps = &Sum;//这个使用方式和上面有些差别
82     (*ps)(19,20);
83     
84     //7、typedef与#define
85 #define String1 char*
86     typedef char* String2;
87     String1 str1,str2;//宏替换 char* str1,str2;//str2只是一个字符变量,不是指针变量
88     String2 str3,str4; //但是这个是这样,char *str3;char * str4;
89   
90     return 0;
91 }

static和extern
static和extern与函数

  关于函数:

  外部函数:如果在当前文件中定义的函数允许其他文件访问、调用,就称为外部函数。C语言规定,不允许有同名的外部函数。

  内部函数:如果在当前文件中定义的函数不允许其他文件访问、调用,只能在内部使用,就称为内部函数。C语言规定不同的源文件可以有同名的内部函数,并且互不干扰。

 

one.h

//one.h

#include "one.c"

extern void one();
void anotherOne();

one.c

1 //one.c
 2 
 3 
 4 #include <stdio.h>
 5 
 6 extern void one()//默认就是extern函数,不写效果一样。外部函数
 7 {
 8     printf("one is called!\n");
 9 }
10 static void anotherOne()//只能在one.c中使用。内部函数
11 {
12     printf("anotherOne is called!\n");
13 }

主函数

1 #include <stdio.h>
 2 //#include "one.h"
 3 /*
 4  extern与static
 5  1、extern与函数==外部函数
 6  2、static与函数==内部函数
 7  */
 8 
 9 //1、extern与函数
10 //#include "one.c"//这样引用会提示重复定义one
11 //extern void one();//可以这样进行外部声明,但是extern可以省略,所以可以直接写成 void one();
12     //实际情况下一般把声明写道头文件里,直接包含头文件,可以直接使用里面的函数
13 // 2、static与函数
14     //只能再定义的文件内使用,无法被外部文件引用
15 
16 void anotherOne();//引用声明
17 
18 int main()
19 {  
20     one();
21     anotherOne(); 
22     return 0;
23 }

static和extern与全局变量

1、全局变量可以重复定义,只要变量名一样,指的都是一个变量,在多个文件中也是如此。

  int b1;

  int b1;

  int b1;

2、如果变量的定义在下面,但是又想提前使用就需extern声明

  extern int a;

3、在函数内部也可以通过extern int a;使用全局变量a,以区别同名的局部变量

4、全局静态变量,只能在本文件内部使用

1 #include <stdio.h>
 2 //3、全局变量和static
 3 static int b;//全局静态变量,只能在本文件内部使用
 4 //全局变量可以重复定义,只要变量名一样,指的都是一个变量,在多个文件中也是如此。
 5 int b1;
 6 int b1;
 7 int b1;
 8 // 4、全局变量和extern
 9 extern int a;//a的定义在下面或者在其他文件里,如果想提前使用就需extern声明
10 
11 int main()
12 {
13     {
14         //在函数内部访问同名全局变量1
15         extern int b1;
16         b1 = 12;
17     }
18      //在函数内部访问同名全局变量2
19     int *p = &b1;
20     
21     int b1;
22     b1 = 20;
23       
24     
25     return 0;
26 }
27 
28 int a;

 

008-预处理

标签:

原文地址:http://www.cnblogs.com/lqsuperman/p/4552951.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!