CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
英特尔®游戏设计大赛100美元现金周周送 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

阅读帖子:),阅读ANSI C标准,寻找裨益与乐趣.

楼主LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)2003-11-01 20:36:49 在 C/C++ / C语言 提问

//1.    
  void   foo(const   char   *p)   {}  
   
  int   main(int   argc,   char   *argv)  
  {  
          foo(argv);  
          return   0;  
  }  
   
   
  //2.    
  void   foo(const   char   **p)   {}  
   
  int   main(int   argc,   char   **argv)  
  {  
          foo(argv);  
          return   0;  
  }  
   
   
  第一个例子正确是因为实参   char   *   能与   const   char   *   匹配,所指的的类型相容,形参所指类型具有实参所指类型的全部限定符.  
   
  第二个例子错误是因为实参指向   char   *   ,   形参指向   const   char   *   ,因此它们不相容.  
   
   
   
   
  ////////////////  
  问题:  
   
  第一个例子说因为   char   *   与   const   char   *   匹配.  
  照这样在第二个例子实参,形参指向是匹配的,但是实际上编译器并不认为这是对的.  
  难道仅仅是因为从字面上来看实参指向   char   *   ,   形参指向   const   char   *   ,由于确实是多了一个词语   "const",就解释它们不相容吗?  
  问题点数:100、回复次数:47Top

1 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-01 20:47:18 得分 0

时针  
   
  梁崇正  
   
   
   
  昨夜她曾经  
  窸   在酣梦阶缘  
  徘徊于百叶窗下玫瑰园中  
  裙带簌簌飘身来去  
  她无声地叹息弥漫着  
  侏罗纪琥珀的松香  
  和远方一千座森林的低嗓  
  为梦境增添了绚丽  
  圆镜前她举臂  
  比划每款梳妆的慵姿  
  纤指牵引着潮夕  
  重划了星图  
  抚平愤懑和忧伤  
  花廊下钟声里  
  我顾视再三  
  读解她挥舞的手势  
   
   
  google.com居然无能啊,但是百度却可以:)  
  好诗与大家分享,这是我最近读到的最爱的诗.  
  Top

2 楼Jethill(生儿子之前,老婆说她喜欢女儿!)回复于 2003-11-01 20:52:34 得分 0

good.Top

3 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-01 20:57:52 得分 0

窸窣  
   
  掉了一个字,原先在google上没有找到,所以用手输入的。但是我打拼音却没有找到窸字。  
  原载台湾中央日报。看一看台湾有好优秀的诗人啊!Top

4 楼Wolf0403(废人:独活十年~心如刀割)回复于 2003-11-01 21:01:08 得分 0

她无声地叹息弥漫着  
  侏罗纪琥珀的松香  
   
  她是恐龙?哈哈  
   
  =================================================================  
   
  int   main(int   argc,   char   *argv)  
  这个难道可以编译?我不相信。main   的   proto   只有两种  
  int   main(void)  
  int   main(int,   char   **)  
   
  =================================  
  试验了一下,居然真的可以。。。想不通Top

5 楼plainsong(短歌)()回复于 2003-11-01 21:49:43 得分 20

从T   *   到const   T   *的转换是允许的。  
   
  而从类型A到类型B可转换并不代表从A*到B*可转换。比如int到double是可以的,但从int*到double*则不行。  
   
  而char**   和 const   char   **   相当于:  
  typedef   char   *   char_pointer;  
  typedef   const   *   const_char_pointer;  
  char_pointer*   到const_char_pointer的转换则不允许,它们不是T与const   T的关系。  
   
  标准C++中限制main只能有两种原型,不过在C中可能没有这个限制。同时很多C++编译器也放宽了这个限制,在Windows上的编译器通常至少还可以用int   main(int,   char**,   char**)的原型。Top

6 楼mmlymlymly(mly)回复于 2003-11-01 21:53:06 得分 0

台湾诗人还得给恐龙写诗,可怜....  
  开个玩笑,楼主在这恐怕很难遇到知音的,还不如贴段优雅的代码上来:)  
  话归正题,  
  第一个例子正确是因为实参   char   *   能与   const   char   *   匹配,所指的的类型相容,不是相容,是相同,都是char!,当然也可以是const   char   。这里const主要是c++语法提供对这类指针用法的一个约束。  
  第二个例子错误是因为实参指向   char   *   ,   形参指向   const   char   *   ,因此它们不相容.  
  至于他们为什么不相容,语法问题吧:)  
  Top

7 楼mmlymlymly(mly)回复于 2003-11-01 22:01:52 得分 0

恩  
  同意plainsong(短歌)    
  char   *   和const   char   *   编译器把他们作为两种类型时没有允许他们得指针可以转换!  
  就像int   和   double一样。  
  为我上面愚拙的解释抱歉....Top

8 楼mmlymlymly(mly)回复于 2003-11-01 22:09:19 得分 0

由此又想到一个问题  
  如果真是这种解释的话,对于任何两种类型,是不是他们的多级指针都不能互相转换。  
  编译器不可能每层都定义...Top

9 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-01 22:12:50 得分 0

在看   "Expert   c   programming"   遇到这个问题。我比较笨,还没有明白啊。  
   
  语言律师:从一本很厚的字典里面找出5句话,摆在你面前,来证明正确观点。并使你有意想不到的收获。  
   
  呵呵,有请有请!Top

10 楼ckacka(/*小红帽*/ckacka();)回复于 2003-11-02 00:19:18 得分 20

正确的用法是:  
  ____________________________________________________  
   
  void   foo(char*   const   *p)   {}  
   
  int   main(int   argc,   char   **argv)  
  {  
          foo(argv);  
          return   0;  
  }  
  ____________________________________________________  
   
  其原因在于const是一个左结合的操作符  
  上面的代码的const正好修饰了char*这样一个类型,即字符串类型,起到了保护传入参数的作用。  
   
   
   
   
   
   
  关于main的形式C++98和C99一样,都指定了两种基本的形式:  
  ____________________________________________________  
   
  int   main()  
   
  int   main(int   argc,   char   *argv[])  
  ____________________________________________________  
   
  但是,同时也补充说明他们在编译器上的实现不是唯一的,而是是至少的,即不同的实现可以有自己的扩充Top

11 楼ALNG(?)回复于 2003-11-02 12:25:51 得分 20

说实在的,我也学了一招。  
   
  plainsong和ckacka的解释应该是合理的。  
   
   
  但是我看不出如果标准允许这种从较宽松的类型到较严格类型的转换或赋值会有什么不利的后果,比如破坏const语义之类。  
   
  试想:  
  const   char   cc='E';  
  char   c;  
   
  const   char   *pcc=&cc;  
  char   *pc   =   &c;  
   
  //   下面的选一  
  const   char   **ppcc   =&pcc;   //   当然合法  
  const   char   **ppcc   =&pc;   //   不合法,就是所讨论的情形。但是如果标准允许这种赋值  
                              //   会有不利后果吗。我觉得不会。ppcc放弃了通过自己修改**ppcc的权利  
                              //   难道放弃权利也有错吗?  
   
  //   至于另外两种组合之一  
  char   **ppc   =   &pcc;   //   当然不合法,可能破坏了const语义,要求了更多权力。  
  char   **ppc   =   &pc;   //   当然合法  
   
  想就ppcc   =   &pc;   可能有什么潜在危害请教plainsong和ckacka.    
   
   
  Top

12 楼williamVII(spread)回复于 2003-11-02 12:41:35 得分 0

学习Top

13 楼plainsong(短歌)()回复于 2003-11-02 14:52:35 得分 0

我觉得危害应该是没有的,这样规定大概是为了方便编译器。  
   
  const   char   *和char   *被认为是两种不同的类型,它们之间存在着单向的转换,而两种类型的指针类型是不允许转换的,就象我说过的int*到double*。我想应该是语言上没有对指针类型作特殊的规定的原因吧。Top

14 楼chinajiji(菜鸟叽叽)回复于 2003-11-02 19:25:13 得分 20

我觉得   ALNG(?)   (   )     的分析很是击中要害.  
   
  我也没有搞清楚这是这么回事,不过我只是想到了一个解决方案,从这个解决方案中似乎可以说点什么问题:  
  先看   ALNG(?)   (   )的这个例子:  
  const   char   **ppcc   =&pc;   //   不合法,就是所讨论的情形。但是如果标准允许这种赋值  
                              //   会有不利后果吗。我觉得不会。ppcc放弃了通过自己修改**ppcc的权利  
                              //   难道放弃权利也有错吗?  
   
  我给出的解决方案是:  
  const   char   **ppcc1   =const_cast<const   char**>(&pc);  
   
  这说明这里仅牵涉到const   modifier   而不存在plainsong(短歌)所说的"类型不同"的因素,因为char**   与   const   char**之间的转换只涉及const   modifier的不同,与int*   与   double*之间的转换各是两码事.  
   
  我给出的那个例子也应证了ckacka的那个修改案例:void   foo(char*   const   *p)   {}  
   
  如果我们采用ckacka的这做方案的话,这句:  
   
  const   char   **ppcc   =&pc;  
  就应该改为:  
  const   char   *const*ppcc   =&pc;  
   
  ckacka这做改法有个小问题,就是不能使这句合法:  
  (*ppcc)++;  
  因为(*ppcc)是const   pointer.  
   
  但对于:  
  const   char   cc='E';  
  const   char   *pcc=&cc;  
  const   char   **ppcc   =&pcc;    
  下面这句是合法的.  
  (*ppcc)++;  
   
  如果用我的哪个方案改:  
  const   char   **ppcc1   =const_cast<const   char**>(&pc);  
  则下面的语句同样是合法的,这样就保证了从char**到const   char**语意的完整性:  
  (*ppcc)++;  
   
  总之,我觉得问题的关键出现在一级指针上,即(*ppcc)上,可能是因为从char**转换到const   char**时,出现了一个临时变量指针char*,这个临时指针变量只能绑定到char   const*上才能正确(但我不能肯定这种分析是否正确).但我觉得从语意上分析,从char**到转换const   char**的转换是合法且合理的.我还没有找到一个实际的例子说明这种转换会造成不安全的因素.  
   
   
  Top

15 楼plainsong(短歌)()回复于 2003-11-02 21:05:17 得分 0

chinajiji说的对,从char   **到const   char**不能转换应该和int*到double*的问题是不一样的,我的想法不对。  
   
  不过,C99中有const_cast吗?  
   
  这个问题如果拿到C++中还有一个相似的表现:  
  class   A{public:virtual   ~A(){}};  
  class   B{};  
  ...  
  A   **   x;  
  B   **   y;  
   
  *x   =   *y;//正确  
  x   =   y;//错误  
  这个表现用const_cast都无法解决了,只能用最令人心惊胆颤的reinterpret_cast了。  
   
  对于这个问题,我怀疑标准中并没有规定不能隐式转换,只是标准中只规定了某些情况下指针类型可以隐式转换,而再没有对多级指针明确说明的情况下,编译器的实现中没有允许这种转换的存在,只能使用显示转换来处理了。Top

16 楼ALNG(?)回复于 2003-11-02 23:06:51 得分 0

plainsong的这个例子和LoveCreatesBeauty   (微笑在一瞬间   但记忆伴随一生)的例子很类似,也很有意思。  
   
  他们的相同点是都是从更严格到更宽松的类型的2级指针转换,语义上都是安全合理的,而都被标准所不容。[至于使用cast,   虽然不一定会有运行时间的开销,但毕竟要多敲那么多字]  
   
  确实可能是为了方便C++编译器厂商。Top

17 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-02 23:15:21 得分 0

ALNG大哥,我的问题是从Expert   C   Programming上摘下来的.   书上的解释我没有看懂.Top

18 楼ckacka(/*小红帽*/ckacka();)回复于 2003-11-03 01:29:22 得分 0

to   chinajiji:  
          不,楼主的问题是函数传参数的问题,是要求解决保护传入参数的问题,和ALNG(?)以及plainsong(短歌)的提法是不同的。  
          如果要想在函数内遍历传入的每个字符串的每个字符,申明一个迭代子就是了。  
   
  to   LoveCreatesBeauty(微笑在一瞬间   但记忆伴随一生):  
          书上怎么说的,帖出来看看!  
   
   
   
  顺便补充一下:  
          const和*操作符都是具有左结合的性质的。Top

19 楼ckacka(/*小红帽*/ckacka();)回复于 2003-11-03 01:31:38 得分 0

记住这个特性,对C/C++不熟悉的朋友就不怕在测试中遇到那种const和*位置“飘忽不定”的试题了Top

20 楼ALNG(?)回复于 2003-11-03 06:12:16 得分 0

我觉得是一样的。  
   
  如果允许这样赋值,参数传递必然也会允许;反之亦然。  
   
  Top

21 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 08:46:10 得分 0

代码后面的两段话大致就是书上的解释。我再想办法贴多点书上的原文。  
  多谢大家。Top

22 楼windyguy()回复于 2003-11-03 08:56:50 得分 0

书中已经讲得很明白了的。  
  const   char   *p1;  
  char   *p2;  
  都是指向char的指针,只是一个多了const修饰符。  
  但是const   char   **p1;  
  char   **p2;  
  就截然不同了,p1指向const   char*,而p2指向char*。两个指向不同类型的指针是不同的。Top

23 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 13:21:49 得分 0

windyguy您好,  
   
  const   char   **p1;  
  char   **p2;  
   
  p1指向const   char*   ,  
  p2指向char*   ,  
  也只是多了一个   const   限定符.   const   是决定不同类型的因素吗?Top

24 楼merlinran(天行者)回复于 2003-11-03 18:14:02 得分 20

今天下午查标准,绞尽脑汁,才发现这个问题只需要用通常的类型转换法则就可以解释。  
   
  依据C99标准6.2.5[26]和C++98标准3.9.3[1],带有const、volatile(C99还有个restrict)限定的类型,与不带这些限定的是不同的类型,但要求有同样的表示和对齐方式。所以const   T和T是两种不同的类型。const   T*   和T*当然更是不同的类型。但这与讨论的主题没有多大关系。  
   
  在4.4[1]中,明确规定了由T*转换到const   T*的合法性,这里只需要一步类型转换。  
   
  T**无法转换为const   T**,因为T*和const   T*是两种不同的类型,而且它们之间没有直接的转换渠道。可以用中间变量来辅助这种转换:  
  const   T**   convert(T**   t)  
  {  
  return   &((const   T*)*t);  
  }  
   
  这种关系就像三个没有继承关系的类型A,B,C:A可以转换为B,B可以转换为C,并不代表A就可以直接转换为C。  
  举个例子:  
  class   MyObj   {  
  MyObj(const   std::string&);  
  //...  
  };  
  f(const   MyObj&   obj);  
   
  f("CSDN   is   good!");   //   error!   const   char*   -->   std::string   -->   Myobj   not   acceptable  
   
  f(std::string("CSDN   is   good!"));   //   ok!  
   
  如果我们允许多级的类型转换,不仅编译器难以实现,程序员也会遭遇大大的不幸。Top

25 楼merlinran(天行者)回复于 2003-11-03 18:18:51 得分 0

关于const位置的问题,我以前也时常弄混。后来从一个外国人那里学了一招,以星号为分界线,左边的const修饰指向的类型,右边的const修饰指针本身。如果是多级指针,也以此类推。  
  从此以后再也不混淆了。大家不妨一试。Top

26 楼merlinran(天行者)回复于 2003-11-03 18:26:25 得分 0

[quote]  
  return   &((const   T*)*t);  
  [/quote]  
  哈哈,搞错了。不能对右值取地址的。  
  Top

27 楼plainsong(短歌)()回复于 2003-11-03 19:06:12 得分 0

位置问题其实很容易,把int、char、const等看作是unary   operator,与*同级,优先级从右向左结合就行了:  
  const   char   **   p;  
  p是指针   指向指针   指向字符   字符是常量:指向(指向(字符常量)的指针)的指针  
  char   const   **   p;  
  p是指针   指向指针   指向常量   常量是字符:指向(指向(常量字符)的指针)的指针  
  上面两个含义是一样的  
   
  char   *   const   *   p;  
  p是指针   指向常量   常量是指针   指向字符:指向(常量:指向(字符)的指针)的指针,即“(指向)字符常量指针的指针”  
  char   *   *   const   p;  
  p是常量   常量是指针   指向指针   指向字符:常量:指向(指向(字符)的指针)的指针,即“(指向)字符指针的常量指针”  
   
  char   **   const   p   [35]  
  []操作符优先级最高(postfix   operator):  
  p是数组   数组存放常量   常量类型是指针   指向指针   指向字符:(指向)字符指针的常量指针的数组Top

28 楼mmlymlymly(mly)回复于 2003-11-03 20:16:56 得分 0

说了半天最初的问题还没有解决。  
  就是为什么指向char和const   char的指针编译器提供隐式转换  
  而指向char   *和const   char   *的指针就不可以,难道是编译器的规定。  
  Top

29 楼mmlymlymly(mly)回复于 2003-11-03 20:19:57 得分 0

to   merlinran(天行者):  
  你说的是A,B,C之间的转换关系问题  
  这里是A,B可转,A*,B*可否转的关系。  
  上面提到int   和   double   这样的一个范例,但问题是c++标准有否给出严格的说明Top

30 楼showming(刘效铭)回复于 2003-11-03 20:21:24 得分 0

什么呀!Top

31 楼ckacka(/*小红帽*/ckacka();)回复于 2003-11-03 20:49:21 得分 0

“而指向char   *和const   char   *的指针就不可以,难道是编译器的规定”  
  这是标准的规定!  
  连同这个:  
  “上面提到int   和   double   这样的一个范例,但问题是c++标准有否给出严格的说明”  
   
  实际上他们说明了同一个问题,因为int和double之间本身也涉及了一次隐式的转化Top

32 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 21:10:30 得分 0

多谢大家.   (多谢merlin被我追着帮我查标准,真诚感谢.)  
  以前我只是认为const限定符仅仅限定不能通过本标志符进行修改.如果它成为区别不同类型的因素,那自然   const   char   *   ,   char   *   是不同的类型,   指针   const   char   **   ,   char   **   也是不同的类型.  
   
  关于位置问题,   我个人有一些直觉上的区别(我个人感觉   plainsong   讲的台复杂了,   我没有看明白:)     ).        
   
  T   *               p;   //p是一个指针  
  T   *   const   p;   //p是一个常指针,因为   const   靠近它,直接修饰它.  
   
  因此推出即使如:  
  T   *******   const   p;   //p也是一个常指针.  
  (几乎是重复了   merlin   说的:)       )  
  Top

33 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 21:14:39 得分 0

当然   plainsong,   ckacka   是用语言本身,   用结合性来解释究竟是常指针还是指向常量的指针.   不过不知   Bjarne   或说   标准委员会当初究竟是怎样解释的呢?Top

34 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 21:36:44 得分 0

T   *******   const   p1;       //p1是一个常指针.  
   
  const   T   *******   p2;                   //p2是指针.但不是一个常指针.    
    //并且   *******   p2   不能被用作左值,   不能通过   p2   来修改所指的值,  
    //当然可以用另一个指针指向它,   再...  
    //(唔,我最好还是不要向大家灌输这种观点.   --   Peter   van   der   Linden   )  
   
  但是如果任由   const   在   星星之间游离(这应该是csdn星星们的专利:)     ),   我怕很快会脑筋打结.Top

35 楼chinajiji(菜鸟叽叽)回复于 2003-11-03 22:18:58 得分 0

有点赞同merlinran(天行者)的说法,  
  不过他给出的这个例子是不能通过编译的:  
   
  const   T**   convert(T**   t)  
  {  
  return   &((const   T*)*t);   //   不能通过编译,  
  }  
   
  只能这样:  
  const   T**   convert(T**   t)  
  {  
        T*   pt=   *t;  
  return   &((const   T*)pt);  
  }  
  也就是说,只能对一个指针变量做取址"&"操作,不能对一个变量的地址做取址操作;  
   
   
  Top

36 楼merlinran(天行者)回复于 2003-11-03 22:24:34 得分 0

--   Peter   van   der   Linden    
  这是什么签名?Joshua你好高深哟。  
  我确实是被你追着去查标准的,我自己几乎从来不用二重指针。也知道T**不能转为const   T**,觉得也没有什么不对,深究起来没啥意义。说实话,看你们在此讨论,我脑袋都已经打结了,今天一个下午都没理清。  
   
  [quote]  
  T**无法转换为const   T**,因为T*和const   T*是两种不同的类型,而且它们之间没有直接的转换渠道。  
  [/quote]  
  怎么我老是写错?T*和const   T*是两种不同的类型,但它们之间确实有直接的转换渠道,前一句才引用了标准,后一句就推翻了。T**和const   T**之间才是没有直接转换渠道。Top

37 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 22:36:51 得分 0

merlin你好,   我以前的标准还是   chinajiji   兄惠寄过来的(谢谢chinajiji)   .  
  但是我连一个u盘都买不起,   后来换公司后就遗失了.(Peter   van   der   Linden   is   the   writter)  
  恭喜你,我只有两个三角.以后多指教我啊.Top

38 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-03 22:53:22 得分 0

>就是为什么指向char和const   char的指针编译器提供隐式转换  
   
  char   *   pc;  
  const   char   *   pcc;  
  pcc   =   pc;  
  1.   都指向char,   因此属于相同类型的指针.  
  2.   左值具有右值全部的限定符.   即  
        左值限定符(无   +   const),    
        右值限定符(无   +   无).  
   
   
  >而指向char   *和const   char   *的指针就不可以,难道是编译器的规定。  
  char   *   和   const   char   *   按照merlin的话属于不同的类型  
  (">..带有const、volatile(C99还有个restrict)限定的类型,与不带这些限定的是不同的类型,但要求有同样的表示和对齐方式。所以const   T和T是两种不同的类型。const   T*   和T*当然更是不同的类型。..")  
   
  因此   char   **   和const   char   **   也是不同的.Top

39 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-04 13:28:52 得分 0

chinajiji兄的代码又让我学到很多知识,谢谢。Top

40 楼merlinran(天行者)回复于 2003-11-04 17:30:49 得分 0

[quote]  
  1.   都指向char,   因此属于相同类型的指针.  
  [/quote]  
  const   T和T是不同的类型,所以指向它们的指针属于*不同*类型的指针。莫搞错了哟。  
  为何这两种指针之间能够转换,那是标准里明确规定了的,并不是因为它们指向同样的类型。  
  Top

41 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-04 21:05:58 得分 0

我的书看得太少了,我要多看看书.谢谢.Top

42 楼merlinran(天行者)回复于 2003-11-05 18:38:15 得分 0

chinajiji(菜鸟叽叽),两颗星了,有前途。  
  chinajiji(菜鸟叽叽)说:  
  >>有点赞同merlinran(天行者)的说法,  
  >>不过他给出的这个例子是不能通过编译的:  
  >>  
  >>const   T**   convert(T**   t)  
  >>{  
  >> return   &((const   T*)*t);   //   不能通过编译,  
  >>}  
  >>  
  >>只能这样:  
  >>const   T**   convert(T**   t)  
  >>{  
  >>       T*   pt=   *t;  
  >> return   &((const   T*)pt);  
  >>}  
  >>也就是说,只能对一个指针变量做取址"&"操作,不能对一个变量的地址做取址操作;  
   
  我发了帖之后才编译,结果就发现编译不了。老是犯错。  
   
  你的代码可以编译,不过犯了个更大的错误。  
  convert的返回值指向的是个局域变量pt,而不是原来的*t,   返回之后这个pt就无效了。指向一个局域变量的指针...,你老兄应该能够想像其严重后果。Top

43 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-05 22:41:43 得分 0

pt   是个局部指针。是否那位兄弟有好的方案呢?Top

44 楼merlinran(天行者)回复于 2003-11-06 08:49:18 得分 0

我想不到什么情况需要把T**转换为const   T**,还是不深究的好。Top

45 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-06 08:53:20 得分 0

我想给大家加点信誉分,不过好像不能提交faq。Top

46 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-07 22:01:12 得分 0

http://www.csdn.net/news/newstopic/10/10305.shtml  
  《程序员》:关注程序员自己的文化——专访Tom   DeMarco    
  (2003.03.28)       来自:《程序员》杂志       熊节      
   
   
  CMM,一种过时的东西  
   
  《程》:我想知道您对CMM的态度。您认为CMM对哪些企业会有帮助?又会有哪些副作用?  
  TDM:帮助?CMM?对于如今的软件企业,CMM有百害而无一利。  
  《程》:我记得您曾经说过,在长期说来,CMM有助于提高生产率,只是在短期内会造成阻碍。  
  TDM:你记错了,我说的是“过程改进”,不是CMM。你知道吗,CMM已经有超过20年的历史,它的成功经验都是在1985年前获得的。CMM试图将一个固定的模型强加于一个日新月异的行业之上,它鼓励你效仿IBM在1970年代所采用的软件开发方式。僵化,不敢面对变化,这是如今的软件业最忌讳的。所以我要说,对于绝大多数的软件开发,CMM毫无帮助。  
  当然,一定的过程是有必要的。但是,在这个变化的时代里,过程也必须拥抱变化,否则就不是好的过程。你一定还记得,CMM2级的特征是“可重复”,我认为这根本就是一个悖论:我们的每个项目都完全不同,我们的开发环境每年都在更新,如何去寻求一个“可重复”的过程呢?你看,所有伟大的软件企业,有哪一家做的事情是“可重复”的呢?  
   
  《程》:可是有那么多人、那么多企业热衷于CMM呢。  
  TDM:他们根本就是无可适从——他们无法适应变化,他们无法在这种全新的环境中找到自己的位置,所以他们总得给自己找点什么东西来信仰。William   Clifford曾经说过,人们常常会根据自己的愿望而虔诚地相信一些东西,但愿望的强烈并不能使信仰变得可靠。  
  不过,对于只做外包项目的企业(例如很多印度软件公司)来说,CMM倒是一个不错的能力衡量标准。只有对于这种不需要动脑筋、不需要创新的企业,CMM才有意义。如果让我来评价,我会认为CMM是软件企业的耻辱符:等级越高,说明企业越缺乏创造力。  
   
  让员工偷一点懒吧  
   
  《程》:我注意到您最近出了一本新书Slack,这个书名很是有趣,能不能请您简单介绍一下这本书?  
  TDM:其实这本书原来的名字叫《敏捷企业的秘密》(Secrets   of   the   Agile   Organization)。在我看来,要让企业具有适应新世纪、新经济所必须的敏捷性,需要做四件事:1)给员工一点点偷懒的时间;2)帮助员工减轻压力;3)注重对员工培养的投资;4)评估风险、控制风险。  
   
  《程》:难道偷懒也能帮助提高生产率吗?这不是违反直觉的吗?  
  TDM:对呀,你应该让员工每周七天、每天十二小时地拼命工作,这样效率最高了——如果他们的工作是搬砖头的话。  
  你必须首先搞清楚,要让你的员工为你贡献什么,然后再决定如何安排他们的工作。对于软件开发者,我们需要他们贡献的是创造力,是他们的点子,是他们的聪明才智,所以,我们必须让他们常常放松,有自由思考的时间,这样他们才能把自己的才华发挥出来。  
   
  Top

47 楼LoveCreatesBeauty(lovecreatesbeauty.googlepages.com)回复于 2003-11-07 22:02:25 得分 0

TDM:噢,我可是Gates和微软的崇拜者。现在,全世界的人都在使用计算机,微软在其中起到的作用胜过其他任何一家公司。而且,Gates本人很有意思:他有一个天才的头脑,总有精彩的点子;同时他又是一个优秀的商人,知道如何用自己的点子去挣钱。你也看到了,在《最后期限》中,我用Gates的形象刻画了摩罗维亚的国家元首。我想,这是我能对Gates表示的最大尊敬吧——不过,像Gates那样挥霍建豪宅,我也是反对的。这大概是老头的毛病吧。  
  说实话,如果说有一家公司是我心目中的理想企业,那就是微软。有很多人试图找出微软成功的秘密,可是他们常常去关注微软的开发过程。其实,微软的开发过程有什么可研究的呢?他们有全世界最优秀的员工,这些人享受着全世界最舒服的工作环境,不管用什么过程,我相信他们都能取得这些成就。其实,微软最值得研究的也是这两个问题:如何得到优秀的员工;如何让员工尽量发挥自己的能力。  
   
  Top

相关问题

  • 阅读《C++ Primer》疑问
  • 阅读《Effective C++》疑问
  • 阅读《More Effective C++》疑问
  • 阅读《C++ Primer》疑问
  • 什么是ANSI C ?
  • 在ANSI C++ 中能用PRO*C 吗?
  • C++是否100%向后兼容ANSI C
  • 如何学习ANSI C++???
  • 阅读<Inside The C++ Object Model>的疑问(1)
  • C/C++经典原版书籍在线阅读,下载!

关键词

  • c++
  • 《程序员》
  • 指针
  • 转换
  • 编译器
  • 字符
  • cmm
  • 员工
  • 指向
  • ppcc

得分解答快速导航

  • 帖主:LoveCreatesBeauty
  • plainsong
  • ckacka
  • ALNG
  • chinajiji
  • merlinran

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo