vc预处理
VC 编译命令开关 vc可以可以通过Settings -->Project-->C/C++-->Customize来设置这个编译开关 /C:在预处理输出中保留注释语句 /c:只编译,不连接,相当于在"Build"菜单下选择了"Compile" /D:定义常量和宏,与源程序里的#define 有相同效果 /E:预处理C、C++源文件,将源文件中所有的预编译指令及宏展开,将注释去掉,然后将预处理器的输出拷贝至标准输出设备输出,并且在每个文件的开头和末尾加入#line /EH:指定编译器用何种异常处理模型 /EP:同/E,只是去掉了#line /F:设置程序的堆栈大小 /FA:设置生成何种列表文件(汇编、汇编与机器码、汇编与源码、汇编与机器码以及源码) /Fa:指定用/FA设置的列表文件的存放路径及(或)文件名 /FD:生成文件的相互依赖信息 /Fd:设置程序数据库文件(PDB)的存放路径及(或)文件名 /Fe:设置最终可执行文件的存放路径及(或)文件名 /FI:预处理指定的头文件,与源文件中的#include有相同效果 /Fm:创建map文件 /Fo:设置编译后Obj文件的存放路径及(或)文件名 /Fp:设置预编译文件(pch)的存放路径及(或)文件名 /FR:生成浏览信息(sbr)文件 /Fr:同/FR,不同之处在于/Fr不包括局部变量信息 /G3:为80386处理器优化代码生成 /G4:为80486处理器优化代码生成 /G5:为Pentium处理器优化代码生成 /G6:为Pentium Pro处理器优化代码生成 /GA:为Windows应用程序作优化 /GB:为Pentium处理器优化代码生成,使用80386、、Pentium、Pentium Pro的混合指令集,是代码生成的默认选项(程序属性选项中Processor对应Blend) /GD:为Windows动态库(dll)作优化,此开关在VC6中没有实现 /Gd:指定使用__cdecl的函数调用规则 /Ge:激活堆栈检测 /GF:消除程序中的重复的字符串,并将她放到只读的缓冲区中 /Gf:消除程序中的重复字符串 /Gh:在每个函数的开头调用钩子(hook)函数--penter /Gi:允许渐进编译 /Gm:允许最小化rebuild /GR:允许运行时类型信息(Run-Time Type Infomation) /Gr:指定使用__fastcall的函数调用规则 /Gs:控制堆栈检测所用内存大小 /GT:支持用__declspec(thread)分配的数据的fier-safety /GX:允许同步异常处理,与/EHsc开关等价 /Gy:允许编译器将每一个函数封装成COMDATs的形式,供连接器调用 /GZ:允许在Debug build 的时候捕捉Release build的错误 /Gz:指定使用__stdcall的函数调用规则 /H:限制外部名字的长度 /HELP:列出编译器的所有的命令开关 /I:指定头文件的搜索路径 /J:将char的缺省类型从signed char改成unsigned char /LD:创建一个动态连接库 /LDd:创建一个Debug版本的动态链接库 /link:将指定的选项传给连接器 /MD:选择多线程、DLL版本的C Run-Time库 /MDd:选择多线程、DLL、Debug版本的C Run-Time库 /ML:选择单线程版本的C Run—Time库 /MLd:选择单线程、Debug版本的C Run—Time库 /MT:选择多线程版本的C Run-Time库 /MTd:选择多线程、Debug版本的C Run—Time库 /nologo:不显示程序的版权信息 /O1:优化使产生的可执行代码最小 /O2:优化使产生的可执行代码速度最快 /Oa:指示编译器程序里没有使用别名,可以提高程序的执行速度 /Ob:控制内联(inline)函数的展开 /Od:禁止代码优化 /Og:使用全局优化 /Oi:用内部函数去代替程序里的函数调用,可以使程序运行的更快,但程序的长度变长 /Op:提高浮点数比较运算的一致性 /Os:产生尽可能小的可执行代码 /Ot:产生尽可能块的可执行代码 /Ow:指示编译器在函数体内部没有使用别名 /Ox:组合了几个优化开关,达到尽可能多的优化 /Oy:阻止调用堆栈里创建帧指针 /Q1f:对核心级的设备驱动程序生成单独的调试信息 /QI0f:对Pentium 0x0f错误指令作修正 /Qifdiv:对Pentium FDIV错误指令作修正 /P:将预处理输出写到指定文件里,文件的后缀名为I /TC:将命令行上的所有文件都当作C源程序编译,不管后缀名是否为.c /Tc:将指定的文件当作C源程序编译,不管后缀名是否为.c /TP:将命令行上的所有文件都当作C++源程序编译,不管后缀名是否为.cpp /Tp:将指定文件当作C++源程序编译,不管后缀名是否为.cpp /U:去掉一个指定的前面定义的符号或常量 /u:去掉所有前面定义的符号或常量 /V:在编译的obj文件里嵌入版本号 /vd:禁止/允许构造函数置换 /vmb:选择指针的表示方法,使用这个开关,在声明指向某个类的成员的指针之前,必须先定义这个类 /vmg:选择指针的表示方法,使用这个开关,在声明指向某个类的成员的指针之前,不必先定义这个类,但要首先指定这个类是使用何种继承方法 /vmm:设置指针的表示方法为Single Inheritance and Multiple Inheritance /vms:设置指针的表示方法为Single Inheritance /vmv:设置指针的表示方法为Any class /W:设置警告等级 /w:禁止所有警告 /X:阻止编译器搜索标准的include 目录 /Yc:创建预编译头文件(pch) /Yd:在所有的obj文件里写上完全的调试信息 /Yu:在build过程中使用指定的预编译头文件 /YX:指示编译器若预编译头文件存在,则使用它,若不存在,则创建一个 /Z7:生成MSC7.0兼容的调试信息 /Za:禁止语言扩展(Microsoft Extensions to C) /Zd:调试信息只包含外部和全局的符号信息以及行号信息 /Ze:允许语言扩展(Microsoft Extensions to C) /Zg:为源文件里面定义的每个函数生成函数原型 /ZI:生成程序库文件(Pdb)并支持Edit and Continue调试特性 /Zi:生成程序库文件(pdb),包含类型信息和符号调试信息 /ZL:从obj文件里去掉缺省的库文件名 /Zm:设置编译器的内存分配xianzhi /Zn:禁止浏览信息文件里面的封装 /Zp:设置结构成员在内存里面的封装格式 /Zs:快速检查语法错误 -------------------------- vc所支持的文件类型 DSW:全称是Developer Studio Workspace,最高级别的配置文件,记录了整个工作空间的配置信息,她是一个纯文本的文件,在vc创建新项目的时候自动生成 DSP:全称是Developer Studio Project,也是一个配置文件,不过她记录的是一个项目的所有配置信息,纯文本文件 OPT:与DSW、DSP配合使用的配置文件,她记录了与机器硬件有关的信息,同一个项目在不同的机器上的opt文件内容是不同的 CLW:记录了跟ClassWizard相关的信息,如果丢失了clw文件,那么在Class View面板里就没有类信息 PLG:实际上是一个超文本文件,可以用Internet Explorer打开,记录了Build的过程,是一个日志型文件 RC:资源描述文件,记录了所有的资源信息,在资源编辑器里作的修改,实际上都是对RC文件的修改 RC2:附加的资源描述文件,不能直接资源编辑器修改,只能手工添加,可以用来添加额外的资源 RES:经过资源编辑器编译之后的资源文件,以二进制方式存放 SBR:编译器生成的浏览信息文件,在代码导航的时候非常有用,她需要在编译时指定/FR或者/Fr开关 BSC:BSCMAKE.EXE将所有的SBR文件作为输入,经过处理之后输出一个BSC文件,在代码导航的时候实际用到的是BSC文件 ILK:当选定渐增型编译连接时,连接器自动生成ILK文件,记录连接信息 PDB:全称是Program DataBase,即程序数据库文件,用来记录调试信息,是一个相当重要的文件,没有他,程序无法正常调试 LIB:如果项目输出是Dll的话,一般会输出一个跟项目同名的Lib文件,记录输出的函数信息 EXP:同Lib,是跟Dll一起生成的输出文件 PCH:全称是PreCompiled Header,就是预先编译好的头文件,在编译时指定/Yu开关时编译器自动生成 vc一些预处理 ) #if defined XXX_XXX #endif 是条件编译,是根据你是否定义了XXX_XXX这个宏,而使用不同的代码。 一般.h文件里最外层的 #if !defined XXX_XXX #define XXX_XXX #endif 是为了防止这个.h头文件被重复include。 #undef为解除定义,#ifndef是if not defined的缩写,即如果没有定义。 ) #error XXXX 是用来产生编译时错误信息XXXX的,一般用在预处理过程中; 例子: #if !defined(__cplusplus) #error C++ compiler required. #endif ) extern 全局变量 相当于C#中的public ) __cdecl和__stdcall是两种C++函数调用规则的系统约定。 __cdecl的: Argument-passing order Right to left Stack-maintenance responsibility Calling function pops the arguments from the stack Name-decoration convention Underscore character (_) is prefixed to names, except when exporting __cdecl functions that use C linkage. Case-translation convention No case translation __stdcall的: Argument-passing order Right to left. Argument-passing convention By value, unless a pointer or reference type is passed. Stack-maintenance responsibility Called function pops its own arguments from the stack. Name-decoration convention An underscore (_) Case-translation convention None ) #pragma pack( [ show ] | [ push | pop ] [, identifier ] , n ) 这个是用来指定类、结构的内存对齐的; 这个说起来有点多,你上网查内存对齐能查到; ) __declspec( dllimport ) declarator __declspec( dllexport ) declarator 这两个是与Dll有关的,声明可以从dll文件中输出和输入的函数、类或数据; ) #pragma once 是规定当编译时这个文件只能被include一次; 类似 #if define ) disable message 才疏学浅,没见过。。。。 ) __int64 是64位的整数类型,是为了防止32位的int不够用时用的; ) #pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] ) 是用来定义函数被放置在obj文件的哪个段里。 --------------------------------------------------- #if defined MACRO_NAME 与 #ifdef MACRO_NAME 还是稍微有点区别的。 譬如我们公司就鼓励写第一种,因为它可以这么写: #if defined(MACRO_NAME) && defined(MACRO_NAME) 这个#error是可以让用户在编译时手动产生一个编译错误,更准确的说是在预处理的时候。 #if !defined(__cplusplus) #error C++ compiler required. #endif 这个就是说如果你的程序不是C++的,譬如C的,就会报错。里面的错误信息是用户自己决定的。 #pragma once基本和前面那个选择编译一样的。 VC中预处理指令与宏定义的妙用 妙用一 刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具。使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能。 一个经典的例子 使用预处理与宏定义最经典的例子莫过于加在一个头文件中以避免头文件被两次编译。试想这种的情况,有一个文件headerfile.h 它被包含在headerfile1.h中,同时在headerfile2.h 中也被包含了,现在有一个CPP文件,implement.cpp 包含了headerfile1.h 和headerfile2.h: #include “headerfile1.h” #include “headerfile2.h” 假设headerfile.h 中定义了一个全局变量 iglobal 。 int iglobal; 在编译的时候编译器两次编译headerfile,也就会发现iglobal被定义了两次,这时就会发生变量重定义的编译错误。 传统的解决办法是使用#ifdef 以及#endif 来避免头文件的重复编译,在上面的例子中,只需要加上这么几行: #ifndef smartnose_2002_6_21_headerfile_h #define smartnose_2002_6_21_headerfile_h int iglobal; #endif 仔细的考虑上面的宏定义,会发现当编译器编译过一次headerfile.h以后,smartnose_2002_6_21_headerfile_h 这个宏就被定义了,以后对headerfile.h的编译都会跳过int iglobal 这一行。当然smartnose_2002_6_21_headerfile_h 这个宏是可以任意定义的,但是这个宏本身不能和其它文件中定义的宏重复,所以MFC在自动生成的文件中总是使用一个随机产生的长度非常长的宏,但我觉得这没有必要,我建议在这个宏中加入一些有意义的信息,比方作者,文件名,文件创建时间等等,因为我们有时候会忘记在注释中加入这些信息。 在VC.Net 中我们不会再看见这些宏定义了,因为在这里会普遍使用一个预处理指令: #pragma once 只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。 源代码版本控制 当我们为许多平台开发多个版本的时候预编译指令和宏定义也能够帮我们的忙。假设我们现在为WINDOWS 和LINUX开发了一套软件,由于这两种系统的不同,我们不得不在程序控制源代码的版本。比方内存的分配,我们可以在LINUX上使用标准C的malloc 函数,但是我们希望在 WINDOWS上使用HeapAlloc API。下面的代码演示了这种情况: main() { ……………….. #ifdef _WINDOWS_PLATFORM HeapAlloc(); #else malloc(); #endif ……………….. } 当我们在WINDOWS 平台上编译此程序的时候,只需要定义_WINDOWS_PLATFORM这个宏,那么HeapAlloc这条语句就能够起作用了。这样就能够让我们在同一个文件中为不同的平台实现不同版本的代码,同时保持程序的良好结构。在许多情况下,我们还可以为一个方法使用不同的算法,然后用宏定义来针对不同的情况选择其中的一个进行编译。这在MFC应用程序中是使用得最多的。最明显的就是文件中经常存在的 #ifdef _DEBUG …………………….some code……….. #endif 这样的代码,这些代码在应用程序的调试版(DEBUG)中会发挥其作用。 #Pragma 指令 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。其格式一般为 #Pragma Para 其中Para 为参数,下面来看一些常用的参数。 message 参数。 Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为: #Pragma message(“消息文本”) 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。 当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法 #ifdef _X86 #Pragma message(“_X86 macro activated!”) #endif 当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。 另一个使用得比较多的pragma参数是code_seg。格式如: #pragma code_seg( ["section-name"[,"section-class"] ] ) 它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。 最后一个比较常用的就是上面所说的#pragma once 指令了。 VC预定义的宏 在VC中有一类宏并不是由用户用#define语句定义的,而是编译器本身就能够识别它们。这些宏的作用也是相当大的。让我们来看第一个,也是MFC中使用得最频繁的一个:__FILE__ 。 当编译器遇到这个宏时就把它展开成当前被编译文件的文件名。好了,我们马上就可以想到可以用它来做什么,当应用程序发生错误时,我们可以报告这个错误发生的程序代码在哪个文件里,比方在文件test.cpp中有这样的代码: try { ]); } catch(CException *e ) { TRACE(“ there is an error in file: %s\n”,__FILE__); } 在程序运行的时候,如果内存分配出现了错误,那么在调试窗口中会出现there is an error in file: test.cpp 这句话,当然,我们还可以把这个错误信息显示在别的地方。 如果我们还能够记录错误发生在哪一行就好了,幸运的是,与__FILE__宏定义一样,还有一个宏记录了当前代码所在的行数,这个宏是__LINE__。使用上面的两个宏,我们可以写出一个类似于VC提供的ASSERT语句。下面是方法 #define MyAssert(x) \ if(!(x)) \ MessageBox(__FILE__,__LINE__,NULL,MB_OK); 我们在应用程序中可以象使用ASSERT语句一样使用它,在错误发生时,它会弹出一个对话框,其标题和内容告诉了我们错误发生的文件和代码行号,方便我们的调试,这对于不能使用ASSERT语句的项目来说是非常有用的。 除了这两个宏以外,还有记录编译时间的__TIME__,记录日期的__DATE__,以及记录文件修改时间的__TIMESTAMP__宏。 使用这些预定义的宏,我们几乎可以生成和VC能够生成的一样完整的源代码信息报表。 结论 翻开MFC和Linux的源代码,宏定义几乎占据了半边天,消息映射,队列操作,平台移植,版本管理,甚至内核模块的拆卸安装都用宏定义完成。毫不夸张的说,有些文件甚至就只能看见宏定义。所以学习宏定义,熟练的使用宏定义对于学习C语言乃至VC都是非常关键的。 妙用二 在上一篇文章中,我演示了几个常用的宏定义和预处理指令,但可以说这些都是相当常规的技巧。下面要介绍的宏定义与预处理指令的用法也是ATL,MFC以及LINUX中使用得比较多的非常重要的技巧。 ## 连接符与# 符 ## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#符是把传递过来的参数当成字符串进行替代。下面来看看它们是怎样工作的。这是MSDN上的一个例子。 假设程序中已经定义了这样一个带参数的宏: #define paster( n ) printf( "token" #n " = %d", token##n ) 同时又定义了一个整形变量: ; 现在在主程序中以下面的方式调用这个宏: paster( ); 那么在编译时,上面的这句话被扩展为: printf( " " = %d", token9 ); 注意到在这个例子中,paster();中的这个””被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9。而#n也被””所替代。 可想而知,上面程序运行的结果就是在屏幕上打印出token9= 在ATL的编程中,我们查看它的源代码就会经常看见这样的一段: #define IMPLEMENTS_INTERFACE(Itf) \ {&IID_##Itf, ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls, Itf) }, 我们经常不假思索的这样使用它: …… IMPLEMENTS_INTERFACE(ICat) …… 实际上IID_ICat 已经在别的地方由ATL向导定义了。当没有向导的时候,你只要遵循把IID_加在你的接口名前面来定义GUID的规则就也可以使用这个宏。在实际的开发过程中可能很少用到这种技巧,但是ATL使用得如此广泛,而其中又出现了不少这样的源代码,所以明白它是怎么一回事也是相当重要的。我的一个朋友就是因为不知道IMPLEMENTS_INTERFACE宏是怎么定义的,而又不小心改动了IID_ICat的定义而忙活了一整天。 Linux的怪圈 在刚开始阅读Linux的时候有一个小小的宏让我百思不得其解: #define wait_event(wq,condition) \ do{ \ if(condition) \ break; \ __wait_event(wq,condition); \ }) 这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的do{..}while结构呢?我曾一度在心里把它叫做“怪圈”。原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释: 假设有这样一个宏定义 #define macro(condition) \ if(condition) dosomething(); 现在在程序中这样使用这个宏: if(temp) macro(i); else doanotherthing(); 一切看起来很正常,但是仔细想想。这个宏会展开成: if(temp) if(condition) dosomething(); else doanotherthing(); 这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的。 为了避免这个错误,我们使用do{….}) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…})这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。 几个小小的警告 正如微软声称的一样,宏定义与预编译器指令是强大的,但是它又使得程序难以调试。所以在定义宏的时候不要节省你的字符串,一定要力争完整的描述这个宏的功能。同时在定义宏的时候如有必要(比方使用了if语句)就要使用do{…})将它封闭起来。在宏定义的时候一定要注意各个宏之间的相互依赖关系,尽量避免这种依赖关系的存在。下面就有这样一个例子。 设有一个静态数组组成的整型队列,在定义中使用了这样的方法: , , , }; 我们还需要在程序中遍历这个数组。通常的做法是使用一个宏定义 #define ELE_NUM 4 ………………………….. …………………………….. ;I<ELE_NUM;I++) { cout<<array[I]; } 由于某种偶然的原因,我们删除了定义中的一个元素,使它变成: array[]={,,} 而却忘了修改ELE_NUM的值。那么在上面的代码中马上就会发生访问异常,程序崩溃。然后是彻夜不眠的调试,最后发现问题出在这个宏定义上。解决这个问题的方法是不使用 array[]={….}这样的定义,而显式的申明数组的大小: array[ELE_NUM]={….} 这样在改动数组定义的时候,我们就不会不记得去改宏定义了。总之,就是在使用宏定义的时候能够用宏定义的地方统统都用上。 我发现的另一个有趣的现象是这样的: 假设现在有一个课程管理系统,学生的人数用宏定义为: #define STU_NUM 50 而老师的人数恰好也是50人,于是很多人把所有涉及到老师人数的地方通通用上STU_NUM这个宏。另一个学期过去,学生中的一个被开除了,系统需要改变。怎么办呢?简单的使用#define STU_NUM 49 么?如果是这样,一个老师也就被开除了,我们不得不手工在程序中去找那些STU_NUM宏然后判断它是否是表示学生的数目,如果是,就把它改成49。天哪,这个宏定义制造的麻烦比使用它带来的方便还多。正确的方法应该是为老师的数目另外定义一个宏: #define TEA_NUM 50 当学生的数目改变以后只要把STU_NUM 定义为49就完成了系统的更改。所以,当程序中的两个量之间没有必然联系的时候一定不要用其中的一个宏去替代另一个,那只会让你的程序根本无法改动。 最后,建议C/C++语言的初学者尽可能多的在你的程序中使用宏定义和预编译指令。多看看MFC,ATL或者LINUX的源代码,你会发现C语言强大的原因所在。
vc预处理的更多相关文章
- [转]VC++宏与预处理使用方法总结
原文链接:VC 宏与预处理使用方法总结 原文链接:VC预处理指令与宏定义的妙用
- WINDOWS动态链接库--MFC规则动态链接库
第一代window程序员使用windows api进行编程,到了后来,微软推出MFC类库,于是,动态链接库进行了升级,可以在动态连接库中使用MFC的API,这就叫做MFC动态链接库, 其中MFC动态链 ...
- VC中预处理指令与宏定义详解
刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...
- VC 宏与预处理使用方法总结
目录(?) C/C++ 预定义宏^ C/C++ 预定义宏用途:诊断与调试输出^ CRT 和 C 标准库中的宏^ NULL 空指针^ limits.h 整数类型常量^ float.h 浮点类型常量^ m ...
- C++预处理详解
本文在参考ISO/IEC 14882:2003和cppreference.com的C++ Preprocessor的基础上,对C++预处理做一个全面的总结讲解.如果没有特殊说明,所列内容均依据C++9 ...
- C++生成二级制文件过程(预处理->编译->链接 )
转载请注明出处 Windows下C++编程,通过VC生成工程,编写C++源文件,点运行,代码没问题直接出结果.VC什么都帮我们搞了,不了解其中过程也完全没问题. 转到linux下写c++,总觉得有点虚 ...
- Editplus配置VC++(1) 及相关注意事项
下篇文章:Editplus配置VC++(2) 与/d1reportSingleClassLayout 原本用的是VC++2010 现在换成了Visual Studio 2013,editplus相关配 ...
- 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出
[源码下载] 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 预处理命令 输入 ...
- VC++NMAKE
目录 第1章 NMAKE 1 1.1 运行NMAKE 1 1.1.1 NMAKE的实质 2 1.2 描述块 3 1.2.1 定义 3 1.2.2 多个描述块 3 1 ...
随机推荐
- c++ primer 10 关联容器
关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,顺序容器则通过元素在容器中的位置顺序存储和访问元素 关联容器类型 map 关联数组:元素通过键来存储和读取 set 大小可变的 ...
- DotNetOpenAuth实践之WCF资源服务器配置
系列目录: DotNetOpenAuth实践系列(源码在这里) 上一篇我们写了一个OAuth2的认证服务器,我们也获取到access_token,那么这个token怎么使用呢,我们现在就来揭开 一般获 ...
- 【LOJ】#2586. 「APIO2018」选圆圈
题解 不旋转坐标系,TLE,旋转坐标系,最慢一个点0.5s--maya,出题人数据水平很高了-- 好吧,如果你不旋转坐标系,写一个正确性和复杂度未知的K - D树,没有优化,你可以得到87分的好成绩 ...
- LoadRunner可以把关联取值当作检查点来使用
在性能测试过程中,很多人都会想通过使用检查点来检查系统响应是否正常,LR的51Testing软件测试网E$S ]:x(d a6h.G \(y 检查点对“死”的,静态的 可以做到检查作业,但是对于动态时 ...
- [Codeforces166B]Polygons 凸包
大致题意: 给你一个凸多边形A,和一个任意多边形B,判断B是否在A的内部 先对A的点集建凸包,然后枚举B中的点,二分判断是否在A的内部. 二分时可用叉积判断,详细见代码 #include<cst ...
- 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]
题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...
- java 错误:无法找到或装入主类
1. 删除找不到的jar 2. 删除src以外的文件夹
- 管理lvm 卷 system-storage-manager
安装 sudo yum install system-storage-manager [root@si-test-blueking--4 ~]# ssm list 创建物理磁盘到物理卷,<poo ...
- Hibernate 组合主键映射
在开发过程中创建数据库表时,有时候会发现单纯的创建一个主键是不可行的,有时候就需要多个字段联合保持唯一,本文讲述如何创建组合主键的映射. 例如:记录一个班的考试成绩.学生跟科目是多对多的关系,只有一个 ...
- 【BZOJ 3456】 3456: 城市规划 (NTT+多项式求逆)
3456: 城市规划 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 658 Solved: 364 Description 刚刚解决完电力网络的问题 ...