<style>
html, body, .ui-content {
background-color: #333;
color: #ddd;
}
body > .ui-infobar {
display: none;
}
.ui-view-area > .ui-infobar {
display: block;
}
.markdown-body h1{
color: #9CCEF2;
}
.markdown-body h2,
.markdown-body h3{
color: #B1D6CA;
}
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
color: #ddd;
}
.markdown-body h1,
.markdown-body h2 {
border-bottom-color: #ffffff69;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #fff;
}
.markdown-body img {
background-color: transparent;
}
.ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a {
color: white;
border-left: 2px solid white;
}
.expand-toggle:hover,
.expand-toggle:focus,
.back-to-top:hover,
.back-to-top:focus,
.go-to-bottom:hover,
.go-to-bottom:focus {
color: white;
}
.ui-toc-dropdown {
background-color: #333;
}
.ui-toc-label.btn {
background-color: #191919;
color: white;
}
.ui-toc-dropdown .nav>li>a:focus,
.ui-toc-dropdown .nav>li>a:hover {
color: white;
border-left: 1px solid white;
}
.markdown-body blockquote {
color: #bcbcbc;
}
.markdown-body table tr {
background-color: #5f5f5f;
}
.markdown-body table tr:nth-child(2n) {
background-color: #4f4f4f;
}
.markdown-body code,
.markdown-body tt {
color: #eee;
background-color: rgba(230, 230, 230, 0.36);
}
a,
.open-files-container li.selected a {
color: #5EB7E0;
}
</style>
###### tags: `tgirc早修book`
# 巢狀迴圈
有些時候會需要在迴圈中再放一層迴圈,分成彼此有關聯以及彼此沒關聯兩種
## 內外層不相干
<font color="F5F6B6">**試著透過 for 畫出一個邊長為 n 的正方形吧**</font>

想輸出這樣的矩形,可以分成兩部分,輸出 n 個 \* 的寬,再輸出 n 排,又可以說是分成一個會重複輸出 n 個 * 的迴圈跟一個會反覆輸出 n 排有 n 個 * 的迴圈
一個個步驟來看,先做出一層輸出寬的迴圈
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
int i;
for(int i=0;i<n;i++){
cout<<'*';
}
return 0;
}
```
現在做好了寬,接著重複輸出 n 排寬
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int i,j;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
cout<<"*";
}
}
return 0;
}
```
最後放入換行,因為換行要等寬都輸出完,所以只能放在外層的迴圈,當然也可以放在內層中看看最後輸出會變怎樣
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int i,j;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
迴圈沒有必要一定要塞在一層內,像這樣的多層迴圈反而能更好閱讀以及更輕易的抓出錯誤
## 內外層相干
知道了該如何做出三角形,接著<font color="F5F6B6">**試著輸出邊長為 n 的直角三角形吧**</font>

透過觀察,我們可以知道三角形在第一層時輸出一個 * 第二層兩個,以此類推,這次我們先建好一個高,長為 n
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
}
return 0;
}
```
和輸出矩形的步驟一樣,放入內層的迴圈與換行
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
從前面的觀察可以知道三角形在第一層時輸出一個 \*,第二層兩個,以此類推,因此把這個邏輯套到程式內,i 跟三角形每層輸出的 * 一樣,每次都加一,所以可以把內層的 n 替換成 i
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){ //n 換成 i
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
但現在又有個問題, i 一開始是 0,如果這樣的話,內層的迴圈就達不到設定的條件,如果要解決這個問題,那就讓 i 直接變成從 1 開始就搞定了
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){ //令 i == 1
for(int j=0;j<i;j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
只是當 i 是 1 時,使用 i < n 的話,會少掉一次,這時的條件要變成 i <= n,當然如果要改成 i < n+1 也可以
接下來試試該如何輸出倒過來且底和高長度是 n 的直角三角形,以及高是 n 的等腰三角形,輸出圖案如下圖所示:
高度長 n 的倒直角三角形

```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<=n-i;j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
高是 n 的等腰三角形

```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++){
cout<<"*";
}
cout<<"\n";
}
for(int i=1;i<=n;i++){
for(int j=0;j<n-i;j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
## 更複雜的巢狀迴圈
<font color="F5F6B6">**輸出一個邊長為 n 的平行四邊形**</font>

透過這張圖,我們可以分析出,它是由一個倒直角三角形加上一個正方形所組成的

運用輸出正方形的程式碼(在練習時請自己重新打一個,不要用複製貼上的方式,否則無法增加熟練度)
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int i,j;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
和倒直角三角形的程式碼
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<=n-i;j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
將它們結合起來即可得到一個邊長為 n 的平行四邊形,由於會先輸出倒直角三角形,把輸出的指令放在上方
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<=n-i;j++){ //輸出倒三角
cout<<" ";
}
cout<<"\n";
}
return 0;
}
```
接著放入正方形的指令
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<=n-i;j++){
cout<<" ";
}
for(int j=0;j<=n-i;j++){ //輸出正方形
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
但很重要的一點是,倒三角形的高是 n-1,可是平行四邊形是 n,因此要修改一下倒三角形的條件式
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<n-i;j++){ //修改成 j < n-1
cout<<" ";
}
for(int j=0;j<n;j++){
cout<<"*";
}
cout<<"\n";
}
return 0;
}
```
將倒直角三角形中的 `j <= n-i` 的部分,修改成 `j < n-i`,這樣就能只輸出邊長為 n-1 的倒直角三角形了