c/c++语言开发共享在哪种情况下,(a = b)是个好主意?


可能重复:
无意中使用=而不是==

C ++编译器通过您编写的警告让您知道

if( a = b ) { //... 

并且这可能是一个错误,你当然想写

 if( a == b ) { //... 

但有没有一种情况应该忽略警告,因为这是使用这个“function”的好方法? 我没有看到任何代码清晰度可能的原因,那么它有用吗?

    两个可能的原因:

     while ( (line = readNextLine()) != EOF) { processLine(); } 

    您可以用来测试函数是否返回任何错误

     if (error_no = some_function(...)) { //handle error } 

    假设some_function在发生错误时返回错误代码,否则返回零

    这是C语言基本function的结果:

    赋值操作的值是赋值本身

    您可以将“返回值”用作if()语句的条件这一事实是偶然的。

    顺便说一句,这是同样的技巧,允许这种疯狂的简洁:

     void strcpy(char *s, char *t) { while( *s++ = *t++ ); } 

    当然,当达到t的nullchar时,while会退出,但同时会将其复制到目标s字符串。

    这是否是一个好主意,通常不是,因为它降低了代码的可读性并且容易出错。

    虽然构造是完全合法的语法,您的意图可能真的如下所示:

     if( (a = b) != 0 ) { ... } 

    不要将“!= 0”部分留下。

    6个月,1年,5年后看代码的人乍一看,只是相信代码包含一个由jr写的“经典bug”。 程序员并将尝试“修复”它。 CLEARLY上面的结构表明了你的意图,并将由编译器进行优化。 如果你是那个人,这将特别令人尴尬。

    你的另一个选择是重复评论。 但以上是自我记录的代码,这是更好的。

    最后,我的偏好是这样做:

     a = b; if( a != 0 ) { ... } 

    这很清楚,因为代码可以获得。 如果性能受到影响,则几乎为零。

     void some( int b ) { int a = 0; if( a = b ) { // or do something with a // knowing that is not 0 } // b remains the same } 

    直接回答这个问题,作为一个个人观点,我真的不认为这是一个好主意的情况。

    我的意思是,我知道使用这种语法可以避免在代码中添加额外的行,但我认为它会从代码中消除一些可读性。

    这种语法对于像@Steven Schlansker建议的那样非常有用,但直接使用它作为条件并不是一个好主意。

    只是我的两分钱……

    这实际上不是C的故意特征,而是另外两个特征的结果:

    赋值返回指定的值

    这对于执行多个赋值(例如a = b = 0 )或循环(例如while ((n = getchar()) != EOF)非常有用。

    数字和指针都有真值

    C最初在1999年标准之前没有bool类型,因此它使用int来表示布尔值。 向后兼容性要求C和C ++允许ifwhileforbool表达式。

    因此,如果a = b有一个值,并且if对它接受的值if宽松,则if (a = b)有效。 但我建议使用if ((a = b) != 0)来阻止任何人“修复”它。

    一个有用的常见例子可能是:

     do { ... } while (current = current->next); 

    您应该以更好的编码方式明确地编写检查语句,避免使用assign&check方法。 例:

     if ((fp = fopen("filename.txt", "wt")) != NULL) { // do something with fp } 

     while( (l = getline()) != EOF){ printf("%sn", l); } 

    这当然是最简单的例子,有很多次这是有用的。 要记住的主要事情是(a = true)返回true,就像(a = false)返回false一样。

    但有没有一种情况应该忽略警告,因为这是使用这个“function”的好方法? 我没有看到任何代码清晰度可能的原因,那么它有用吗?

    可以通过在作业周围放置额外的括号来抑制警告。 这样澄清了程序员的意图。 我见过的常见情况与(a = b)情况直接匹配的情况如下:

     if ( (a = expression_with_zero_for_failure) ) { // do something with 'a' to avoid having to reevaluate // 'expression_with_zero_for_failure' (might be a function call, eg) } else if ( (a = expression2_with_zero_for_failure) ) { // do something with 'a' to avoid having to reevaluate // 'expression2_with_zero_for_failure' } // etc. 

    至于编写这种代码是否足够有用来certificate初学者(有时甚至是最糟糕时刻的专业人士)在使用C ++时遇到的常见错误,很难说。 这是inheritance自C和Stroustrup的遗产,其他有助于设计C ++的人可能已经走了一条完全不同的,更安全的路线,如果他们没有尽可能地使C ++向后兼容C语言。

    我个人认为这不值得。 我在一个团队工作,之前我曾多次遇到过这个bug。 我会赞成不允许它(至少需要括号或其他一些明确的语法,否则它被认为是构建错误)以换取减轻遇到这些错误的负担。

    前言

    请注意,这个答案是关于C ++的(我在添加标签“C”之前开始写这个答案)。

    在阅读Jens Gustedt的评论之后,我意识到这不是我第一次写这样的答案。 事实是,这个问题与另一个问题重复,我给出了以下答案:

    无意中使用=而不是==

    所以,我会在这里无耻地引用自己来添加一个重要的信息: if不是关于比较。 这是关于评估。

    这种差异非常重要,因为它意味着任何东西都可以在if的括号内,只要它可以被计算为布尔值。 这是件好事。

    现在,通过禁止=限制语言,其中所有其他运算符都被授权,对于该语言来说是一个危险的例外,这个例子的使用远非确定,其缺点确实很多。

    对于那些对= typo不感兴趣的人,那么有解决方案(参见下面的替代方案 ……)。

    关于if(i = 0)的有效用法[引自我自己]

    问题是你正在把问题颠倒过来。 “if”表示法不是像在某些其他语言中那样比较两个值。

    C / C ++ if指令等待任何将计算为boolean或null / non-null值的表达式。 该表达式可以包括两个值比较,和/或可以更复杂。

    例如,您可以:

     if(i >> 3) { std::cout << "i is less than 8" << std::endl } 

    这certificate,在C / C ++中,if表达式不限于==和=。 任何事都可以,只要它可以被评估为真或假(C ++),或零非零(C / C ++)。

    关于有效用途

    回到未引用的答案。

    以下表示法:

     if(MyObject * p = findMyObject()) { // uses p } 

    使用户能够声明然后在if中使用p。 这是一个语法糖...但有趣的一个。 例如,想象一下类似XML DOM的对象的情况,其类型在运行时之前是未知的,并且您需要使用RTTI:

     void foo(Node * p_p) { if(BodyNode * p = dynamic_cast(p_p)) { // this is a  node } else if(SpanNode * p = dynamic_cast(p_p)) { // this is a  node } else if(DivNode * p = dynamic_cast(p_p)) { // this is a 
    node } // etc. }

    当然,RTTI不应该被滥用,但这只是这种语法糖的一个例子。

    另一种用途是使用所谓的C ++ Variable Injection。 在Java中,有这个很酷的关键字:

     synchronized(p) { // Now, the Java code is synchronized using p as a mutex } 

    在C ++中,您也可以这样做。 我没有确切的代码(也没有我发现它的确切的DDJ文章),但这个简单的定义应该足以用于演示目的:

     #define synchronized(lock)  if (auto_lock lock_##__LINE__(lock)) synchronized(p) { // Now, the C++ code is synchronized using p as a mutex } 

    (请注意,此宏非常原始,不应在生产代码中使用。真正的宏使用if和a for 。请参阅下面的源代码以获得更正确的实现)。

    这是相同的方式,混合注入iffor声明,你可以声明一个原始的foreach宏(如果你想要一个工业级的foreach,使用boost)。

    关于你的错字问题

    您的问题是一个错字,并且有多种方法可以限制代码中的频率。 最重要的是确保左侧操作数是常量。

    例如,由于多种原因,此代码将无法编译:

     if( NULL = b ) // won't compile because it is illegal // to assign a value to r-values. 

    甚至更好:

     const T a ; // etc. if( a = b ) // Won't compile because it is illegal // to modify a constant object 

    这就是为什么在我的代码中, const是你会发现的最常用的关键字之一。 除非我真的想要修改变量,否则它被声明为const ,因此,编译器可以保护我免受大多数错误的影响,包括促使您编写此问题的拼写错误。

    但有没有一种情况应该忽略警告,因为这是使用这个“function”的好方法? 我没有看到任何代码清晰度可能的原因,那么它有用吗?

    结论

    如上例所示,您在问题中使用的function有多种有效用途。

    自从我使用此function启用的代码注入后,我自己的代码更清晰,更清晰:

     void foo() { // some code LOCK(mutex) { // some code protected by a mutex } FOREACH(char c, MyVectorOfChar) { // using c } } 

    ...这让我很难遇到这个错字的代价是一个可以忽略不计的代价(我不记得上次我写这种类型而没有被编译器抓住)。

    有趣的消息来源

    我终于找到了关于变量注入的文章。 开始了 !!!

    备择方案

    如果一个人害怕成为= / ==拼写错误的受害者,那么使用宏可能会有所帮助:

     #define EQUALS == #define ARE_EQUALS(lhs,rhs) (lhs == rhs) int main(int argc, char* argv[]) { int a = 25 ; double b = 25 ; if(a EQUALS b) std::cout << "equals" << std::endl ; else std::cout << "NOT equals" << std::endl ; if(ARE_EQUALS(a, b)) std::cout << "equals" << std::endl ; else std::cout << "NOT equals" << std::endl ; return 0 ; } 

    通过这种方式,可以保护自己免受拼写错误的影响,而不需要语言限制(这会使语言瘫痪),因为很少发生的错误(即几乎从来没有,就我在代码中记得的那样)

    决不!

    引用的例外情况不会产生编译器警告。 在编译器生成警告的情况下,这绝不是一个好主意。

    还有一个方面没有提到:C不会阻止你做任何不必要的事情。 它并不妨碍你这样做,因为C的工作就是给你足够的绳索来吊死自己。 不要以为它比你聪明。 它很擅长。

    RegEx样本

      RegEx r;   if(((r = new RegEx(“ w *))。IsMatch()){     // ...在这里做点什么  }  else if((r = new RegEx(“ d *”))。IsMatch()){     // ...在这里做点什么  } 

    作为价值测试

      int i = 0;  if((i = 1)== 1){     // 1等于分配给int值1的i  } 其他{     //?  } 

    我最喜欢的是:

     if (CComQIPtr a = BaseClassPtr) { ... } else if (CComQIPtr b = BaseClassPtr) { ... } 

      以上就是c/c++开发分享在哪种情况下,(a = b)是个好主意?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560790.html

      (0)
      上一篇 2021年1月28日
      下一篇 2021年1月28日

      精彩推荐