delphi {$I-} {$I+}是什么意思

如题所述

一个程序从无到有的过程是这样的: 编辑代码 -> 预处理 -> 编译(成dcu等) -> 链接(为exe等).

什么是预处理?

譬如 VCL 中有很多代码是兼容 Linux 的, 在 Windows 下就需要在编译之前预处理掉那些 for Linux 的代码.

1、判断操作系统:

其中的 "MSWINDOWS" 和 "LINUX" 就是 Delphi 预定义的 "条件标识符".

begin
{$IFDEF MSWINDOWS}
ShowMessage('Windows');
{$ENDIF}
{$IFDEF LINUX}
ShowMessage('Linux');
{$ENDIF}
end;

2、自定义条件标识符(DEFINE):

下面例子中自定义了条件标识符: WanYi; 标识符和定义它的指令都不区分大小写, 但大家一般惯用大写.

begin
{$DEFINE WANYI}
{$IFDEF WanYi}
ShowMessage('标识符 WanYi 已定义');
{$ELSE}
ShowMessage('标识符 WanYi 未定义');
{$ENDIF}
end;

3、取消条件标识符的定义(UNDEF):

begin
{$DEFINE WANYI}
{$IFDEF WANYI}
ShowMessage('确认标识符 WanYi 是否定义');
{$ENDIF}
{$UNDEF WANYI}
{$IFDEF WANYI}
ShowMessage('再次确认标识符 WanYi 是否定义');
{$ENDIF}
end;

4、取消定义的简单办法:

在 {$...} 的 $ 前面随便加点什么, 让它变成 "注释", 譬如: {.$}

begin
{.$DEFINE WANYI}
{$IFDEF WANYI}
ShowMessage('确认标识符 WanYi 是否定义');
{$ENDIF}
{.$UNDEF WANYI}
{$IFDEF WANYI}
ShowMessage('再次确认标识符 WanYi 是否定义');
{$ENDIF}
end;

5、调试编译指令时特别要注意的:

Delphi 有个常识: 如果单元代码没有改变, 相应的 dcu 不会重新生成!

因此, 为了有准确的调试结果, 执行前先用 Shift+F9 强制编译当前工程, 然后再 Run;

强制编译所有相关单元也可以, 方法: Project -> Build all project.

当然修改下代码也很方便, 譬如在代码中打个空格再退回来.

6、测试预定义的 Debug 和 Release:

当我们当新建一个工程, Delphi 默认的是调试(Debug)状态, 当我们发布软件时应该切换到发布(Release)状态.

两种状态下编译指令是有区别的, 在 Release 状态下发布的 dcu 或 exe 会更小、更优化.

Debug 和 Release 的切换方法:

进入 Project Manager -> Build Configurations, 在 Debug 或 Release 上双击, 或从右键 Activate.

下面的代码可以检测到这种改变, 不过要注意上面提到的 Shift+F9 或 Project -> Build all project.

begin
{$IFDEF DEBUG}
ShowMessage('调试模式');
{$ENDIF}
{$IFDEF RELEASE}
ShowMessage('发布模式');
{$ENDIF}
end;

7、编译指令写在哪?:

编译指令可以写在代码页的任何地方, 不过在代码的不同区域有时也会不同;

譬如: {$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 就只能写在工程文件里才有效.

{$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 分别表示窗口工程和控制台工程.

其中 {$APPTYPE GUI} 是默认的, 所以很少见到它.

它甚至可以嵌入到代码行当中, 譬如 ActnColorMaps 单元就有这么一句:

begin
SystemParametersInfo(SPI_GETFLATMENU, 0, {$IFNDEF CLR}@{$ENDIF}FlatMenus, 0);
end;

8、条件标识符的有效范围:

Delphi 预定义的条件标识符都是全局的, 我们用 {$DEFINE ...} 自定义的标识符都是局部的.

如何自定义全局的标识符呢?

Project -> Options... -> 选定 Delphi Compiler -> 点击 Conditional defines 右边小按钮 -> 添加.

不过这和系统预定义的还是有区别, 咱们自定义的只能用于当前文件.

如何定义每个文件都可以使用的标识符呢?

从 Project -> Options... 定义后, 马上选择左下角的 Default.

这和系统预定义的还是有区别, 因为这只能左右以后的文件, 管不着以前存在的文件.

如何...没办法了.

其他编译指令, 譬如在 Debug 或 Release 中的设置也都是这样; 也就是说: 每个文件都有相对独立的编译设置.

看到 Project -> Options... 马上明白了编译指令的设置方法有两种:

1、使用 {$...} 在代码中嵌入;

2、从 Project -> Options... 设置.

但在代码中嵌入有时是不可替代的, 譬如现在讨论的条件编译.

9、编译指令有多少?:

现在谈到的还只是条件编译, 实际应用最多的是开关编译; 在任一代码页执行快捷键 Ctrl+O+O , 然后看看最上面...

下面列出了这些默认设置:

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
{$MINSTACKSIZE $00004000}
{$MAXSTACKSIZE $00100000}
{$IMAGEBASE $00400000}
{$APPTYPE GUI}
{$WARN SYMBOL_DEPRECATED ON}
{$WARN SYMBOL_LIBRARY ON}
{$WARN SYMBOL_PLATFORM ON}
{$WARN SYMBOL_EXPERIMENTAL ON}
{$WARN UNIT_LIBRARY ON}
{$WARN UNIT_PLATFORM ON}
{$WARN UNIT_DEPRECATED ON}
{$WARN UNIT_EXPERIMENTAL ON}
{$WARN HRESULT_COMPAT ON}
{$WARN HIDING_MEMBER ON}
{$WARN HIDDEN_VIRTUAL ON}
{$WARN GARBAGE ON}
{$WARN BOUNDS_ERROR ON}
{$WARN ZERO_NIL_COMPAT ON}
{$WARN STRING_CONST_TRUNCED ON}
{$WARN FOR_LOOP_VAR_VARPAR ON}
{$WARN TYPED_CONST_VARPAR ON}
{$WARN ASG_TO_TYPED_CONST ON}
{$WARN CASE_LABEL_RANGE ON}
{$WARN FOR_VARIABLE ON}
{$WARN CONSTRUCTING_ABSTRACT ON}
{$WARN COMPARISON_FALSE ON}
{$WARN COMPARISON_TRUE ON}
{$WARN COMPARING_SIGNED_UNSIGNED ON}
{$WARN COMBINING_SIGNED_UNSIGNED ON}
{$WARN UNSUPPORTED_CONSTRUCT ON}
{$WARN FILE_OPEN ON}
{$WARN FILE_OPEN_UNITSRC ON}
{$WARN BAD_GLOBAL_SYMBOL ON}
{$WARN DUPLICATE_CTOR_DTOR ON}
{$WARN INVALID_DIRECTIVE ON}
{$WARN PACKAGE_NO_LINK ON}
{$WARN PACKAGED_THREADVAR ON}
{$WARN IMPLICIT_IMPORT ON}
{$WARN HPPEMIT_IGNORED ON}
{$WARN NO_RETVAL ON}
{$WARN USE_BEFORE_DEF ON}
{$WARN FOR_LOOP_VAR_UNDEF ON}
{$WARN UNIT_NAME_MISMATCH ON}
{$WARN NO_CFG_FILE_FOUND ON}
{$WARN IMPLICIT_VARIANTS ON}
{$WARN UNICODE_TO_LOCALE ON}
{$WARN LOCALE_TO_UNICODE ON}
{$WARN IMAGEBASE_MULTIPLE ON}
{$WARN SUSPICIOUS_TYPECAST ON}
{$WARN PRIVATE_PROPACCESSOR ON}
{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CODE OFF}
{$WARN UNSAFE_CAST OFF}
{$WARN OPTION_TRUNCATED ON}
{$WARN WIDECHAR_REDUCED ON}
{$WARN DUPLICATES_IGNORED ON}
{$WARN UNIT_INIT_SEQ ON}
{$WARN LOCAL_PINVOKE ON}
{$WARN MESSAGE_DIRECTIVE ON}
{$WARN TYPEINFO_IMPLICITLY_ADDED ON}
{$WARN RLINK_WARNING ON}
{$WARN IMPLICIT_STRING_CAST ON}
{$WARN IMPLICIT_STRING_CAST_LOSS ON}
{$WARN EXPLICIT_STRING_CAST OFF}
{$WARN EXPLICIT_STRING_CAST_LOSS OFF}
{$WARN CVT_WCHAR_TO_ACHAR OFF}
{$WARN CVT_NARROWING_STRING_LOST OFF}
{$WARN CVT_ACHAR_TO_WCHAR OFF}
{$WARN CVT_WIDENING_STRING_LOST OFF}
{$WARN XML_WHITESPACE_NOT_ALLOWED ON}
{$WARN XML_UNKNOWN_ENTITY ON}
{$WARN XML_INVALID_NAME_START ON}
{$WARN XML_INVALID_NAME ON}
{$WARN XML_EXPECTED_CHARACTER ON}
{$WARN XML_CREF_NO_RESOLVE ON}
{$WARN XML_NO_PARM ON}
{$WARN XML_NO_MATCHING_PARM ON}
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-01-18
预处理指令,EInOutError检查的开关。在{$I+}(系统默认值)状态编译的程序, 一旦发生I/O错误时, 将会引发一个EInOutError的例外, 假如我们在特定的情况下不希望出现这个例外的讯息时)可以将这个Compiler directive设为{$I-}, 此时, 程序执行时是否发生过错误,必须自行检查IOResult这个公用变量的值, 如果是零, 表示没有错误,本回答被提问者采纳

delphi {$I-} {$I+}是什么意思
在{$I+}(系统默认值)状态编译的程序, 一旦发生I\/O错误时, 将会引发一个EInOutError的例外, 假如我们在特定的情况下不希望出现这个例外的讯息时)可以将这个Compiler directive设为{$I-}, 此时, 程序执行时是否发生过错误,必须自行检查IOResult这个公用变量的值, 如果是零, 表示没有错误,...

delphi 中 $这个符号干嘛用的?
2. 预编译指令,{$ I+} 表示打开I\/O检查

请问delphi中用{}代表什么含义.
代表注释,人看,机器不看 但是{$i-}等编译指令除外

i在delphi中是什么意思大神们帮帮忙
i 和 n、sum一样,是integer 类型的。。 一般用在for while 等循环语句中,控制循环次数。。 当然用来干别的也成,只要您喜欢。。 总之是个整型变量,能干整型能干的事。。

delphi 单元中 {$I *.inc}是什么意思?
将INC文件包含到程序中 其中inc一般是include文件用于编写同用代码的,比如在网页编写过程中就可以把很多页面需要运用的自定义代码统一写在一个inc文件中然后用include语句包含进网页。这样做的好处是,改的时候只需要改inc文件网页不用动。inc文件用任何文本编辑器都可以打开比如记事本、word……

初学delphi数组问题
第一,在delphi中{}中是注释语句,编译时不起作用。你在var前加上了{,在\/\/定二维数组 后加上了}代表声明变量的语句无效 第二,delphi中的变量需要先声明后使用,上面变量的声明被注释了,下面的赋值语句就不能使用 第三,for语句的使用是for i:=1 to 10 do begin ... end;程序修改如下:var...

delphi中怎么用什么命令打开文件夹?
扫描文件夹里面有哪些文件应该使用findfirst、findnext,下面是我程序里面的一个自定义函数,用来把指定目录下的文件清单写入一个字符串里面,可以writeln输出(writeln(DirListStr('c:\\windows\\*.exe'))),或者存放到memo里面。function DirListStr(const FileName: string): string;var SearchRec: ...

Delphi 怎么倒循环
定义一个变量i,integer类型,每次循环i加1就知道了

delphi中多维数组的运算问题 拜托大家了
SetLength( x[i][j], 6 );for k := 0 to 5 do SetLength( x[i][j][k], 7 );end;end;如上很繁琐吧?所以建议你直接用静态数组,定义一个各个维度足够大的四维数组就行,例如:T1 = array[1..100][1..100][1..100][1..100] of Integer;一旦x : T1; 则数组x立即占据(不...

delphi的程序执行顺序
MyProc(i)的功能是对参数值递增3,并且是过程形式;另一个是递增2,并且是函数形式;写成TMyClass类的形式作者的本意可能是为了突出 类 的应用,多个函数集中到一个类显得有条理些;当然也可以写成单个函数,可以不要TMyClass类。Type TMyClass = class procedure MyProc(var x: Integer);function ...

相似回答