当前位置: 技术问答>linux和unix
有关C语言的问题。
来源: 互联网 发布时间:2014-12-01
本文导语: 刚开始打算看linux的源码,可是c语言基础有限,有很多问题,不很清楚。下面是一个有关linux宏定义的问题。 宏定义如果如果有参数其有点很容易理解,但像下面开始这样的宏定义又有什么意义呢?联系上下看看,似...
刚开始打算看linux的源码,可是c语言基础有限,有很多问题,不很清楚。下面是一个有关linux宏定义的问题。
宏定义如果如果有参数其有点很容易理解,但像下面开始这样的宏定义又有什么意义呢?联系上下看看,似乎是与条件编译有关,可是要怎么理解呢?这种定义一般怎么使用?我的这点c语言基础实在无法理解,希望那位朋友能帮忙解答一些,谢谢!
下面只是一个例子,在内核的源码里面还有很多这种应用,先谢谢了!!
100分送上!
___________
include/asm-i386/boot.h linux2.5.10内核
______________________
#ifndef _LINUX_BOOT_H
#define _LINUX_BOOT_H
/* Don't touch these, unless you really know what you're doing. */
#define DEF_INITSEG 0x9000
#define DEF_SYSSEG 0x1000
#define DEF_SETUPSEG 0x9020
#define DEF_SYSSIZE 0x7F00
/* Internal svga startup constants */
#define NORMAL_VGA 0xffff /* 80x25 mode */
#define EXTENDED_VGA 0xfffe /* 80x50 mode */
#define ASK_VGA 0xfffd /* ask for it at bootup */
#endif
宏定义如果如果有参数其有点很容易理解,但像下面开始这样的宏定义又有什么意义呢?联系上下看看,似乎是与条件编译有关,可是要怎么理解呢?这种定义一般怎么使用?我的这点c语言基础实在无法理解,希望那位朋友能帮忙解答一些,谢谢!
下面只是一个例子,在内核的源码里面还有很多这种应用,先谢谢了!!
100分送上!
___________
include/asm-i386/boot.h linux2.5.10内核
______________________
#ifndef _LINUX_BOOT_H
#define _LINUX_BOOT_H
/* Don't touch these, unless you really know what you're doing. */
#define DEF_INITSEG 0x9000
#define DEF_SYSSEG 0x1000
#define DEF_SETUPSEG 0x9020
#define DEF_SYSSIZE 0x7F00
/* Internal svga startup constants */
#define NORMAL_VGA 0xffff /* 80x25 mode */
#define EXTENDED_VGA 0xfffe /* 80x50 mode */
#define ASK_VGA 0xfffd /* ask for it at bootup */
#endif
|
给你说个例子吧,看你挺认真学习的
假如这样:
--sample.h--
#ifndef SAMPLE_H
#define SAMPLE_H
#define MAX_VAL 254 //定义一个最大值
void ShowVal(); //声明这个函数
#endif
--sample.c--
#include "sample.h"
void ShowVal() { printf("Max Val = %dn",MAX_VAL);}
-- main.c --
#include "sample.h"
int main()
{
ShowVal();
printf("main VAL = %dn",MAX_VAL + 1);
return 0;
}
这样编译:gcc -o main main.c sample.c
你注意上面main.c和sample.c都#include "sample.h"了。现在gcc在这次编译中,要有两个.c文件编译。假如它先编译sample.c。sample.c第一次#include"sample.h",因为这时没有SAMPLE_H符号的定义,所以编译器就会执行#define SAMPLE_H这个预编译指令,定义一个SAMPLE_H符号。接着,sample.h中还有#define MAX_VAL 254,这时,编译器就知道,以后会用254这个值换掉所有后面见到的MAX_VAL.这样编译器必须也要记住MAX_VAL这个符号。
那,现在编译器又开始编译main.c了。因为在编译sample.c时,已经定义了SAMPLE_H,现在main.c里想去#include "sample.h"代码展开时,#ifndef SAMPLE_H条件不成立,所以sample.h的代码,实质上就没有包含到main.c单元中。但编译器这时已经知道了MAX_VAL 和ShowVal的意义。所以编译顺利通过。
如果你不用上面的预编译控制。那在编译main.c时,编译器又见到了#define MAX_VAL 254.这样就有重复定义了。
还好,两个.c都用一个头文件,那么MAX_VAL重复来重复去,还是254。那要是还有个地方定义了#define MAX_VAL 12 并且也被E#include 到main.c中。看你用哪个值?!
我够罗嗦了吧。要是有说错的地方,那要当是心情不好啦!
假如这样:
--sample.h--
#ifndef SAMPLE_H
#define SAMPLE_H
#define MAX_VAL 254 //定义一个最大值
void ShowVal(); //声明这个函数
#endif
--sample.c--
#include "sample.h"
void ShowVal() { printf("Max Val = %dn",MAX_VAL);}
-- main.c --
#include "sample.h"
int main()
{
ShowVal();
printf("main VAL = %dn",MAX_VAL + 1);
return 0;
}
这样编译:gcc -o main main.c sample.c
你注意上面main.c和sample.c都#include "sample.h"了。现在gcc在这次编译中,要有两个.c文件编译。假如它先编译sample.c。sample.c第一次#include"sample.h",因为这时没有SAMPLE_H符号的定义,所以编译器就会执行#define SAMPLE_H这个预编译指令,定义一个SAMPLE_H符号。接着,sample.h中还有#define MAX_VAL 254,这时,编译器就知道,以后会用254这个值换掉所有后面见到的MAX_VAL.这样编译器必须也要记住MAX_VAL这个符号。
那,现在编译器又开始编译main.c了。因为在编译sample.c时,已经定义了SAMPLE_H,现在main.c里想去#include "sample.h"代码展开时,#ifndef SAMPLE_H条件不成立,所以sample.h的代码,实质上就没有包含到main.c单元中。但编译器这时已经知道了MAX_VAL 和ShowVal的意义。所以编译顺利通过。
如果你不用上面的预编译控制。那在编译main.c时,编译器又见到了#define MAX_VAL 254.这样就有重复定义了。
还好,两个.c都用一个头文件,那么MAX_VAL重复来重复去,还是254。那要是还有个地方定义了#define MAX_VAL 12 并且也被E#include 到main.c中。看你用哪个值?!
我够罗嗦了吧。要是有说错的地方,那要当是心情不好啦!
|
#ifndef _LINUX_BOOT_H //如果没有定义_LINUX_BOOT_H则(编译下一行)
#define _LINUX_BOOT_H //定义_LINUX_BOOT_H
。。。
#endif //结束#if 判断 #endif和#if 是配对使用的
这样做的目的是避免头文件被重复包含
#define _LINUX_BOOT_H //定义_LINUX_BOOT_H
。。。
#endif //结束#if 判断 #endif和#if 是配对使用的
这样做的目的是避免头文件被重复包含
|
#define _LINUX_BOOT_H //定义_LINUX_BOOT_H
是为了避免宏和函数被重复声明,而不是真正要定义什么具体的内容
是为了避免宏和函数被重复声明,而不是真正要定义什么具体的内容