pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

C/C++ 中的無限循環

Endless loop in C/C++(C/C++ 中的無限循環)
本文介紹了C/C++ 中的無限循環的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

無限循環有幾種可能,我會選擇以下幾種:

  • for(;;) {}
  • while(1) {}/while(true) {}
  • do {} while(1)/do {} while(true)

是否有某種形式應該選擇哪一種?現代編譯器是否對中間語句和最后一條語句有所區別,或者它是否意識到這是一個無限循環并完全跳過檢查部分?

正如前面提到的,我忘記了 goto,但這樣做是因為我根本不喜歡它作為命令.

Edit2:我對從 kernel.org 獲取的最新版本做了一些 grep.隨著時間的推移,我似乎沒有太大變化(至少在內核中)

解決方案

問這個問題的問題是你會得到很多主觀的答案,只是簡單地說明我更喜歡這個......".我不會做出這些毫無意義的陳述,而是嘗試用事實和參考資料來回答這個問題,而不是個人意見.

根據經驗,我們可以先排除 do-while 替代方案(和 goto),因為它們并不常用.我不記得在由專業人員編寫的實時生產代碼中看到過它們.

while(1)while(true)for(;;) 是實際代碼中普遍存在的 3 個不同版本.它們當然是完全等價的,并產生相同的機器代碼.

<小時>

for(;;)

  • 這是永恒循環的原始規范示例.在 Kernighan 和 Ritchie 的古老 C 圣經C 編程語言中,我們可以讀到:

    K&R 第二版 3.5:

    for (;;) {...}

    <塊引用>

    是一個無限"循環,大概會被其他方式打破,例如作為休息或返回.使用 while 還是 for 在很大程度上是一個問題個人喜好.

    很長一段時間(但不是永遠),這本書被視為經典和 C 語言的定義.由于 K&R 決定展示一個 for(;;) 的例子,至少在 1990 年 C 標準化之前,這被認為是最正確的形式.

    然而,K&R 自己已經表示這是一個偏好問題.

    今天,K&R 是一個非常有問題的來源,用作規范的 C 參考.它不僅多次過時(不是針對 C99 或 C11),而且還宣揚在現代 C 編程中通常被認為是壞的或公然危險的編程實踐.

    盡管 K&R 是一個可疑的來源,但這一歷史方面似乎是支持 for(;;) 的最有力論據.

  • 反對 for(;;) 循環的論點是它有點晦澀難懂.要了解代碼的作用,您必須了解標準中的以下規則:

    ISO 9899:2011 6.8.5.3:

    for ( clause-1 ; expression-2 ; expression-3 ) 語句

    /--/

    <塊引用>

    子句 1 和表達式 3 都可以省略.省略的表達式-2由一個非零常數代替.

    根據標準中的這段文字,我認為大多數人會同意它不僅晦澀難懂,而且很微妙,因為 for 循環的第一和第三部分在省略時的處理方式與第二部分不同.

<小時>

while(1)

  • 這應該是比 for(;;) 更易讀的形式.然而,它依賴于另一個晦澀但眾所周知的規則,即 C 將所有非零表達式視為布爾邏輯真.每個 C 程序員都知道這一點,所以這不是什么大問題.

  • 這種形式有一個很大的實際問題,即編譯器往往會給出警告:條件總是為真"或類似的.這是一個很好的警告,您真的不想禁用它,因為它對于查找各種錯誤很有用.例如,當程序員打算編寫 while(i == 1) 時,會出現諸如 while(i = 1) 之類的錯誤.

    此外,外部靜態代碼分析器可能會抱怨條件始終為真".

<小時>

while(true)

  • 為了使 while(1) 更具可讀性,有些使用 while(true) 代替.程序員之間的共識似乎是這是最易讀的形式.

  • 然而,這種形式與while(1)有同樣的問題,如上所述:condition is always true"警告.

  • 對于 C,這種形式還有另一個缺點,即它使用了 stdbool.h 中的宏 true.所以為了進行這個編譯,我們需要包含一個頭文件,這可能不方便.在 C++ 中,這不是問題,因為 bool 作為原始數據類型存在,而 true 是語言關鍵字.

  • 這種形式的另一個缺點是它使用 C99 bool 類型,該類型僅在現代編譯器上可用且不向后兼容.同樣,這只是 C 中的問題,而不是 C++ 中的問題.

<小時>

那么使用哪種形式?兩者似乎都不完美.正如 K&R 在黑暗時代已經說過的那樣,這是個人喜好問題.

就個人而言,我總是使用 for(;;) 只是為了避免其他形式經常生成的編譯器/分析器警告.但也許更重要的是因為這個:

如果連 C 初學者都知道 for(;;) 意味著一個永恒的循環,那么你想讓誰的代碼更易讀?

我想這就是真正歸結起來的原因.如果您發現自己試圖讓您的源代碼對于那些甚至不了解編程語言的基本部分的非程序員來說是可讀的,那么您只是在浪費時間.他們不應該閱讀您的代碼.

而且由于每個應該閱讀你的代碼的人都已經知道 for(;;) 的意思,所以沒有必要讓它進一步可讀 - 它已經是可讀.

There are several possibilities to do an endless loop, here are a few I would choose:

  • for(;;) {}
  • while(1) {} / while(true) {}
  • do {} while(1) / do {} while(true)

Is there a certain form which one should choose? And do modern compilers make a difference between the middle and the last statement or does it realize that it is an endless loop and skips the checking part entirely?

Edit: as it has been mentioned I forgot goto, but this was done out of the reason that I don't like it as a command at all.

Edit2: I made some grep on the latest versions taken from kernel.org. I does seems as nothing much changed over time (within the Kernel at least)

解決方案

The problem with asking this question is that you'll get so many subjective answers that simply state "I prefer this...". Instead of making such pointless statements, I'll try to answer this question with facts and references, rather than personal opinions.

Through experience, we can probably start by excluding the do-while alternatives (and the goto), as they are not commonly used. I can't recall ever seeing them in live production code, written by professionals.

The while(1), while(true) and for(;;) are the 3 different versions commonly existing in real code. They are of course completely equivalent and results in the same machine code.


for(;;)

  • This is the original, canonical example of an eternal loop. In the ancient C bible The C Programming Language by Kernighan and Ritchie, we can read that:

    K&R 2nd ed 3.5:

    for (;;) {
    ...
    }
    

    is an "infinite" loop, presumably to be broken by other means, such as a break or return. Whether to use while or for is largely a matter of personal preference.

    For a long while (but not forever), this book was regarded as canon and the very definition of the C language. Since K&R decided to show an example of for(;;), this would have been regarded as the most correct form at least up until the C standardization in 1990.

    However, K&R themselves already stated that it was a matter of preference.

    And today, K&R is a very questionable source to use as a canonical C reference. Not only is it outdated several times over (not addressing C99 nor C11), it also preaches programming practices that are often regarded as bad or blatantly dangerous in modern C programming.

    But despite K&R being a questionable source, this historical aspect seems to be the strongest argument in favour of the for(;;).

  • The argument against the for(;;) loop is that it is somewhat obscure and unreadable. To understand what the code does, you must know the following rule from the standard:

    ISO 9899:2011 6.8.5.3:

    for ( clause-1 ; expression-2 ; expression-3 ) statement
    

    /--/

    Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a nonzero constant.

    Based on this text from the standard, I think most will agree that it is not only obscure, it is subtle as well, since the 1st and 3rd part of the for loop are treated differently than the 2nd, when omitted.


while(1)

  • This is supposedly a more readable form than for(;;). However, it relies on another obscure, although well-known rule, namely that C treats all non-zero expressions as boolean logical true. Every C programmer is aware of that, so it is not likely a big issue.

  • There is one big, practical problem with this form, namely that compilers tend to give a warning for it: "condition is always true" or similar. That is a good warning, of a kind which you really don't want to disable, because it is useful for finding various bugs. For example a bug such as while(i = 1), when the programmer intended to write while(i == 1).

    Also, external static code analysers are likely to whine about "condition is always true".


while(true)

  • To make while(1) even more readable, some use while(true) instead. The consensus among programmers seem to be that this is the most readable form.

  • However, this form has the same problem as while(1), as described above: "condition is always true" warnings.

  • When it comes to C, this form has another disadvantage, namely that it uses the macro true from stdbool.h. So in order to make this compile, we need to include a header file, which may or may not be inconvenient. In C++ this isn't an issue, since bool exists as a primitive data type and true is a language keyword.

  • Yet another disadvantage of this form is that it uses the C99 bool type, which is only available on modern compilers and not backwards compatible. Again, this is only an issue in C and not in C++.


So which form to use? Neither seems perfect. It is, as K&R already said back in the dark ages, a matter of personal preference.

Personally, I always use for(;;) just to avoid the compiler/analyser warnings frequently generated by the other forms. But perhaps more importantly because of this:

If even a C beginner knows that for(;;) means an eternal loop, then who are you trying to make the code more readable for?

I guess that's what it all really boils down to. If you find yourself trying to make your source code readable for non-programmers, who don't even know the fundamental parts of the programming language, then you are only wasting time. They should not be reading your code.

And since everyone who should be reading your code already knows what for(;;) means, there is no point in making it further readable - it is already as readable as it gets.

這篇關于C/C++ 中的無限循環的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數據?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環: for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環?)
Reusing thread in loop c++(在循環 C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環形?)
主站蜘蛛池模板: 无缝方管|无缝矩形管|无缝方矩管|无锡方管厂家 | 热镀锌槽钢|角钢|工字钢|圆钢|H型钢|扁钢|花纹板-天津千百顺钢铁贸易有限公司 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 岩棉板|岩棉复合板|聚氨酯夹芯板|岩棉夹芯板|彩钢夹芯板-江苏恒海钢结构 | 股票入门基础知识_股票知识_股票投资大师_格雷厄姆网 | 建筑工程资质合作-工程资质加盟分公司-建筑资质加盟 | ICP备案查询_APP备案查询_小程序备案查询 - 备案巴巴 | 红外光谱仪维修_二手红外光谱仪_红外压片机_红外附件-天津博精仪器 | 粉末冶金注射成型厂家|MIM厂家|粉末冶金齿轮|MIM零件-深圳市新泰兴精密科技 | 骁龙云呼电销防封号系统-axb电销平台-外呼稳定『免费试用』 | [官网]叛逆孩子管教_戒网瘾学校_全封闭问题青少年素质教育_新起点青少年特训学校 | 高楼航空障碍灯厂家哪家好_航空障碍灯厂家_广州北斗星障碍灯有限公司 | 阻燃剂-氢氧化镁-氢氧化铝-沥青阻燃剂-合肥皖燃新材料 | 上海皓越真空设备有限公司官网-真空炉-真空热压烧结炉-sps放电等离子烧结炉 | 雨燕360体育免费直播_雨燕360免费NBA直播_NBA篮球高清直播无插件-雨燕360体育直播 | 西门子伺服控制器维修-伺服驱动放大器-828D数控机床维修-上海涌迪 | 阿尔法-MDR2000无转子硫化仪-STM566 SATRA拉力试验机-青岛阿尔法仪器有限公司 | 电动高压冲洗车_价格-江苏速利达机车有限公司 | 软膜天花_软膜灯箱_首选乐创品牌_一站式天花软膜材料供应商! | 仿古瓦,仿古金属瓦,铝瓦,铜瓦,铝合金瓦-西安东申景观艺术工程有限公司 | 旗帜网络笔记-免费领取《旗帜网络笔记》电子书 | 聚丙烯酰胺_阴离子_阳离子「用量少」巩义亿腾厂家直销,售后无忧 聚合甘油__盐城市飞龙油脂有限公司 | 合肥地磅_合肥数控切割机_安徽地磅厂家_合肥世佳电工设备有限公司 | 龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司_龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司 | 蜜蜂职场文库_职场求职面试实用的范文资料大全| 密集架-密集柜厂家-智能档案密集架-自动选层柜订做-河北风顺金属制品有限公司 | TPE塑胶原料-PPA|杜邦pom工程塑料、PPSU|PCTG材料、PC/PBT价格-悦诚塑胶 | 2025世界机器人大会_IC China_半导体展_集成电路博览会_智能制造展览网 | 北京工业设计公司-产品外观设计-产品设计公司-千策良品工业设计 北京翻译公司-专业合同翻译-医学标书翻译收费标准-慕迪灵 | 锤式粉碎机,医药粉碎机,锥式粉碎机-无锡市迪麦森机械制造有限公司 | 断桥铝破碎机_铝合金破碎机_废铁金属破碎机-河南鑫世昌机械制造有限公司 | IP检测-检测您的IP质量 | 百方网-百方电气网,电工电气行业专业的B2B电子商务平台 | 低浓度恒温恒湿称量系统,强光光照培养箱-上海三腾仪器有限公司 | 生态板-实木生态板-生态板厂家-源木原作生态板品牌-深圳市方舟木业有限公司 | 岸电电源-60HZ变频电源-大功率变频电源-济南诚雅电子科技有限公司 | bng防爆挠性连接管-定做金属防爆挠性管-依客思防爆科技 | 天津次氯酸钠酸钙溶液-天津氢氧化钠厂家-天津市辅仁化工有限公司 | 电动葫芦-河北悍象起重机械有限公司| 书信之家_书信标准模板范文大全| 岛津二手液相色谱仪,岛津10A液相,安捷伦二手液相,安捷伦1100液相-杭州森尼欧科学仪器有限公司 |