回 帖 发 新 帖 刷新版面

主题:请问高手,谢谢

#define TRAN_GLOBALS

这句代码把TRAN_GLOBALS定义成什么呢?谢谢

回复列表 (共14个回复)

沙发

什么都没定义成。
这样的定义只起编译开关作用。
头文件中经常用这种方式,用以防止文件被重复包含导致编译出错。
例如:

//a.h
#ifndef _A_H
#define _A_H
#include "b.h"
a的其他内容
#endif//_A_H

//b.h
#ifndef _B_H
#define _B_H
#include "a.h"//注意这里!!!!!
b的其他内容
#endif//_B_H

如果没有那种开关语句,是不是将进入循环编译两个文件的状态?
原本两个文件的语法都没有错误,可是却通不过编译,你会头疼吗?
这个开关语句就是止痛丸。

当然了,这类语句还有其他作用,你暂且了解这些吧,以后你学的多了,自然就明白了。

Good luck!

板凳

哦,原来是这样,谢谢啊

3 楼

请问斑竹
在vc中要定义一个派生类头文件中vc会生成这样的宏什么意示??
#if !defined(AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_)
#define AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class a:publuc b
{
};
#endif // !defined(AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_)


多谢啦!!


4 楼

#if !defined(AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_)
//===>相当于
//#ifndef(AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_)
#define AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_)
……
#endif // !defined(AFX_DDDD_H__509F5B29_F883_48F7_9757_5C9BAFD2E0BE__INCLUDED_)
那个宏只不过名字很长而已,,让你感觉似乎有什么名堂。
自己完全可以把它写成上面的样子,比如_DDDD_H,一般情况不会有错。
其实这个名字的生成过程由一定的算法作背景,这样生成的宏名能保证全球唯一。
至于具体算法是什么,我也不知道,你只有问高手或者问Microsoft了,你知道结果后还请你不要忘了高诉我哦。

5 楼

请教大虾
//a.h
#ifndef _A_H
#define _A_H
#include "b.h"
a的其他内容
#endif//_A_H

//b.h
#ifndef _B_H
#define _B_H
#include "a.h"//注意这里!!!!!
b的其他内容
#endif//_B_H

A.上面宏中#define _B_H 在什么时候是关闭的??
B.当编译器编译下面宏时b.h应该被编译吧
#ifndef _A_H
#define _A_H
#include "b.h"
a的其他内容
#endif//_A_H
结束以后编译下面文件时哪a,h还编译不???如果编的话,如何解决循环编译???
//b.h
#ifndef _B_H
#define _B_H
#include "a.h"//注意这里!!!!!
b的其他内容
#endif//_B_H


问题有点幼稚望大虾能帮我解惑,谢谢!!!



6 楼

很早以前我对你提的这个问题作过回答,现在找不到在哪里了。
现在只好再把这个问题重新解释一下了。
先回答你这个问题:
A.上面宏中#define _B_H 在什么时候是关闭的??
你什么时候听说过一个宏定义非要关闭?又不是#if,#ifdef等需要#endif做宏定义结束标志。
关于B:
上面的一堆
#ifndef AA_H
#define AA_H
……
#endif
就是为了解决循环编译的问题的。
否则要它干吗?

B.当编译器编译下面宏时b.h应该被编译吧
============
答:然也。
============
#ifndef _A_H
#define _A_H
#include "b.h"
a的其他内容
#endif//_A_H
结束以后编译下面文件时哪a,h还编译不???
====================
答:否。
====================
如果编的话,如何解决循环编译???
=================================
答:前提不成立。
=================================
//b.h
#ifndef _B_H
#define _B_H
#include "a.h"//注意这里!!!!!
===================================
答:我不用注意!
===================================
b的其他内容
#endif//_B_H
======================================================
======================================================
下面给你简单的解释为什么不会出现第二次编译a.h.
第一次编译a.h的时候,
#ifndef _A_H
条件成立,
因此,
#define _A_H
宏定义生效
接下来的
#include "b.h"
将被编译,
此时编译进程进入b.h
b.h中:
----------------------------------
#ifndef _B_H
#define _B_H
上面两行同上述过程
#include "a.h"
到这里时编译进程将回到a.h
但是
a.h的
#ifndef _A_H
已经不满足了,
(这里需要强调的是,在同一个编译过程中,宏定义全局有效)
因此,a.h不会被重复编译。
直到b.h编译完毕后,才返回第一次编译a.h的过程,接下来将编译
#include "b.h"
下面的代码,这时直到#endif前的代码也都通过编译。
a.h编译完毕后两个头文件其实都已经被编译完毕。

假设有一个实现文件main.c,它的开头两行是
#include "a.h"
#include "b.h"
那么,当编译到#include "a.h"时,就进入上面的整个编译过程。
当#include "a.h"的编译过程返回后,#include "b.h"实际上不会再真正编译b.h了。
因此,不会出现循环编译任何文件的情况。
所以常见于头文件(*.h)中类似于
#ifndef AAA
#define AAA
……
#enif
或者
#if !defined AAA
#define AAA
……
#enif
的情况起到了编译开关的作用。
如果头文件中没有上面的情况,而只有
#define AAA
这样一行,
那么也有相关的办法处理,就是这样,
在#include "aaa.h"处添加附加代码,如下便可以:
#ifndef AAA
#include "aaa.h"
#endif
照样可以避免重复包含头文件。

这里面有几个习惯的规则,就是宏名一般跟头文件名相关,这样能使包含方容易确定用哪个宏开关。
比如:
头文件abc.h中一般这样定义:
#define AAA_H
或者
#define _AAA_H
或者
#define _AAA_H_
包含时就可以用对应的开关了。




7 楼

非常清晰,完全明白啦谢谢,谢谢
我遐想编译器是不是这样
#define _a_h 0
int  N_a_h;
N_a_h=_a_h;

如编译后N_a_h=N_a_h-1;
哪么编译器每次在编译_a_h时检查N_a_h是否非零
非零就不编译
这是本人的瞎想

在这里还得再一次感谢斑竹又问必答的敬业精神

8 楼

上面的绝对是“遐想”。
#define AA
的时候跟数字根本无关!
更不会存在什么数学运算!

9 楼

说的好知识吗要求精和准不能相当然
有问题请教斑竹
在vc中要定义一个派生类头文件中vc会生成这样的宏什么意示??
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
谢谢

10 楼

这个问题不清楚。
主要是对 _MSC_VER 宏的意义还有progma once这两个的意义没弄明白,不敢枉下断言。

我来回复

您尚未登录,请登录后再回复。点此登录或注册