好吧,也許你認為我在寫一篇如何使用for循環的文章,,,,首先,我想說無論是學習C語言還是學習java的同學都能從此文中獲益,還有,你確定你會用for循環嗎?其實許多東西你只是在表面,要品才能有一種感覺,有的時候,我喜歡咬文嚼字一下,所以你可以認為我現在在程序中討論關于“用推還是用敲”的話題。
先來問你一個問題,一個簡單的數學問題,不過你盡量快點回答,區間[9,15]中有幾個整數?
多數想馬上表現自己聰明的同學可能會馬上回答6個,但是是7個,你會發現這種雙閉區間的元素會比你想象的多,就連[9,9]都有一個元素是嗎?而半開半閉就不同了[0,10)你可以不假思索的用[m,n)中有n-m個元素,來回答這個答案,10個元素,你發現什么了沒?這。。有點像數組,恩恩,這個問題就是我們在本文后面將討論的你如何才能熟練的使用這些多1少1的問題。現在先開始說for循環
我常常把最簡單的for循環稱之為循環計數器:
for(inti =1;i《=10;i++)cout《《“求妹子”《
你看,這里的i只是一個計數的作用,它在告訴cpu,去把我的這條語句執行十次把!
你可能會說,這有什么?for都是這樣的呀!請你往下看
for(inti =1;i《=10;i++)cout《《“求”《
這個for就不同了,它把i做為一種產物,在循環中使用它,我把它稱之為循環產生器,這個i就不僅僅是讓循環執行十次的作用了,它在每次的循環中產生,循環體的語句中有自己的作用,所以當你理解所謂的循環產生器,你就會很輕松的寫出各種多層循環的程序了,比如崔哥曾出個這樣一個題:
請用循環語句打印一個空心菱形:
我將用一種清晰的思路來分析寫這個程序,
嗯,我先寫一個函數,它提供的接口如下:
void print(int n,int p,int q);//在一行輸出n個元素,除了在p和q出輸出*其它地方都輸出空格
恩,很簡單的一個函數:
void print(int n,int p,int q){ for(int i = 1;i《=n;i++) { if(i==p||i==q) printf(“*”); else printf(“ ”); } printf(“
”);}
void print(int n,int p,int q){ for(int i = 1;i《=n;i++) { if(i==p||i==q) printf(“*”); else printf(“ ”); } printf(“
”);}
所以,用所謂的循環產生器,產生我們需要的參數傳遞給這個函數不就行了嗎?
下面,我們先做一些約定
“你我約定,難過的往事不許提”。。。
開玩笑了,,,我們繼續:
首先,輸出空心菱形,這個行數一定是個奇數,
所以我們用1到LOW來表示這LOW個位置,而且中間的那個位置就是LOW/2+1
這樣我們的程序就是這樣:
#define LOW 13int j,k,n = LOW/2+1;//空心菱形的中間位置j=k=n;for(int i = 1;i《=LOW;i++){ print(LOW,j,k); if(i《n) j--,k++; else j++,k--;}
i做為一個產生器,不但讓循環執行LOW次(打印low行)同時也控制產生這j和k這兩個參數了,當然我們在清晰道理之后,完全可以把這個函數嵌到循環中,看只用了兩個for,而不是某些同學的分段循環,四個for。。。
繼續討論有關for的話題,現在我要通過說明for的一些使用細節,來向你展示,你用什么樣的語言決定你的編程思維,我問你如果讓你訪問數組a[10]的每個元素,你會寫怎樣的代碼?
for(int i = 0;i《=9;i++)
還是
for(int i = 0;i!=10;i++)
我一直都是使用第二種,因為這可以很好的說明半開半閉區間的思想,而且,C數組本身就是從零開始的,我們用10來表示它最后一個元素的下一個位置(因為最后一個元素是a[9]),
其實,不僅僅是數組,在許多語言的迭代器(包括c++標準庫)中都會使用第一個元素表示頭,最后一個元素的下一個位置表示尾,半開半閉區間的這種思想可以讓你不用陷入多1或是少1的問題中,比如[n,n)是沒有元素的,[n,m)是有m-n個元素的。。
至于為什么是i!=10,而不是i《10,那要是這樣的語句呢?
for(int i = 10;i!=0;i--)
不用把”《”改成”》”了,而且。。。作為一個終止狀態,還有用(后面論述)
現在還記得開頭的那個求妹子的列子嗎?
for(inti =1;i《=10;i++)cout《《“求”《
這里我就讓i從1到10,(我不可能求0個妹子吧?)所以,這種對循環i的選取,0或1,是很有細節思考的。
下面再看一個列子:
inti;for(i=0;a[i]!=‘c’&&i!=N;i++);
這段代碼的作用是在一個char數組中找到第一個是’c’的元素,并返回它的索引
有幾個有趣的地方:
我把i的定義放在外面
這個for循環沒有循環體,看那個分號。。。。。。
不是計數器,不是產生器,我喜歡把這種for稱之為循環搜捕器,它用來找一個元素
所以我把i定義在循環外,因為之后我們還要使用到i,而同時也與前面的那些for循環中把i定義到for里面形成了對比,因為之前的作用,我并不想把它的作用域外流,實際上,在c++中鼓勵你這么使用for,不讓它外流,這種東西在vc6.0會出點問題(因為它不是標準的c++),因為i的作用域會外流,所以你就不能寫for(int i;;)這樣的語句兩次,它會報錯說你重定義了。而在c語言中,之前是不支持for(int i;;)這種定義方式的,不過在c99的時候,它也支持了,并鼓勵你這樣寫。
并且,通過這個搜捕器,它的條件是a[i]!=‘c’&&i!=N,所以循環終止時,是a[i]==‘c’||i==N這就是我之前說的終止條件,我們就可以在之后寫這樣的語句;
if(i==N)//沒找到else//找到了。i 是它的下標
這就是為什么用’!=’而不是《的原因了,這可以很清楚的看清終止條件。
以上就是今天的分享,小伙伴們可以點個贊支持一下喲~
編輯:jq
-
cpu
+關注
關注
68文章
10877瀏覽量
212129 -
產生器
+關注
關注
0文章
25瀏覽量
20090 -
函數
+關注
關注
3文章
4338瀏覽量
62734 -
for循環
+關注
關注
0文章
61瀏覽量
2512
原文標題:C語言編程筆記:關于 for循環 的那些不為人知的秘密!
文章出處:【微信號:xx-cyy,微信公眾號:C語言編程基礎】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論