找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7273|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

break、continue和goto語(yǔ)句在C語(yǔ)言中的區(qū)別和用法

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:109770 發(fā)表于 2016-3-22 23:21 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
<break語(yǔ)句>
break語(yǔ)句通常用在循環(huán)語(yǔ)句和開(kāi)關(guān)語(yǔ)句中。當(dāng)break用于開(kāi)關(guān)語(yǔ)句switch中
時(shí), 可使程序跳出switch而執(zhí)行switch以后的語(yǔ)句; 如果沒(méi)有break語(yǔ)句, 則將
成為一個(gè)死循環(huán)而無(wú)法退出。
當(dāng)break語(yǔ)句用于do-while、for、while循環(huán)語(yǔ)句中時(shí), 可使程序終止循環(huán)
而執(zhí)行循環(huán)后面的語(yǔ)句, 通常break語(yǔ)句總是與if語(yǔ)句聯(lián)在一起。 即滿(mǎn)足條件時(shí)
便跳出循環(huán)。
例:
main()
{
int i=0;
char c;
while(1)                 /*設(shè)置循環(huán)*/
{
c='\0';             /*變量賦初值*/
while(c!=13&&c!=27) /*鍵盤(pán)接收字符直到按回車(chē)或Esc鍵*/
{
c=getch();
printf("%c\n", c);
}
if(c==27)
break;          /*判斷若按Esc鍵則退出循環(huán)*/
i++;
printf("The No. is %d\n", i);
}
printf("The end");
}
注意:
1. break語(yǔ)句對(duì)if-else的條件語(yǔ)句不起作用。
2. 在多層循環(huán)中, 一個(gè)break語(yǔ)句只向外跳一層。
<continue 語(yǔ)句>
continue語(yǔ)句的作用是跳過(guò)本循環(huán)中剩余的語(yǔ)句而強(qiáng)行執(zhí)行下一次循環(huán)。
continue語(yǔ)句只用在for、while、do-while等循環(huán)體中, 常與if條件語(yǔ)句一
起使用, 用來(lái)加速循環(huán)。
例:
main()
{
char c;
while(c!=0X0D)      /*不是回車(chē)符則循環(huán)*/
{
c=getch();
if(c==0X1B)
continue; /*若按Esc鍵不輸出便進(jìn)行下次循環(huán)*/
printf("%c\n", c);
}
}
<goto 語(yǔ)句>
goto語(yǔ)句是一種無(wú)條件轉(zhuǎn)移語(yǔ)句, 與BASIC中的goto語(yǔ)句相似。goto 語(yǔ)句的
使用格式為:
goto 標(biāo)號(hào);
其中標(biāo)號(hào)是Turbo C2.0中一個(gè)有效的標(biāo)識(shí)符, 這個(gè)標(biāo)識(shí)符加上一個(gè)":" 一起
出現(xiàn)在函數(shù)內(nèi)某處, 執(zhí)行g(shù)oto語(yǔ)句后, 程序?qū)⑻D(zhuǎn)到該標(biāo)號(hào)處并執(zhí)行其后的語(yǔ)句。
另外標(biāo)號(hào)必須與goto語(yǔ)句同處于一個(gè)函數(shù)中, 但可以不在一個(gè)循環(huán)層中。通常
goto語(yǔ)句與if條件語(yǔ)句連用, 當(dāng)滿(mǎn)足某一條件時(shí), 程序跳到標(biāo)號(hào)處運(yùn)行。
goto語(yǔ)句通常不用, 主要因?yàn)樗鼘⑹钩绦驅(qū)哟尾磺? 且不易讀, 但在多層嵌
套退出時(shí), 用goto語(yǔ)句則比較合理。
例:
main()
{
int i=0;
char c;
while(1)
{
c='\0';
while(c!=13)
{
c=getch();
if(c==27)
goto quit;
printf("%c\n", c);
}
i++;
printf("The No. is %d\n", i);
}
quit:
printf("The end");
}



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:109770 發(fā)表于 2016-3-22 23:21 | 只看該作者
goto語(yǔ)句
goto語(yǔ)句的發(fā)展歷程
  問(wèn)題起源:
  60年代中期以后,計(jì)算機(jī)硬件技術(shù)日益進(jìn)步,計(jì)算的存貯容量、運(yùn)算速度和可靠性明顯提高,生產(chǎn)硬件的成本不斷降低。計(jì)算機(jī)價(jià)格的下跌為它的廣泛應(yīng)用創(chuàng)造了極好的條件。在這種形勢(shì)下,迫切要求計(jì)算機(jī)軟件也能與之相適應(yīng)。因而,一些開(kāi)發(fā)大型軟件系統(tǒng)的要求提了出來(lái)。然而軟件技術(shù)的進(jìn)步一直未能滿(mǎn)足形勢(shì)發(fā)展的需要,在大型軟件的開(kāi)發(fā)過(guò)程中出現(xiàn)了復(fù)雜程度高、研制周期長(zhǎng)、正確性難以保證的三大難題。遇到的問(wèn)題找不到解決辦法,致使問(wèn)題堆積起來(lái),形成了人們難以控制的局面,出現(xiàn)了所謂的“軟件危機(jī)”。為了克服這一危機(jī),一方面需要對(duì)程序設(shè)計(jì)方法、程序的正確性和軟件的可靠性等問(wèn)題進(jìn)行系列的研究;另一方面,也需要對(duì)軟件的編制、測(cè)試、維護(hù)和管理的方法進(jìn)行研究,從而產(chǎn)生了程序設(shè)計(jì)方法學(xué)。
  goto語(yǔ)句是有害的觀(guān)點(diǎn):
  1968年,E·W·代克斯特拉首先提出“GOTO語(yǔ)句是有害的”論點(diǎn),向傳統(tǒng)程序設(shè)計(jì)方法提出了挑戰(zhàn),從而引起了人們對(duì)程序設(shè)計(jì)方法討論的普遍重視。
  goto語(yǔ)句的爭(zhēng)論:
  在60年代末和70年代初,關(guān)于GOTO語(yǔ)句的用法的爭(zhēng)論比較激烈。主張從高級(jí)程序語(yǔ)言中去掉GOTO語(yǔ)句的人認(rèn)為,GOTO語(yǔ)句是對(duì)程序結(jié)構(gòu)影響最大的一種有害的語(yǔ)句,他們的主要理由是:GOTO語(yǔ)句使程序的靜態(tài)結(jié)構(gòu)和動(dòng)態(tài)結(jié)構(gòu)不一致,從而使程序難以理解,難以查錯(cuò)。去掉GOTO語(yǔ)句后,可直接從程序結(jié)構(gòu)上反映程序運(yùn)行的過(guò)程。這樣,不僅使程序結(jié)構(gòu)清晰,便于理解,便于查錯(cuò),而且也有利于程序的正確性證明。
  持反對(duì)意見(jiàn)的人認(rèn)為,GOTO語(yǔ)句使用起來(lái)比較靈活,而且有些情形能提高程序的效率。若完全刪去GOTO語(yǔ)句,有些情形反而會(huì)使程序過(guò)于復(fù)雜,增加一些不必要的計(jì)算量。
  關(guān)于goto語(yǔ)句的解決方法:
  1974年,D·E·克努斯對(duì)于GOTO語(yǔ)句爭(zhēng)論作了全面公正的評(píng)述,其基本觀(guān)點(diǎn)是:不加限制地使用GOTO語(yǔ)句,特別是使用往回跳的GOTO語(yǔ)句,會(huì)使程序結(jié)構(gòu)難于理解,在這種情形,應(yīng)盡量避免使用GOTO語(yǔ)句。但在另外一些情況下,為了提高程序的效率,同時(shí)又不致于破壞程序的良好結(jié)構(gòu),有控制地使用一些GOTO語(yǔ)句也是必要的。用他的話(huà)來(lái)說(shuō)就是:“在有些情形,我主張刪掉GOTO語(yǔ)句;在另外一些情形,則主張引進(jìn)GOTO語(yǔ)句!睆拇,使這場(chǎng)長(zhǎng)達(dá)10年之久的爭(zhēng)論得以平息。
  后來(lái),G·加科皮尼和C·波姆從理論上證明了:任何程序都可以用順序、分支和重復(fù)結(jié)構(gòu)表示出來(lái)。這個(gè)結(jié)論表明,從高級(jí)程序語(yǔ)言中去掉GOTO語(yǔ)句并不影響高級(jí)程序語(yǔ)言的編程能力,而且編寫(xiě)的程序的結(jié)構(gòu)更加清晰。
  goto語(yǔ)句的結(jié)果:
  在C/C++等高級(jí)編程語(yǔ)言中保留了goto語(yǔ)句,但被建議不用或少用。在一些更新的高級(jí)編程語(yǔ)言,如Java不提供goto語(yǔ)句,它雖然指定goto作為關(guān)鍵字,但不支持它的使 用,使程序簡(jiǎn)潔易讀;盡管如此后來(lái)的c#還是支持goto語(yǔ)句的,goto語(yǔ)句一個(gè)好處就是可以保證chengx程序存在唯一的出口,避免了過(guò)于龐大的if嵌套。
回復(fù)

使用道具 舉報(bào)

板凳
ID:109770 發(fā)表于 2016-3-22 23:22 | 只看該作者
goto語(yǔ)句在C/C++語(yǔ)言中可謂是“臭名昭著”,乃至有的書(shū)(或公司的編程規(guī)范)提出禁用goto語(yǔ)句的說(shuō)法。其結(jié)果就是,造成有的程序員一看到goto語(yǔ)句在某程序中被使用,就本能地認(rèn)為這個(gè)程序?qū)懙煤堋袄薄4送,也使得有些程序員因?yàn)槭褂昧薵oto語(yǔ)句而覺(jué)得自己很不專(zhuān)業(yè)。其實(shí),凡事都不能太偏激,goto語(yǔ)句運(yùn)用得好能大大地簡(jiǎn)化程序,以及提高程序的可讀性和可維護(hù)性。在開(kāi)始示例其好處之前,先用一些統(tǒng)計(jì)數(shù)據(jù)來(lái)說(shuō)明goto語(yǔ)句并沒(méi)有因?yàn)椤俺裘阎倍粧仐,這些統(tǒng)計(jì)數(shù)據(jù)可能并不是百分之百的精確,但很具有說(shuō)服力。對(duì)于操作系統(tǒng),Linux-2.6.21內(nèi)核使用了20,333個(gè)goto語(yǔ)句,VxWorks-6.2則使用了9142個(gè),最后941個(gè)goto語(yǔ)句被運(yùn)用到了rtems-4.9.2中;另外,glibc-2.9庫(kù)使用了1750個(gè)goto語(yǔ)句。所有這些統(tǒng)計(jì)數(shù)據(jù)都表明,goto語(yǔ)言并沒(méi)有想象的那樣可怕而招到禁用,其關(guān)鍵在于 —— 恰當(dāng)?shù)剡\(yùn)用它。

圖1是一個(gè)沒(méi)有采用goto語(yǔ)句編寫(xiě)的函數(shù),其中存在多處出錯(cuò)處理的代碼,比如113~115行、120~122行和126~129行。采用這種分布式的出錯(cuò)處理,很容易出現(xiàn)遺漏釋放前面已經(jīng)分配的資源,從而造成資源泄漏問(wèn)題。如果采用goto語(yǔ)句,則能取得更好的效果。

example.c
00097: int queue_init (queue_t ** _pp_queue, int _size)
00098: {
00099:     pthread_mutexattr_t attr;
00100:     queue_t *queue;
00101:
00102:        queue = (queue_t *) malloc(sizeof(queue_t));
00103:        if (0 == queue) {
00104:         return -1;
00105:     }
00106:     *_pp_queue = queue;
00107:
00108:     memset (queue, 0, sizeof (*queue));
00109:     queue->size_ = _size;
00110:
00111:     pthread_mutexattr_init (&attr);
00112:     if (0 != pthread_mutex_init(&queue->mutex_, &attr)) {
00113:         pthread_mutexattr_destroy (&attr);
00114:         free (queue);
00115:         return -1;
00116:     }
00117:
00118:     queue->messages_ = (void **) malloc (queue->size_ * sizeof (void *));
00119:     if (0 == queue->messages_) {
00120:         pthread_mutexattr_destroy (&attr);
00121:         free (queue);
00122:         return -1;
00123:     }
00124:
00125:     if (0 != sem_init(&queue->sem_put_, 0, queue->size_)) {
00126:         free (queue->messages_);
00127:         pthread_mutexattr_destroy (&attr);
00128:         free (queue);
00129:         return -1;
00130:     }
00131:
00132:     pthread_mutexattr_destroy (&attr);
00133:
00134:     return 0;
00135: }


圖1

圖2是采用goto語(yǔ)句所編寫(xiě)的另一個(gè)版本,與不采用goto語(yǔ)句的版本相比,程序更加的簡(jiǎn)單,且在出錯(cuò)處理的地方大都使用goto語(yǔ)句跳轉(zhuǎn)到程序的末尾進(jìn)行處理。goto語(yǔ)句除了可以用在這里所示例的出錯(cuò)處理中,還可以用在其它的程序邏輯中以簡(jiǎn)化程序并提高閱讀性。
example.c
00053: int queue_init (queue_t ** _pp_queue, int _size)
00054: {
00055:     pthread_mutexattr_t attr;
00056:     queue_t *queue;
00057:
00058:     queue = (queue_t *) malloc(sizeof(queue_t));
00059:         if (0 == queue) {
00060:         return -1;
00061:     }
00062:     *_pp_queue = queue;
00063:
00064:     memset (queue, 0, sizeof (*queue));
00065:     queue->size_ = _size;
00066:
00067:     pthread_mutexattr_init (&attr);
00068:     if (0 != pthread_mutex_init(&queue->mutex_, &attr)) {
00069:         goto error;
00070:     }
00071:
00072:     queue->messages_ = (void **) malloc (queue->size_ * sizeof (void *));
00073:     if (0 == queue->messages_) {
00074:         goto error;
00075:     }
00076:
00077:     if (0 != sem_init(&queue->sem_put_, 0, queue->size_)) {
00078:         goto error1;
00079:     }
00080:
00081:     pthread_mutexattr_destroy (&attr);
00082:
00083:     return 0;
00084:
00085: error1:
00086:     free (queue->messages_);
00087: error:
00088:     pthread_mutexattr_destroy (&attr);
00089:     free (queue);
00090:     return -1;
00091: }


圖2

使用goto語(yǔ)句時(shí)需要注意以下原則:
1) 不要過(guò)份地使用。比如圖2中的60行就沒(méi)有采用goto語(yǔ)句跳到程序的最后面,之所以這里不使用goto是為了閱讀方便。因?yàn)槌绦虼藭r(shí)還沒(méi)有分配資源,所以直接返回顯得更加的直接了當(dāng)。還有就是,在這個(gè)函數(shù)中如果存在使用goto語(yǔ)句都意味著出錯(cuò)了且需要釋放資源。如果將60行的語(yǔ)句也改為goto就破壞了這個(gè)函數(shù)中使用goto語(yǔ)句的一致性。
2) 不要讓goto語(yǔ)句形成一個(gè)環(huán)。使用goto語(yǔ)句應(yīng)形成一條線(xiàn),從一點(diǎn)跳到另一點(diǎn)。當(dāng)然,如果goto語(yǔ)句的使用沒(méi)有破壞可讀性,那可以適當(dāng)?shù)目紤]打破這一原則。


回復(fù)

使用道具 舉報(bào)

地板
ID:109770 發(fā)表于 2016-3-22 23:25 | 只看該作者
在中斷中使用goto語(yǔ)句:LZ用匯編寫(xiě)過(guò)程序,就應(yīng)該明白
當(dāng)你進(jìn)入中斷服務(wù)程序時(shí),單片機(jī)本身會(huì)備份當(dāng)前程序狀態(tài),中斷部分執(zhí)行完畢后會(huì)用RETI恢復(fù)現(xiàn)場(chǎng)
如果這時(shí)候主程序是在執(zhí)行一個(gè)子程序時(shí)進(jìn)入的中斷,那么中斷執(zhí)行完畢后自然會(huì)繼續(xù)執(zhí)行之前的子程序毫無(wú)影響,問(wèn)題就在這...中斷部分用LJMP之類(lèi)跳轉(zhuǎn)指令(相當(dāng)于goto),自然是“合法”得跳轉(zhuǎn)到目的地,但之前被執(zhí)行到一半的子程序?qū)?huì)被徹底打斷,程序架構(gòu)一旦沒(méi)處理好這部分,出問(wèn)題也在所難免,比如一個(gè)狀態(tài)機(jī),在狀態(tài)改變時(shí)的那一步被打斷......
這樣的話(huà),要么你在所有不可打斷處關(guān)閉中斷,處理完畢后再打開(kāi),但這樣程序可移植性等等都將被破壞
要么用類(lèi)似如下主循環(huán):
while(1)
{
    工作1;
        跳轉(zhuǎn)變量檢測(cè);
    工作2;
        跳轉(zhuǎn)變量檢測(cè);
    工作3;
        跳轉(zhuǎn)變量檢測(cè);
    工作4;
        跳轉(zhuǎn)變量檢測(cè);
    ....
}
這樣看似語(yǔ)句啰嗦不少,但每次大循環(huán)也就犧牲若干個(gè)微秒便可保證響應(yīng)的速度



回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表