??xml version="1.0" encoding="utf-8" standalone="yes"?>日产亚洲一区二区三区,亚洲片一区二区三区,久久久久亚洲AV无码专区首JNhttp://m.tkk7.com/Archangelsy/category/20558.htmlLSYzh-cnFri, 21 Sep 2007 05:52:36 GMTFri, 21 Sep 2007 05:52:36 GMT60C~程手册http://m.tkk7.com/Archangelsy/articles/146413.htmlarchangelarchangelWed, 19 Sep 2007 04:25:00 GMThttp://m.tkk7.com/Archangelsy/articles/146413.htmlhttp://m.tkk7.com/Archangelsy/comments/146413.htmlhttp://m.tkk7.com/Archangelsy/articles/146413.html#Feedback0http://m.tkk7.com/Archangelsy/comments/commentRss/146413.htmlhttp://m.tkk7.com/Archangelsy/services/trackbacks/146413.html阅读全文

archangel 2007-09-19 12:25 发表评论
]]>
ODBC驱动E序不支持动态记录集http://m.tkk7.com/Archangelsy/articles/146183.htmlarchangelarchangelTue, 18 Sep 2007 07:47:00 GMThttp://m.tkk7.com/Archangelsy/articles/146183.htmlhttp://m.tkk7.com/Archangelsy/comments/146183.htmlhttp://m.tkk7.com/Archangelsy/articles/146183.html#Feedback0http://m.tkk7.com/Archangelsy/comments/commentRss/146183.htmlhttp://m.tkk7.com/Archangelsy/services/trackbacks/146183.html CSetSourCertInfo certinfo(g_pDB);
 if(!certinfo.Open(CRecordset::dynaset,NULL,CRecordset::none))
 {
  return;
 }
Open时会报出pȝ错误
后来发现Q把dynasetҎ(gu)snapshot可以了Q动态不支持动态记录集Q!

archangel 2007-09-18 15:47 发表评论
]]>
LNK2005 原因http://m.tkk7.com/Archangelsy/articles/146109.htmlarchangelarchangelTue, 18 Sep 2007 03:47:00 GMThttp://m.tkk7.com/Archangelsy/articles/146109.htmlhttp://m.tkk7.com/Archangelsy/comments/146109.htmlhttp://m.tkk7.com/Archangelsy/articles/146109.html#Feedback0http://m.tkk7.com/Archangelsy/comments/commentRss/146109.htmlhttp://m.tkk7.com/Archangelsy/services/trackbacks/146109.html 许多Visual C++的用者都到q?font size="+0">LNK2005:symbol already defined和LNK1169:one or more multiply defined symbols foundq样的链接错误,而且通常是在使用W三方库旉到的。对于这个问题,有的朋友可能不知其然Q而有的朋友可能知其然却不知其所以然Q那么本文就试图为大家彻底解开关于它的U种疑惑?/font>

    大家都知道,从C/C++源程序到可执行文件要l历两个阶段:(1)~译器将源文件编译成汇编代码Q然后由汇编?assembler)译成机器指?再加上其它相关信?后输出到一个个目标文g(object file,VC的编译器~译出的目标文g默认的后~名是.obj)中;(2)链接?linker)一个个的目标文?或许q会有若q程序库)链接在一L成一个完整的可执行文件?/font>

    ~译器编译源文g时会把源文g的全局W号(global symbol)分成?strong)和弱(weak)两类传给汇编器,而随后汇~器则将强弱信息~码q保存在目标文g的符可中。那么何谓强弱呢Q编译器认ؓ函数与初始化了的全局变量都是强符P而未初始化的全局变量则成了弱W号。比如有q么个源文g:

extern int errorno;
int buf[2] = {1,2};
int *p;

int main()
{
   return 0;
}

其中main、buf是强W号Qp是弱W号Q而errorno则非强非弱,因ؓ它只是个外部变量的用声明?/font>

    有了强弱W号的概念,我们可以看看链接器是如何处理与选择被多ơ定义过的全局W号:

规则1: 不允许强W号被多ơ定?即不同的目标文g中不能有同名的强W号)Q?/font>


规则2: 如果一个符号在某个目标文g中是强符P在其它文件中都是qP那么选择强符P


规则3: 如果一个符号在所有目标文件中都是qP那么选择其中L一个;

    ׃可知多个目标文g不能重复定义同名的函C初始化了的全局变量Q否则必然导?font size="+0">LNK2005和LNK1169两种链接错误。可是,有的时候我们ƈ没有在自qE序中发现这L重定义现象,却也遇到了此U链接错误,q又是何解?嗯,问题E微有点儿复杂,Ҏ(gu)慢慢道来?br />

    众所周知QANSI C/C++ 定义了相当多的标准函敎ͼ而它们又分布在许多不同的目标文g中,如果直接以目标文件的形式提供l程序员使用的话Q就需要他们确切地知道哪个函数存在于哪个目标文件中Qƈ且在链接时显式地指定目标文g名才能成功地生成可执行文Ӟ昄q是一个巨大的负担。所以C语言提供了一U将多个目标文g打包成一个文件的机制Q这是静态程序库(static library)。开发者在链接时只需指定E序库的文g名,链接器就会自动到E序库中L那些应用E序实用到的目标模块,q把(且只?它们从库中拷贝出来参与构建可执行文g。几乎所有的C/C++开发系l都会把标准函数打包成标准库提供l开发者?有不q么做的吗?)?/font>

    E序库ؓ开发者带来了方便Q但同时也是某些混ؕ的根源。我们来看看链接器是如何解析(resolve)对程序库的引用的?br />   
    在符可?symbol resolution)阶段Q链接器按照所有目标文件和库文件出现在命o行中的顺序从左至右依ơ扫描它们,在此期间它要l护若干个集?(1)集合E是将被合q到一L成可执行文g的所有目标文仉合;(2)集合U是未解析W号(unresolved symbolsQ比如已l被引用但是q未被定义的W号)的集合;(3)集合D是所有之前已被加入到E的目标文件定义的W号集合。一开始,E、U、D都是I的?/font>

(1): 对命令行中的每一个输入文件fQ链接器定它是目标文gq是库文Ӟ如果它是目标文gQ就把f加入到EQƈ把f中未解析的符号和已定义的W号分别加入到U、D集合中,然后处理下一个输入文件?/font>

(2): 如果f是一个库文gQ链接器会尝试把U中的所有未解析W号与f中各目标模块定义的符可行匹配。如果某个目标模块m定义了一个U中的未解析符P那么把m加入到E中,q把m中未解析的符号和已定义的W号分别加入到U、D集合中。不断地对f中的所有目标模块重复这个过E直臛_达一个不动点(fixed point)Q此时U和D不再变化。而那些未加入到E中的f里的目标模块p单地丢弃Q链接器l箋处理下一输入文g?/font>

(3): 如果处理q程中往D加入一个已存在的符P或者当扫描完所有输入文件时U非空Q链接器报错q停止动作。否则,它把E中的所有目标文件合q在一L成可执行文g?/font>

    VC带的~译器名字叫cl.exeQ它有这么几个与标准E序库有关的选项: /ML?MLd?MT?MTd?MD?MDd。这些选项告诉~译器应用程序想使用什么版本的C标准E序库?ML(~省选项)对应单线E静态版的标准程序库(libc.lib)Q?MT对应多线E静态版标准?libcmt.lib)Q此时编译器会自动定义_MT宏;/MD对应多线EDLL?导入库msvcrt.libQDLL是msvcrt.dll)Q编译器自动定义_MT和_DLL两个宏。后面加d的选项都会让编译器自动多定义一个_DEBUG宏,表示要用对应标准库的调试版Q因?MLd对应调试版单U程静态标准库(libcd.lib)Q?MTd对应调试版多U程静态标准库(libcmtd.lib)Q?MDd对应调试版多U程DLL标准?导入库msvcrtd.libQDLL是msvcrtd.dll)。虽然我们的在~译时明白无误地告诉了编译器应用E序希望使用什么版本的标准库,可是当编译器q完了活Q轮到链接器开工时它又如何得知一个个目标文g到底在思念谁?Z传递相思,我们的编译器干了点U密的勾当。在cl~译出的目标文g中会有一个专门的区域(兛_q个区域到底在文件中什么地方的朋友可以参考COFF和PE文g格式)存放一些指导链接器如何工作的信息,其中有一U就叫缺省库(default library)Q这些信息指定了一个或多个库文件名Q告诉链接器在扫描的时候也把它们加入到输入文g列表?当然序位于在命令行中被指定的输入文件之?。说到这里,我们先来做个实验。写个顶简单的E序Q然后保存ؓmain.c :

/* main.c */
int main() { return 0; }

用下面这个命令编译main.c(什么?你从不用命o行来~译E序Q这?.....) :

cl /c main.c

/c是告诉cl只编译源文gQ不用链接。因?ML是缺省选项Q所以上q命令也相当? cl /c /ML main.c 。如果没什么问题的?要出了问题才是活见鬼Q当焉非你的环境变量没有设|好Q这时你应该去VC的bin目录下找到vcvars32.bat文g然后q行它?Q当前目录下会出C个main.obj文gQ这是我们可爱的目标文件。随便用一个文本编辑器打开?是的Q文本编辑器Q大胆地d别害?Q搜?defaultlib"字符Ԍ通常你就会看到这L东西: "-defaultlib:LIBC -defaultlib:OLDNAMES"。啊哈,没错Q这?br />是保存在目标文g中的~省库信息。我们的目标文g昄指定了两个缺省库Q一个是单线E静态版标准库libc.lib(q与/ML选项相符)Q另外一个是oldnames.lib(它是Z兼容微Y以前的C/C++开发系l??/font>

    VC的链接器是link.exeQ因为main.obj保存了缺省库信息Q所以可以用

link main.obj libc.lib

或?/font>

link main.obj

来生成可执行文gmain.exeQ这两个命o是等L。但是如果你?/font>

link main.obj libcd.lib

的话Q链接器会给Z个警? "warning LNK4098: defaultlib "LIBC" conflicts with use of other libs; use /NODEFAULTLIB:library"Q因Z昑ּ指定的标准库版本与目标文件的~省g一致。通常来说Q应该保证链接器合ƈ的所有目标文件指定的~省标准库版本一_否则~译器一定会l出上面的警告,?font size="+0">LNK2005和LNK1169链接错误则有时会出现有时不会。那么这个有时到底是什么时候?呵呵Q别着急,下面的一切正是ؓ喜欢q根I底的你准备的?/font>

    Z个源文gQ就叫mylib.cQ内容如?

/* mylib.c */
Qi nclude

void foo()
{
   printf("%s","I am from mylib!\n");
}

?/font>

cl /c /MLd mylib.c

命o~译Q注?MLd选项是指定libcd.lib为默认标准库。lib.exe是VC自带的用于将目标文g打包成程序库的命令,所以我们可以用

lib /OUT:my.lib mylib.obj

mylib.obj打包成库Q输出的库文件名是my.lib。接下来把main.cҎ(gu):

/* main.c */
void foo();

int main()
{
   foo();
   return 0;
}

?/font>

cl /c main.c

~译Q然后用

link main.obj my.lib

q行链接。这个命令能够成功地生成main.exe而不会?font size="+0">LNK2005和LNK1169链接错误Q你仅仅是得C一条警告信?"warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs; use /NODEFAULTLIB:library"。我们根据前文所q的扫描规则来分析一下链接器此时做了些啥?/font>

    一开始E、U、D都是I集Q链接器首先扫描到main.objQ把它加入E集合Q同时把未解析的foo加入UQ把main加入DQ而且因ؓmain.obj的默认标准库是libc.libQ所以它被加入到当前输入文g列表的末。接着扫描my.libQ因是个库,所以会拿当前U中的所有符?当然现在׃个foo)与my.lib中的所有目标模?当然也只有一个mylib.obj)依次匚wQ看是否有模块定义了U中的W号。结果mylib.obj实定义了fooQ于是它被加入到EQfoo从U转移到DQmylib.obj引用的printf加入到UQ同样地Qmylib.obj指定的默认标准库是libcd.libQ它也被加到当前输入文g列表的末?在libc.lib的后?。不断地在my.lib库的各模块上q行q代以匹配U中的W号Q直到U、D都不再变化。很明显Q现在就已经到达了这么一个不动点Q所以接着扫描下一个输入文Ӟ是libc.lib。链接器发现l(f)ibc.lib里的printf.obj里定义有printfQ于是printf从UUdDQ而printf.obj被加入到EQ它定义的所有符号加入到DQ它里头的未解析W号加入到U。链接器q会把每个程序都要用到的一些初始化操作所在的目标模块(比如crt0.obj{?及它们所引用的模?比如malloc.obj、free.obj{?自动加入到E中,q更新U和D以反应这个变化。事实上Q标准库各目标模块里的未解析W号都可以在库内其它模块中找到定义,因此当链接器处理完libc.libӞU一定是I的。最后处理libcd.libQ因为此时U已经为空Q所以链接器会抛弃它里面的所有目标模块从而结束扫描,然后合ƈE中的目标模块q输出可执行文g?/font>

    上文描述了虽然各目标模块指定了不同版本的~省标准库但仍然链接成功的例子,接下来你目睹因U不严}而导致的(zhn)惨p|?/font>

    修改mylib.c成这个样?

Qi nclude

void foo()
{
   // just a test , don"t care memory leak
   _malloc_dbg( 1, _NORMAL_BLOCK, __FILE__, __LINE__ );
}

其中_malloc_dbg不是ANSI C的标准库函数Q它是VC标准库提供的malloc的调试版Q与相关函数配套能帮助开发者抓各种内存错误。用它一定要定义_DEBUG宏,否则预处理器会把它自动{为malloc。l用

cl /c /MLd mylib.c
lib /OUT:my.lib mylib.obj

~译打包。当再次?/font>

link main.obj my.lib

q行链接Ӟ我们看到了什么?天哪Q一堆的LNK2005加上个贵?fatal error"的LNK1169垫底Q当然还不了那个LNK4098。链接器是不是疯了?不,你冤枉可怜的链接器了Q我拍胸脯保证它可是一直在心?yu)责地照章办事?/font>

    一开始E、U、D为空Q链接器扫描main.objQ把它加入EQ把foo加入UQ把main加入DQ把libc.lib加入到当前输入文件列表的末尾。接着扫描my.libQfoo从U转移到DQ_malloc_dbg加入到UQlibcd.lib加到当前输入文g列表的尾部。然后扫描libc.libQ这时会发现l(f)ibc.lib里Q何一个目标模块都没有定义_malloc_dbg(它只在调试版的标准库中存?Q所以不会有M一个模块因为_malloc_dbg而加入EQ但是每个程序都要用到的初始化模?如crt0.obj{?及它们所引用的模?比如malloc.obj、free.obj{?q是会自动加入到E中,同时U和D被更C反应q个变化。当链接器处理完libc.libӞU只剩_malloc_dbgq一个符受最后处理libcd.libQ发现dbgheap.obj定义了_malloc_dbgQ于是dbgheap.obj加入到EQ它里头的未解析W号加入UQ它定义的所有其它符号也加入DQ这时灾难便来了。之前malloc{符号已l在D?随着libc.lib里的malloc.obj加入E而加入的)Q而dbgheap.obj又定义了包括malloc在内的许多同名符Pq引发了重定义冲H,链接器只好中断工作ƈ报告错误?/font>

    现在我们该知道,链接器完全没有责任,责Q在我们自qw上。是我们_心地把~省标准库版本不一致的目标文g(main.obj)与程序库(my.lib)链接hQ导致了大灾难。解军_法很单,要么?MLd选项来重~译main.cQ要么用/ML选项重编译mylib.c?/font>

    在上qC子中Q我们拥有库my.lib的源代码(mylib.c)Q所以可以用不同的选项重新~译q些源代码ƈ再次打包。可如果使用的是W三方的库,它ƈ没有提供源代码,那么我们只有改变自q序的~译选项来适应q些库了。但是如何知道库中目标模块指定的默认库呢Q其实VC提供的一个小工具便可以完成Q务,q就是dumpbin.exe。运行下面这个命?/font>

dumpbin /DIRECTIVES my.lib

然后在输ZN?Linker Directives"引导的信息,你一定会发现每一处这L信息都会包含若干个类?-defaultlib:XXXX"q样的字W串Q其中XXXX便代表目标模块指定的~省库名?/font>

    知道了第三方库指定的默认标准库,再用合适的选项~译我们的应用程序,可以避?font size="+0">LNK2005和LNK1169链接错误。喜ƢIDE的朋友,你一样可以到 "Project属? -> "C/C++" -> "代码生成(code generation)" -> "q行时库(run-time library)" 下讄应用E序的默认标准库版本Q这与命令行选项的效果是一L?/font>

l极解决办法Q?/strong>

?Project/Setting/Link/General中的 Project Options: 加入 /FORCE:MULTIPLE卛_?/font>



archangel 2007-09-18 11:47 发表评论
]]>
VC++的链接错误LNK2005 http://m.tkk7.com/Archangelsy/articles/146105.htmlarchangelarchangelTue, 18 Sep 2007 03:30:00 GMThttp://m.tkk7.com/Archangelsy/articles/146105.htmlhttp://m.tkk7.com/Archangelsy/comments/146105.htmlhttp://m.tkk7.com/Archangelsy/articles/146105.html#Feedback0http://m.tkk7.com/Archangelsy/comments/commentRss/146105.htmlhttp://m.tkk7.com/Archangelsy/services/trackbacks/146105.html   
  ~程中经常能遇到LNK2005错误——重复定义错误,其实LNK2005错误q不是一个很难解决的错误。弄清楚它Ş成的原因Q就可以L解决它了? 
   
  造成LNK2005错误主要有以下几U情况:  
  1Q重复定义全局变量。可能存在两U情况:  
  A、对于一些初学编E的E序员,有时候会以ؓ需要用全局变量的地方就可以使用定义x一下。其实这是错误的Q全局变量是针Ҏ(gu)个工E的。正的应该是在 一个CPP文g中定义如下:int   g_Test;那么在用的CPP文g中就应该使用Qextern   int   g_Test卛_Q如果还是用int   g_TestQ那么就会生LNK2005错误Q一般错误错误信息类|AAA.obj   error   LNK2005   int   book   cQbook@@3HA   already   defined   in   BBB.obj。切记的是不能l变量赋值否则还是会有LNK2005错误? 
                q里需要的是“声明”,不是“定义”!Ҏ(gu)C++标准的规定,一个变量是声明Q必d时满两个条Ӟ否则是定义Q? 
  (1)声明必须使用extern关键字;(2)不能l变量赋初? 
  所以,下面的是声明:  
  extern   int   a;  
  下面的是定义  
  int   a;   int   a   =   0;   extern   int   a   =0;  
  B、对于那么编E不是那么严谨的E序员,L在需要用变量的文g中随意定义一个全局变量Qƈ且对于变量名也不予考虑Q这也往往Ҏ(gu)造成变量名重复,而造成LNK2005错误。  ?br />

2Q头文g的包含重复。往往需要包含的头文件中含有变量、函数、类的定义,在其它用的地方又不得不多次包含之,如果头文件中没有相关的宏{防止重复链?的措施,那么׃产生LNK2005错误。解军_法是在需要包含的头文件中做类似的处理Q?ifndef   MY_H_FILE       //如果没有定义q个? 
  #define   MY_H_FILE       //定义q个? 
  …?       //头文件主体内? 
  …?  
  #endif  
  上面是用宏来做的,也可以用预~译来做Q在头文件中加入Q? 
  #pragma   once  
  //头文件主体  ?br />

3Q用第三方的库造成的。这U情况主要是Cq行期函数库和MFC的库冲突造成的。具体的办法是那个提C出错的库放到另外一个库的前面。另外选择不同 的C函数库,可能会引赯个错误。微软和C有两UCq行期函数库Q一U是普通的函数库:LIBC.LIBQ不支持多线E。另外一U是支持多线E的Q?msvcrt.lib。如果一个工E里Q这两种函数库؜合用,可能会引赯个错误,一般情况下它需要MFC的库先于Cq行期函数库被链接,因此使用 支持多线E的msvcrt.lib。所以在使用W三方的库之前首先要知道它链接的是什么库Q否则就可能造成LNK2005错误。如果不得不使用W三方的 库,可以试按下面所说的Ҏ(gu)修改Q但不能保证一定能解决问题Q前两种Ҏ(gu)是微软提供的Q? 
  A、选择VC菜单Project->Settings->Link->Catagory选择InputQ再在Ignore   libraries   的Edit栏中填入你需要忽略的库,如:Nafxcwd.lib;Libcmtd.lib。然后在Object/library   Modules的Edit栏中填入正确的库的顺序,q里需要你能确定什么是正确的顺序,呵呵QGod   bless   youQ? 
  B、选择VC菜单Project->Settings->Link,然后在Project   Options的Edit栏中输入/verbose:libQ这样就可以在编译链接程序过E中在输出窗口看到链接的序了? 
  C、选择VC菜单Project->Settings->C/C++,Catagory选择Code   Generation后再在User   Runtime   libraray中选择MultiThread   DLL{其他库Q逐一试? 
  关于~译器的相关处理q程Q参考:  
  http://www.donews.net/xzwenlan/archive/2004/12/23/211668.aspx  
   
  q就是我所遇到q的LNK2005错误的几U情况,肯定q有其他的情况也可能造成q种错误Q所以我不希望你在看完这文章以后,再遇到LNK2005错误 时候,不动脑筋的想对号入的排除错误。编E的q程是一个思考的q程Q所以还是多多开动你的头脑,那样收获会更多!  
  Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q? 
  支持,我在C֌里也看到了许多LINK   2005? 
  补充一?是一ơ在用第三方库时,׃errno被重定义,用多U方法都不能解决,后查找MSDN,发现l(f)ink有个选项/FORCE可以解决,在IDE? 
  Project->Settings->Link?选categroy为custom,force   file   output前打? 
  但会有警? 
  warning   LNK4088:   image   being   generated   due   to   /FORCE   option;   image   may   not   run  
  但的解决了问题,q是׃VC寚w定义比较严格,像BCB或GCC在库中的重定义不会有M警告或错? 
  Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=  
  我发现的另外一个出现LINK2005的现象,好像是由于名U空间而引L。我在dos下写的程序没有问题,但是攑֜mfc中就出现了这个链接错误。因?起初囄事,我在一个头文g中写了using   namespace   std,q且q个头文件我多处使用Q另外,我还使用了boost库。后来,问题解决的方法非常奇怪,在一个头文g中引用其他头文gQ这些头文g的顺序换一 下就通过了,那个出现问题的头文g中我使用了std::mapQ当我把q种容器使用模板代替后,链接有没事了。(例如Qtemplate< class   coll>Q?后来感到模板技术还有这U效?赚了!哈哈  
  Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=  
  Knowledge   Base      
  What   are   the   C   and   C++   libraries   my   program   would   link   with?  
   
  ------------------------------------------------------------------  
  |   Compile       Old                 New   IOStream       Libraries                                     |  
  |   Option         IOStream       or   STL                   Linked   With                                 |  
  |================================================================|  
  |   /ML               Yes                 No                           LIBC.LIB,         LIBCI.LIB           |  
  |   /MDd             Yes                 No                           MSVCRTD.LIB,   MSVCIRTD.LIB     |  
   
  你的E序使用?ML~译选项,而程序依赖的.lib可能使用/MDd选项~译,造成链接冲突.  
   
  l一~译选项可回避此错误  
  Project   Settings->C/C++   Tab->Category:CodeGeneration  
  Use   run-time   libraryl合框中选择Multithread   Dll(或Debug   Multithread   Dll   )  
   
  注意Q所有相兛_E都应该选择相同~译选项  
  Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=  
  微Y的MSDN中查C息的  
   
  可能的原?   
   
  不慎同时与单U程库和多线E库链接。确保应用程序项目文件只包括适当的库Qƈ且Q何第三方库已适当创徏了单U程或多U程版本?   
  该符号ؓ装函数Q通过?  /Gy   ~译创徏Q,包含在多个文件中Q但在各~译间已改变。重新编译所有包?  symbol   的文件?   
  以不同的形式在不同库中的两个成员对象中定义了该符Pq且使用了这两个成员对象?   
  某个l对W号被定义两ơ,而每ơ定义的g同?   
  头文件声明ƈ定义了变量。可能的解决Ҏ(gu)有:    
  ?  .h   中声明变量:extern   BOOL   MyBool;Q然后在   .c   ?  .cpp   文g中向它分配:BOOL   MyBool   =   FALSE;?   
  变量声明ؓ   Static?   
  变量声明ؓ   selectany?   
  当将   uuid.lib   与定?  GUID   的其?  .lib   文gQ例?  oledb.lib   ?  adsiid.libQ一起用时。例如:    
  oledb.lib(oledb_i.obj)   :   error   LNK2005:   _IID_ITransactionObject  
  already   defined   in   uuid.lib(go7.obj)  
  若要修复Q请?  /FORCE:MULTIPLE   d到链接器命o行选项Qƈ保   uuid.lib   是引用的W一个库?   
   
  有关更多信息Q请参阅知识库文章:    
   
  Q148652QPRB:   LNK2005   Errors   When   Link   C   Run-Time   Libraries   Are   Linked   Before   MFC   Libraries?   
  Q140440QFIX:   Global   Overloaded   Delete   Operator   Causes   LNK2005?   
  Q184235QPRB:   LNK2005   Errors   on   New   and   Delete   When   Defining   _ATL_MIN_CRT?   
  该错误之后ؓ致命错误   LNK1169? 
  Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q? 
  有时候因为工E用了预编译头文gq且是增量编译,所以当你改动以后可能也会出现LNK2005错误Q提C“XXXX已经在XXXX.obj文g中定义?的消息,q时候只要Rebuild   All一般都能解决问题。这是因为头文g的顺序被改动{等操作造成的? 
  最后要说明的:事物是在不断变化中的QC++的标准在变化Q编译器也在变化Q所以ƈ不是所有的LNK2005错误都可以在q里扑ֈ{案Q但是至它能给你以提示。学习ƈ思考才是正的Q   ?br />

archangel 2007-09-18 11:30 发表评论
]]>
C/C++中的日期和时?time_t与struct tmQ{Q?/title><link>http://m.tkk7.com/Archangelsy/articles/112829.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Sun, 22 Apr 2007 14:47:00 GMT</pubDate><guid>http://m.tkk7.com/Archangelsy/articles/112829.html</guid><wfw:comment>http://m.tkk7.com/Archangelsy/comments/112829.html</wfw:comment><comments>http://m.tkk7.com/Archangelsy/articles/112829.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/Archangelsy/comments/commentRss/112829.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/Archangelsy/services/trackbacks/112829.html</trackback:ping><description><![CDATA[ <div id="z99jbdv" class="tit">C/C++中的日期和时?time_t与struct tm</div> <table style="TABLE-LAYOUT: fixed"> <tbody> <tr> <td> <div id="nf33pb9" class="cnt"> <p>摘要Q?/p> <p> <a >http://wiseman.cnblogs.com</a> <br />本文从介l基概念入手Q探讨了在C/C++中对日期和时间操作所用到的数据结构和函数Qƈ对计时、时间的获取、时间的计算和显C格式等斚wq行了阐q。本文还通过大量的实例向你展CZtime.h头文件中声明的各U函数和数据l构的详l用方法?br /><br />关键字:UTCQ世界标准时_QCalendar TimeQ日历时_QepochQ时间点Q,clock tickQ时钟计时单元)<br /><br /><br />1Q概?br />在C/C++中,对字W串的操作有很多值得注意的问题,同样QC/C++Ҏ(gu)间的操作也有许多值得大家注意的地斏V最q,在技术群中有很多|友也多ơ问到过C++语言中对旉的操作、获取和昄{等的问题。下面,在这文章中Q笔者将主要介绍在C/C++中时间和日期的用方?<br /><br />通过学习许多C/C++库,你可以有很多操作、用时间的Ҏ(gu)。但在这之前你需要了解一些“时间”和“日期”的概念Q主要有以下几个Q?br /><br />Coordinated Universal TimeQUTCQ:协调世界Ӟ又称Z界标准时_也就是大家所熟知的格林威L准时_Greenwich Mean TimeQGMTQ。比如,中国内地的时间与UTC的时差ؓ+8Q也是UTC+8。美国是UTC-5?br /><br />Calendar TimeQ日历时_是用“从一个标准时间点到此时的旉l过的秒数”来表示的时间。这个标准时间点对不同的~译器来说会有所不同Q但对一个编译系l来_q个标准旉Ҏ(gu)不变的,该编译系l中的时间对应的日历旉都通过该标准时间点来衡量,所以可以说日历旉是“相Ҏ(gu)间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说Q日历时间都是一L?br /><br />epochQ时间点。时间点在标准C/C++中是一个整敎ͼ它用此时的时间和标准旉点相差的U数Q即日历旉Q来表示?br /><br />clock tickQ时钟计时单元(而不把它叫做旉滴答ơ数Q,一个时钟计时单元的旉长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位?br /><br />我们可以使用ANSI标准库中的time.h头文件。这个头文g中定义的旉和日期所使用的方法,无论是在l构定义Q还是命名,都具有明昄C语言风格。下面,我将说明在C/C++中怎样使用日期的时间功能?br /><br />2Q?计时<br /><br />C/C++中的计时函数是clock()Q而与其相关的数据cd是clock_t。在MSDN中,查得对clock函数定义如下Q?br /><br />clock_t clock( void );<br /><br />q个函数q回从“开启这个程序进E”到“程序中调用clock()函数”时之间的CPU旉计时单元Qclock tickQ数Q在MSDN中称之ؓ挂钟旉Qwall-clockQ。其中clock_t是用来保存时间的数据cdQ在time.h文g中,我们可以扑ֈ对它的定义:<br /><br />#ifndef _CLOCK_T_DEFINED<br />typedef long clock_t;<br />#define _CLOCK_T_DEFINED<br />#endif<br /><br />很明显,clock_t是一个长整Ş数。在time.h文g中,q定义了一个常量CLOCKS_PER_SECQ它用来表示一U钟会有多少个时钟计时单元,其定义如下:<br /><br />#define CLOCKS_PER_SEC ((clock_t)1000)<br /><br />可以看到可以看到每过千分之一U(1毫秒Q,调用clockQ)函数q回的值就?。下面D个例子,你可以用公式clock()/CLOCKS_PER_SEC来计一个进E自w的q行旉Q?br /><br />void elapsed_time()<br />{<br />printf("Elapsed time:%u secs.\n",clock()/CLOCKS_PER_SEC);<br />}<br /><br />当然Q你也可以用clock函数来计你的机器运行一个@环或者处理其它事件到底花了多时_<br /><br />Qi nclude “stdio.h?br />Qi nclude “stdlib.h?br />Qi nclude “time.h?br /><br />int main( void )<br />{<br />   long    i = 10000000L;<br />   clock_t start, finish;<br />   double  duration;<br />   /* 量一个事件持l的旉*/<br />   printf( "Time to do %ld empty loops is ", i );<br />   start = clock();<br />   while( i-- )      ;<br />   finish = clock();<br />   duration = (double)(finish - start) / CLOCKS_PER_SEC;<br />   printf( "%f seconds\n", duration );<br />   system("pause");<br />}<br /><br />在笔者的机器上,q行l果如下Q?br /><br />Time to do 10000000 empty loops is 0.03000 seconds<br /><br />上面我们看到旉计时单元的长度ؓ1毫秒Q那么计时的_ֺ也ؓ1毫秒Q那么我们可不可以通过改变CLOCKS_PER_SEC的定义,通过把它定义的大一些,从而计时_ֺ更高呢?通过试Q你会发现这h不行的。在标准C/C++中,最的计时单位是一毫秒?br /><br />3Q与日期和时间相关的数据l构<br /><br />在标准C/C++中,我们可通过tml构来获得日期和旉Qtml构在time.h中的定义如下Q?br /><br />#ifndef _TM_DEFINED<br />struct tm {<br />        int tm_sec;     /* U??取值区间ؓ[0,59] */<br />        int tm_min;     /* ?- 取值区间ؓ[0,59] */<br />        int tm_hour;    /* ?- 取值区间ؓ[0,23] */<br />        int tm_mday;    /* 一个月中的日期 - 取值区间ؓ[1,31] */<br />        int tm_mon;     /* 月䆾Q从一月开始,0代表一月) - 取值区间ؓ[0,11] */<br />        int tm_year;    /* q䆾Q其值等于实际年份减?900 */<br />        int tm_wday;    /* 星期 ?取值区间ؓ[0,6]Q其?代表星期天,1代表星期一Q以此类?*/<br />        int tm_yday;    /* 从每q的1?日开始的天数 ?取值区间ؓ[0,365]Q其?代表1?日,1代表1?日,以此cL */<br />        int tm_isdst;   /* 夏o时标识符Q实行夏令时的时候,tm_isdst为正。不实行夏o时的q候,tm_isdst?Q不了解情况Ӟtm_isdst()?/<br />        };<br />#define _TM_DEFINED<br />#endif<br /><br />ANSI C标准UC用tml构的这U时间表CZؓ分解旉(broken-down time)?br /><br />而日历时_Calendar TimeQ是通过time_t数据cd来表C的Q用time_t表示的时_日历旉Q是从一个时间点Q例如:1970q?????U)到此时的U数。在time.h中,我们也可以看到time_t是一个长整型敎ͼ<br /><br />#ifndef _TIME_T_DEFINED<br />typedef long time_t;         /* 旉?*/<br />#define _TIME_T_DEFINED     /* 避免重复定义 time_t */<br />#endif<br /><br />大家可能会生疑问:既然time_t实际上是长整型,到未来的某一天,从一个时间点Q一般是1970q?????U)到那时的U数Q即日历旉Q超Z长整形所能表C的数的范围怎么办?对time_t数据cd的值来_它所表示的时间不能晚?038q??8?9?4?7U。ؓ了能够表C更久远的时_一些编译器厂商引入?4位甚x长的整Ş数来保存日历旉。比如微软在Visual C++中采用了__time64_t数据cd来保存日历时_q过_time64()函数来获得日历时_而不是通过使用32位字的time()函数Q,q样可以通过该数据类型保?001q?????U(不包括该旉点)之前的时间?br /><br />在time.h头文件中Q我们还可以看到一些函敎ͼ它们都是以time_t为参数类型或q回值类型的函数Q?br /><br />double difftime(time_t time1, time_t time0);<br />time_t mktime(struct tm * timeptr);<br />time_t time(time_t * timer);<br />char * asctime(const struct tm * timeptr);<br />char * ctime(const time_t *timer);<br /><br />此外Qtime.hq提供了两种不同的函数将日历旉Q一个用time_t表示的整敎ͼ转换为我们^时看到的把年月日时分U分开昄的时间格式tmQ?br /><br />struct tm * gmtime(const time_t *timer);                                          <br />struct tm * localtime(const time_t * timer);<br /><br />通过查阅MSDNQ我们可以知道Microsoft C/C++ 7.0中时间点的|time_t对象的|是从1899q?2?1???U到该时间点所l过的秒敎ͼ而其它各U版本的Microsoft C/C++和所有不同版本的Visual C++都是计算的从1970q?????U到该时间点所l过的秒数?br /><br />4Q与日期和时间相关的函数及应?br />在本节,我将向大家展C怎样利用time.h中声明的函数Ҏ(gu)间进行操作。这些操作包括取当前旉、算旉间隔、以不同的Ş式显C时间等内容?br /><br />4.1 获得日历旉<br /><br />我们可以通过time()函数来获得日历时_Calendar TimeQ,其原型ؓQ?br /><br />time_t time(time_t * timer);<br /><br />如果你已l声明了参数timerQ你可以从参数timerq回现在的日历时_同时也可以通过q回D回现在的日历旉Q即从一个时间点Q例如:1970q?????U)到现在此时的U数。如果参CؓI(NULLQ,函数只通过q回D回现在的日历旉Q比如下面这个例子用来显C当前的日历旉Q?br /><br />Qi nclude "time.h"<br />Qi nclude "stdio.h"<br />int main(void)<br />{<br />struct tm *ptr;<br />time_t lt;<br />lt =time(NULL);<br />printf("The Calendar Time now is %d\n",lt);<br />return 0;<br />}<br /><br />q行的结果与当时的时间有养I我当时运行的l果是:<br /><br />The Calendar Time now is 1122707619<br /><br />其中1122707619是我运行程序时的日历时间。即?970q?????U到此时的秒数?br /><br />4.2 获得日期和时?br /><br />q里说的日期和时间就是我们^时所说的q、月、日、时、分、秒{信息。从W?节我们已l知道这些信息都保存在一个名为tm的结构体中,那么如何一个日历时间保存ؓ一个tml构的对象呢Q?br /><br />其中可以使用的函数是gmtime()和localtime()Q这两个函数的原型ؓQ?br /><br />struct tm * gmtime(const time_t *timer);                                          <br />struct tm * localtime(const time_t * timer);<br /><br />其中gmtime()函数是将日历旉转化Z界标准时_x林尼L_Qƈq回一个tml构体来保存q个旉Q而localtime()函数是将日历旉转化为本地时间。比如现在用gmtime()函数获得的世界标准时间是2005q??0??8?0U,那么我用localtime()函数在中国地得的本地旉会比旉标准旉?个小Ӟ?005q??0?5?8?0U。下面是个例子:<br /><br />Qi nclude "time.h"<br />Qi nclude "stdio.h"<br />int main(void)<br />{<br />struct tm *local;<br />time_t t;<br />t=time(NULL);<br />local=localtime(&t);<br />printf("Local hour is: %d\n",local->tm_hour);<br />local=gmtime(&t);<br />printf("UTC hour is: %d\n",local->tm_hour);<br />return 0;<br />}<br /><br />q行l果是:<br /><br />Local hour is: 15<br />UTC hour is: 7<br /><br />4.3 固定的时间格?br /><br />我们可以通过asctime()函数和ctime()函数时间以固定的格式显C出来,两者的q回值都是char*型的字符丌Ӏ返回的旉格式为:<br /><br />星期?月䆾 日期 ??U?q\n\0<br />例如QWed Jan 02 02:03:55 1980\n\0<br /><br />其中\n是一个换行符Q\0是一个空字符Q表C字W串l束。下面是两个函数的原型:<br /><br />char * asctime(const struct tm * timeptr);<br />char * ctime(const time_t *timer);<br /><br />其中asctime()函数是通过tml构来生成具有固定格式的保存旉信息的字W串Q而ctime()是通过日历旉来生成时间字W串。这L话,asctimeQ)函数只是把tml构对象中的各个域填到时间字W串的相应位|就行了Q而ctimeQ)函数需要先参照本地的时间设|,把日历时间{化ؓ本地旉Q然后再生成格式化后的字W串。在下面Q如果lt是一个非I的time_t变量的话Q那么:<br /><br />printf(ctime(<));<br /><br />{h(hun)于:<br /><br />struct tm *ptr;<br />ptr=localtime(<);<br />printf(asctime(ptr));<br /><br />那么Q下面这个程序的两条printf语句输出的结果就是不同的了(除非你将本地时区设ؓ世界标准旉所在的时区Q:<br /><br />Qi nclude "time.h"<br />Qi nclude "stdio.h"<br />int main(void)<br />{<br />struct tm *ptr;<br />time_t lt;<br />lt =time(NULL);<br />ptr=gmtime(<);<br />printf(asctime(ptr));<br />printf(ctime(<));<br />return 0;<br />}<br /><br />q行l果Q?br /><br />Sat Jul 30 08:43:03 2005<br />Sat Jul 30 16:43:03 2005<br /><br />4.4 自定义时间格?br /><br />我们可以使用strftimeQ)函数时间格式化为我们想要的格式。它的原型如下:<br /><br />size_t strftime(<br />   char *strDest,<br />   size_t maxsize,<br />   const char *format,<br />   const struct tm *timeptr <br />);<br /><br />我们可以Ҏ(gu)format指向字符串中格式命o把timeptr中保存的旉信息攑֜strDest指向的字W串中,最多向strDest中存放maxsize个字W。该函数q回向strDest指向的字W串中放|的字符数?br /><br />函数strftime()的操作有些类gsprintf()Q识别以癑ֈ?%)开始的格式命o集合Q格式化输出l果攑֜一个字W串中。格式化命o说明串strDest中各U日期和旉信息的确切表C方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大写的?br /><br />%a 星期几的?<br />%A 星期几的全称 <br />%b 月分的简?<br />%B 月䆾的全U?<br />%c 标准的日期的旉?<br />%C q䆾的后两位数字 <br />%d 十进制表C的每月的第几天 <br />%D ??q?<br />%e 在两字符域中Q十q制表示的每月的W几?<br />%F q???<br />%g q䆾的后两位数字Q用基于周的年 <br />%G q分Q用基于周的年 <br />%h 写的月䆾?<br />%H 24时制的时 <br />%I 12时制的时<br />%j 十进制表C的每年的第几天 <br />%m 十进制表C的月䆾 <br />%M 十时制表C的分钟?<br />%n 新行W?<br />%p 本地的AM或PM的等hC?<br />%r 12时的时?<br />%R 昄时和分钟:hh:mm <br />%S 十进制的U数 <br />%t 水^制表W?<br />%T 昄时分U:hh:mm:ss <br />%u 每周的第几天Q星期一为第一?Qg0?Q星期一?Q?br />%U W年的第几周Q把星期日做为第一天(g0?3Q?br />%V 每年的第几周Q用基于周的年 <br />%w 十进制表C的星期几(g0?Q星期天?Q?br />%W 每年的第几周Q把星期一做ؓW一天(g0?3Q?<br />%x 标准的日期串 <br />%X 标准的时间串 <br />%y 不带世纪的十q制q䆾Qg0?9Q?br />%Y 带世U部分的十制q䆾 <br />%zQ?Z 时区名称Q如果不能得到时区名U则q回I字W?br />%% 癑ֈ?br /><br />如果xC现在是几点了,q以12时制显C,p下面q段E序Q?br /><br />Qi nclude “time.h?br />Qi nclude “stdio.h?br />int main(void)<br />{<br />struct tm *ptr;<br />time_t lt;<br />char str[80];<br />lt=time(NULL);<br />ptr=localtime(<);<br />strftime(str,100,"It is now %I %p",ptr);<br />printf(str);<br />return 0;<br />}<br /><br />其运行结果ؓQ?br />It is now 4PM<br /><br />而下面的E序则显C当前的完整日期Q?br /><br />Qi nclude <stdio.h /><br />Qi nclude <time.h /><br /><br />void main( void )<br />{<br />        struct tm *newtime;<br />        char tmpbuf[128];<br />        time_t lt1;<br />        time( <1 );<br />        newtime=localtime(<1);<br />        strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", newtime);<br />        printf(tmpbuf);<br />}<br /><br />q行l果Q?br /><br />Today is Saturday, day 30 of July in the year 2005.<br /><br />4.5 计算持箋的时间长?br /><br />有时候在实际应用中要计算一个事件持l的旉长度Q比如计打字速度。在W?节计旉分中Q我已经用clock函数举了一个例子。Clock()函数可以_到毫U。同Ӟ我们也可以用difftime()函数Q但它只能精到U。该函数的定义如下:<br /><br />double difftime(time_t time1, time_t time0);<br /><br />虽然该函数返回的以秒计算的时间间隔是doublecd的,但这q不说明该时间具有同double一L_度,q是由它的参数觉得的Qtime_t是以Uؓ单位计算的)。比如下面一D늨序:<br /><br />Qi nclude “time.h?br />Qi nclude “stdio.h?br />Qi nclude “stdlib.h?br />int main(void)<br />{<br />time_t start,end;<br />start = time(NULL);<br />system("pause");<br />end = time(NULL);<br />printf("The pause used %f seconds.\n",difftime(end,start));//<-<br />system("pause");<br />return 0;<br />}<br /><br />q行l果为:<br />hL键l? . .<br />The pause used 2.000000 seconds.<br />hL键l? . .<br /><br />可以惛_Q暂停的旉q不那么巧是整整2U钟。其实,你将上面E序的带有?/<-”注释的一行用下面的一行代码替换:<br /><br />printf("The pause used %f seconds.\n",end-start);<br /><br />其运行结果是一L?br /><br />4.6 分解旉转化为日历时?br /><br />q里说的分解旉是以年、月、日、时、分、秒{分量保存的旉l构Q在C/C++中是tml构。我们可以用mktimeQ)函数用tml构表示的时间{化ؓ日历旉。其函数原型如下Q?br /><br />time_t mktime(struct tm * timeptr);<br /><br />其返回值就是{化后的日历时间。这h们就可以先制定一个分解时_然后对这个时间进行操作了Q下面的例子可以计算?997q??日是星期几:<br /><br />Qi nclude "time.h"<br />Qi nclude "stdio.h"<br />Qi nclude "stdlib.h"<br />int main(void)<br />{<br />struct tm t;<br />time_t t_of_day;<br />t.tm_year=1997-1900;<br />t.tm_mon=6;<br />t.tm_mday=1;<br />t.tm_hour=0;<br />t.tm_min=0;<br />t.tm_sec=1;<br />t.tm_isdst=0;<br />t_of_day=mktime(&t);<br />printf(ctime(&t_of_day));<br />return 0;<br />}<br /><br />q行l果Q?br /><br />Tue Jul 01 00:00:01 1997<br /><br />现在注意了,有了mktime()函数Q是不是我们可以操作现在之前的Q何时间呢Q你可以通过q种办法出1945q??5h星期几吗Q答案是否定的。因个时间在1970q??日之前,所以在大多数编译器中,q样的程序虽然可以编译通过Q但q行时会异常l止?br /><br />5Qȝ<br /><br />本文介绍了标准C/C++中的有关日期和时间的概念Qƈ通过各种实例讲述了这些函数和数据l构的用方法。笔者认为,和时间相关的一些概忉|相当重要的,理解q些概念是理解各U时间格式的转换的基Q更是应用这些函数和数据l构的基?br /></p> </div> </td> </tr> </tbody> </table> <img src ="http://m.tkk7.com/Archangelsy/aggbug/112829.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/Archangelsy/" target="_blank">archangel</a> 2007-04-22 22:47 <a href="http://m.tkk7.com/Archangelsy/articles/112829.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> C++中constȝ Q{Q?/title><link>http://m.tkk7.com/Archangelsy/articles/112828.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Sun, 22 Apr 2007 14:46:00 GMT</pubDate><guid>http://m.tkk7.com/Archangelsy/articles/112828.html</guid><wfw:comment>http://m.tkk7.com/Archangelsy/comments/112828.html</wfw:comment><comments>http://m.tkk7.com/Archangelsy/articles/112828.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/Archangelsy/comments/commentRss/112828.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/Archangelsy/services/trackbacks/112828.html</trackback:ping><description><![CDATA[ <table cellspacing="0" cellpadding="0" width="98%" align="center" border="0"> <tbody> <tr> <td> </td> </tr> <tr> <td> <p style="WORD-BREAK: break-all; LINE-HEIGHT: 16pt; WORD-WRAP: break-word"> <span id="91tlzzr" class="bt"> <br />一、对于基本声?<br />1.const int r=100; //标准const变量声明加初始化Q因为默认内部连接所以必被初始化,其作用域为此文gQ编译器l过cd查后直接?00在编译时替换?<br /><br />2.extend const int r=100; //const改ؓ外部q接Q作用于扩大臛_局Q编译时会分配内存,q且可以不进行初始化Q仅仅作为声明,~译器认为在E序其他地方q行了定义?<br /><br />3.const int r[ ]={1,2,3,4}; <br />struct S {int a,b;}; <br />const S s[ ]={(1,2),(3.4)}; //以上两种都是帔R集合Q编译器会ؓ其分配内存,所以不能在~译期间使用其中的|例如Qint temp[r[2]];q样的编译器会报告不能找到常量表辑ּ <br /><br />二、对于指?<br />1.const int *r=&x; //声明rZ个指向常量的x的指针,r指向的对象不能被修改Q但他可以指向Q何地址的常量?<br /><br />2.int const *r=&x; //与用?完全{h(hun)Q没有Q何区别?<br /><br />3.int * const r=&x; //声明rZ个常量指针,他指向xQrq个指针的指向不能被修改Q但他指向的地址的内容可以修攏V?<br /><br />4.const int * const r=&x; //l合1?用法Qr是一个指向常量的帔R型指针?<br /><br />三、对于类型检?<br />可以把一个非const对象赋给一个指向const的指针,因ؓ有时候我们不想从q个指针来修改其对象的|但是不可以把一个const对象赋值给一个非const指针Q因样可能会通过q个指针改变指向对象的|但也存在使这U操作通过的合法化写法Q用类型强制{换可以通过指针改变const对象Q?<br />const int r=100; <br />int * ptr = const_cast(&r); //C++标准QC语言使用Qint * ptr =(int*)&r; <br /><br />四、对于字W数l?<br />如char * name = “china? q样的语句,在编译时是能够通过的,但是”china”是帔R字符数组QQ何想修改他的操作也能通过~译但会引vq行旉误,如果我们想修改字W数l的话就要用char name[ ] = “china? q种形式?<br /><br />五、对于函?<br />1.void Fuction1 ( const int r ); //此处为参C递const|意义是变量初g能被函数改变 <br /><br />2.const int Fuction1 (int); //此处q回const|意思指q回的原函数里的变量的初g能被修改Q但是函数按D回的q个变量被制成副本,能不能被修改没有了意义Q它可以被赋lQ何的const或非constcd变量Q完全不需要加上这个const关键字。但q只对于内部cd而言Q因为内部类型返回的肯定是一个|而不会返回一个变量,不会作ؓ左g用)Q对于用戯定义cdQ返回值是帔R是非帔R要的Q见下面条款3?<br /><br />3.Class CX; //内部有构造函敎ͼ声明如CX(int r =0) <br />CX Fuction1 () { return CX(); } <br />const CX Fuction2 () { return CX(); } <br />如有上面的自定义cCXQ和函数Fuction1()和Fuction2(),我们q行如下操作Ӟ <br />Fuction1() = CX(1); //没有问题Q可以作为左D?<br />Fuction2() = CX(1); //~译错误Qconstq回值禁止作为左D用。因为左值把q回g为变量会修改其返回|const声明止q种修改?<br /><br />4.函数中指针的const传递和q回Q?<br />int F1 (const char * pstr); //作ؓ传递的时候用const修饰可以保证不会通过q个指针来修改传递参数的初|q里在函数内部Q何修?pstr的企N会引L译错误?<br />const char * F2 (); //意义是函数返回的指针指向的对象是一个const对象Q它必须赋给一个同h指向const对象的指针?<br />const char * const F3(); //比上面多了一个constQ这个const的意义只是在他被用作左值时有效Q它表明了这个指针除了指向const对象外,它本w也不能被修改,所以就不能当作左值来处理?<br /><br />5.函数中引用的const传递: <br />void F1 ( const X& px); //q样的一个const引用传递和最普通的函数按g递的效果是一模一LQ他止对引用的对象的一切修改,唯一不同的是按g递会先徏立一个类对象的副本,然后传递过去,而它直接传递地址Q所以这U传递比按g递更有效?<br />**另外只有引用的const传递可以传递一个时对象,因ؓ临时对象都是const属性,且是不可见的Q他短时间存在一个局部域中,所以不能用指针,只有引用的const传递能够捕捉到q个家伙?<br /><br />六、对于类 <br />1.首先Q对于const的成员变量,只能在构造函数里使用初始化成员列表来初始化,试图在构造函C内进行初始化const成员变量会引L译错误。初始化成员列表形如Q?<br />2.X:: X ( int ir ): r(ir) {} //假设r是类X的const成员变量 <br /><br />2.const成员函数。提到这个概念首先要谈到const对象Q正象内|类型能够定义const对象一Pconst int r=10;Q,用户自定义类型也可以定义const对象(const X px(10);)Q编译器要保证这个对象在其生命周期内不能够被改变。如果你定义了这L一个const对象Q那么对于这个对象的一切非const成员函数的调用,~译器ؓ了保证对象的constҎ(gu),都会止q在~译期间报错。所以如果你惌你的成员函数能够在const对象上进行操作的话,p把这个函数声明ؓconst成员函数。假如f( )是类中的成员函数的话Q它的声明Ş如: <br />int f( ) const; //const攑֜函数的最后,~译器会对这个函数进行检查,在这个函C的Q何试图改变成员变量和调用非const成员函数的操作都被视为非?<br />注意Q类的构造和析构函数都不能是const函数?<br /><br />3.建立了一个const成员函数Q但仍然想用q个函数改变对象内部的数据。这L一个要求也会经帔R刎ͼ其是在一个苛ȝ面试考官那里。首先我们要弄清楚考官的要求,因ؓ有两U方法可以实玎ͼ如果q位考官要求不改变原来类的Q何东西,只让你从当前q个const成员函数入手Q那么你只有使用前面提到的类型强制{换方法。实例如下: <br />//假如有一个叫做X的类Q它有一个int成员变量rQ我们需要通过一个const成员函数f( )来对q个rq行++r操作Q代码如?<br />void X::f( ) const <br />{ (const_cast(this)) -> ++r; } //通过this指针q行cd强制转换实现 <br />另外一U方法就是用关键字Qmutable。如果你的成员变量在定义时是q个样子的: <br />mutable int r ; <br />那么它就告诉~译器这个成员变量可以通过const成员函数改变。编译器׃会再理会对他的检查了?<br /><br />Q这个ȝq不错的?</span> <br /> </p> </td> </tr> </tbody> </table> <img src ="http://m.tkk7.com/Archangelsy/aggbug/112828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/Archangelsy/" target="_blank">archangel</a> 2007-04-22 22:46 <a href="http://m.tkk7.com/Archangelsy/articles/112828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于CONST的用??http://m.tkk7.com/Archangelsy/articles/112827.htmlarchangelarchangelSun, 22 Apr 2007 14:45:00 GMThttp://m.tkk7.com/Archangelsy/articles/112827.htmlhttp://m.tkk7.com/Archangelsy/comments/112827.htmlhttp://m.tkk7.com/Archangelsy/articles/112827.html#Feedback0http://m.tkk7.com/Archangelsy/comments/commentRss/112827.htmlhttp://m.tkk7.com/Archangelsy/services/trackbacks/112827.html
const在C语言中算是一个比较新的描q符Q我们称之ؓ帔R修饰W,意即其所修饰
的对象ؓ帔R(immutable)?br />
我们来分情况看语法上它该如何被用?br />
1、函C内修饰局部变量?br />例:
void func(){
const int a=0;
}

首先Q我们先把constq个单词忽略不看Q那么a是一个intcd的局部自动变量,
我们l它赋予初始??br />
然后再看const.

const作ؓ一个类型限定词Q和int有相同的C?br />const int a;
int const a;
是等L。于是此处我们一定要清晰的明白,const修饰的对象是谁,是a,和int?br />有关pRconst 要求他所修饰的对象ؓ帔RQ不可被改变Q不可被赋|不可作ؓ
左|l-value)?br />q样的写法也是错误的?br />const int a;
a=0;
q是一个很常见的用方式:
const double pi=3.14;
在程序的后面如果企图对pi再次赋值或者修改就会出错?br />
然后看一个稍微复杂的例子?br />const int* p;
q是先去掉const 修饰W号?br />注意Q下面两个是{h(hun)的?br />int* p;
int *p;
其实我们惌说的是,*p是intcd。那么显Ӟp是指向int的指针?br />同理
const int* p;
其实{h(hun)?br />const int (*p);
int const (*p);
卻I*p是常量。也是_p指向的数据是帔R?br />于是
p+=8; //合法
*p=3; //非法Qp指向的数据是帔R?br />
那么如何声明一个自w是帔R指针呢?Ҏ(gu)是让const可能的靠近p;
int* const p;
const右面只有p,昄Q它修饰的是p,说明p不可被更攏V然后把constLQ可?br />看出p是一个指?int形式变量的指针?br />于是
p+=8; //非法
*p=3; //合法

再看一个更复杂的例子,它是上面二者的l合
const int* const p;
说明p自己是常量,且p指向的变量也是常量?br />于是
p+=8; //非法
*p=3; //非法

const q有一个作用就是用于修饰常量静态字W串?br />例如Q?br />const char* name="David";
如果没有const,我们可能会在后面有意无意的写name[4]='x'q样的语句,q样?br />D对只d存区域的赋|然后E序会立d常终止。有?const,q个错误?br />能在E序被编译的时候就立即查出来,q就是const的好处。让逻辑错误在编?br />期被发现?br />
const q可以用来修饰数l?br />const char s[]="David";
与上面有cM的作用?br />
2、在函数声明时修饰参?br />来看实际中的一个例子?br />NAME
memmove -- copy byte string

LIBRARY
Standard C Library (libc, -lc)

SYNOPSIS
#include <string.h>

void *
memmove(void *dst, const void *src, size_t len);

q是标准库中的一个函敎ͼ用于按字节方式复制字W串Q内存)?br />它的W一个参敎ͼ是将字符串复制到哪里去(dest),是目的地Q这D内存区域必?br />是可写?br />它的W二个参敎ͼ是要什么样的字W串复制出去Q我们对q段内存区域只做?br />取,不写?br />于是Q我们站在这个函数自q角度来看Qsrc q个指针Q它所指向的内存内所?br />储的数据在整个函数执行的q程中是不变。于是src所指向的内Ҏ(gu)帔R。于是就
需要用const修饰?br />例如Q我们这里这样用它?br />const char* s="hello";
char buf[100];
memmove(buf,s,6); //q里其实应该用strcpy或memcpy更好

如果我们反过来写Q?br />memmove(s,buf,6);
那么~译器一定会报错。事实是我们l常会把各种函数的参数顺序写反。事实是~?br />译器在此时帮了我们大忙。如果编译器静?zhn)?zhn)的不报错,(在函数声明处L
const卛_),那么q个E序在运行的时候一定会崩溃?br />
q里q要说明的一Ҏ(gu)在函数参数声明中const一般用来声明指针而不是变量本w?br />例如Q上面的size_t len,在函数实现的时候可以完全不用更改len的|那么是否
应该把len也声明ؓ帔R呢?可以Q可以这么做。我们来分析q么做有什么优劣?br />如果加了const,那么对于q个函数的实现者,可以防止他在实现q个函数的时候修
改不需要修改的?len),q样很好?br />但是对于q个函数的用者,
1。这个修饰符h无意义,我们可以传递一个常量整数或者一个非帔R整数q?br />去,反正Ҏ(gu)获得的只是我们传递的一个copy?br />2。暴露了实现。我不需要知道你在实现这个函数的时候是否修改过len的倹{?br />
所以,const一般只用来修饰指针?br />
再看一个复杂的例子
int execv(const char *path, char *const argv[]);
着重看后面q个Qargv.它代表什么?br />如果Lconst,我们可以看出
char * argv[];
argv是一个数l,它的每个元素都是char *cd的指针?br />如果加上const.那么const修饰的是谁呢Q他修饰的是一个数l,argv[],意思就?br />说这个数l的元素是只ȝ。那么数l的元素的是什么类型呢Q是char *cd的指
?也就是说指针是常量,而它指向的数据不是?br />于是
argv[1]=NULL; //非法
argv[0][0]='a'; //合法


3、全局变量?br />我们的原则依然是Q尽可能的使用全局变量?br />我们的第二条规则 则是Q尽可能多的使用const?br />如果一个全局变量只在本文件中使用Q那么用法和前面所说的函数局部变量没有什
么区别?br />如果它要在多个文仉׃nQ那么就牉|C个存储类型的问题?br />
有两U方式?br />1.使用extern
例如
/* file1.h */
extern const double pi;
/* file1.c */
const double pi=3.14;
然后其他需要用piq个变量的,包含file1.h
#include "file1.h"
或者,自己把那句声明复制一遍就好?br />q样做的l果是,整个E序链接完后Q所有需要用piq个变量的共享一个存储区域?br />
2.使用static,静态外部存储类
/* constant.h */
static const pi=3.14;
需要用这个变量的*.c文g中,必须包含q个头文件?br />前面的static一定不能少。否则链接的时候会报告说该变量被多ơ定义?br />q样做的l果是,每个包含了constant.h?.c文gQ都有一份该变量自己的copy,
该变量实际上q是被定义了多次Q占用了多个存储I间Q不q在加了static关键?br />后,解决了文仉重定义的冲突?br />坏处是浪费了存储I间Q导致链接完后的可执行文件变大。但是通常Q这个,小
几字节的变化Q不是问题?br />好处是,你不用关心这个变量是在哪个文件中被初始化的?br />

最后,说说const的作用?br />const 的好处,是引入了帔R的概念,让我们不要去修改不该修改的内存。直接的
作用是让更多的逻辑错误在编译期被发现。所以我们要可能的多用const?br />但是很多人ƈ不习惯用它Q更有甚者,是在整个E序 ~写Q调?完后才补
const。如果是l函数的声明补const,好。如果是l?全局Q局部变量补const,?br />么……那么,为时已晚Q无非是让代码看h更漂亮了?/div>


archangel 2007-04-22 22:45 发表评论
]]>
c++全局变量 的问?可能是~?/title><link>http://m.tkk7.com/Archangelsy/articles/104499.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Sat, 17 Mar 2007 11:25:00 GMT</pubDate><guid>http://m.tkk7.com/Archangelsy/articles/104499.html</guid><wfw:comment>http://m.tkk7.com/Archangelsy/comments/104499.html</wfw:comment><comments>http://m.tkk7.com/Archangelsy/articles/104499.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/Archangelsy/comments/commentRss/104499.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/Archangelsy/services/trackbacks/104499.html</trackback:ping><description><![CDATA[ <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">遇到一个怪现象?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">写的</span> <span lang="EN-US"> <font face="宋体, MS Song">VC</font> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">E序打开Q再关闭Q就会提C异常?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">q个E序使用?/span> <span lang="EN-US"> <font face="宋体, MS Song">ADO</font> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">一开始定义了一个全局的:</span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt">CAdoConnection <span style="mso-spacerun: yes"> </span>conn;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">后面每个c都直接用了</span> <span lang="EN-US"> <font face="宋体, MS Song">conn.</font> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">~~</span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">但是</span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">全局变量在初时化前引入,</span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">在退出时自动释放Q无法控刉攄地方?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> <font face="宋体, MS Song"> </font> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri">但用指针Q?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt">CAdoConnection <span style="mso-spacerun: yes"> </span>*pConn;<o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt">pConn = <span style="mso-spacerun: yes"> </span>new <span style="mso-spacerun: yes"> </span>CAdoConnection();<o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt">pConn-></span> <span style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">~~</span> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以控制它的释放了Q?/span> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: blue; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt">delete</span> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt"> <span style="mso-spacerun: yes"> </span>pConn;<o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">好像是这个道理吧?/span> <span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <img src ="http://m.tkk7.com/Archangelsy/aggbug/104499.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/Archangelsy/" target="_blank">archangel</a> 2007-03-17 19:25 <a href="http://m.tkk7.com/Archangelsy/articles/104499.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>time函数http://m.tkk7.com/Archangelsy/articles/104498.htmlarchangelarchangelSat, 17 Mar 2007 11:19:00 GMThttp://m.tkk7.com/Archangelsy/articles/104498.htmlhttp://m.tkk7.com/Archangelsy/comments/104498.htmlhttp://m.tkk7.com/Archangelsy/articles/104498.html#Feedback1http://m.tkk7.com/Archangelsy/comments/commentRss/104498.htmlhttp://m.tkk7.com/Archangelsy/services/trackbacks/104498.html阅读全文

archangel 2007-03-17 19:19 发表评论
]]>
վ֩ģ壺 ޳һ| þ4438| avר| δʮ˽˸ӰԺ| AVרӰ | ëƬڵ| ŷղ| һƵ | ƷһëƬ| avþDz| Ʒަv| ޸ľƷŮ| ۺɫ¶| ҹҹҹҹƵ| һҳ| gavѲƵ| 18ŮվɫƬѹۿ| 97Ʒѹۿ| վѹۿ| Ƶ| Ƶѹۿwww| һëƬ| ƯŮ| ޹ۺ| 椸Ƶۿ| þѹۿƷ88av| ޾Ƶ| ׾ƷͼƬ| av뾫Ʒվ| ޾Ʒһ| Ů18һëƬѹۿ| ƵĻȫ| Ʒ˳վ| Avۺ辫Ʒ| ¶ۺƵ| ƵŷƵ| þ99޾Ʒۿ| 츾AV߲| ˳ɹƷ| һ| ձvƬһ|