1 00:00:00,000 --> 00:00:00,309 2 00:00:00,309 --> 00:00:02,350 [? DAN ARMADARAS:?]你好, 我[?丹Armadaras?]。 3 00:00:02,350 --> 00:00:04,410 今天,我們要 在看調試。 4 00:00:04,410 --> 00:00:06,697 我們不僅要 談一些技巧, 5 00:00:06,697 --> 00:00:09,280 而且我們要看看 一些特性包含 6 00:00:09,280 --> 00:00:14,170 在CS50 IDE允許範圍內 您可以輕鬆地調試程序。 7 00:00:14,170 --> 00:00:16,272 >> 只是一個例子, 東西可以去錯 8 00:00:16,272 --> 00:00:18,730 它實際上是什麼 我們已經看到了。 9 00:00:18,730 --> 00:00:23,200 在這種情況下,這是一個C程序 接受來自用戶的整數, 10 00:00:23,200 --> 00:00:27,580 除以它由兩個,並提供了 輸出給用戶。 11 00:00:27,580 --> 00:00:30,610 現在從我們所看到的 在前面講課, 12 00:00:30,610 --> 00:00:34,370 我們知道,這實際上會導致 特定類型的劃分問題 13 00:00:34,370 --> 00:00:35,860 當我們有奇數。 14 00:00:35,860 --> 00:00:40,330 >> 具體來說,我們就扔掉 小數點後的任何東西。 15 00:00:40,330 --> 00:00:43,170 現在,我們知道,這 恰好是這種情況。 16 00:00:43,170 --> 00:00:47,430 如果我們運行它,我們可以確認 我們的懷疑,首先,通過編譯。 17 00:00:47,430 --> 00:00:50,460 然後,通過運行和 輸入奇數。 18 00:00:50,460 --> 00:00:51,720 >> 這是什麼新鮮事。 19 00:00:51,720 --> 00:00:54,490 但是,這實際上是一個 例如一個錯誤的 20 00:00:54,490 --> 00:00:58,810 可以在一個更大的計劃存在 這變得更難追查。 21 00:00:58,810 --> 00:01:02,640 儘管我們知道是什麼問題 是,事情的真正癥結所在 22 00:01:02,640 --> 00:01:06,250 可能會試圖確定 具體在哪裡出現錯誤, 23 00:01:06,250 --> 00:01:09,750 確定是什麼問題 是,然後將其固定。 24 00:01:09,750 --> 00:01:14,400 因此,提供這作為一個例子 的可能是什麼東西 25 00:01:14,400 --> 00:01:19,030 我們已經知道,但可以埋 內的代碼的其他元素。 26 00:01:19,030 --> 00:01:23,090 >> 所以打開這個其他來源 代碼文件作為例子, 27 00:01:23,090 --> 00:01:27,165 這種劃分問題是現在 一個較大的程序的一部分。 28 00:01:27,165 --> 00:01:29,040 不過可能有點 有點做作,和我們 29 00:01:29,040 --> 00:01:31,076 可能能夠容易地 識別它,特別是 30 00:01:31,076 --> 00:01:32,450 因為我們剛才談到的這一點。 31 00:01:32,450 --> 00:01:38,250 但是,我們可以計算出,這 問題可以在更大的範圍存在。 32 00:01:38,250 --> 00:01:45,450 >> 如果我編譯這個和現在 運行它,輸入一個奇數, 33 00:01:45,450 --> 00:01:49,816 我們可以看到,我們沒有得到準確 我們可能預期的輸出。 34 00:01:49,816 --> 00:01:51,690 在這種特殊情況下, 我們可以說,我們 35 00:01:51,690 --> 00:01:56,060 要計算所有號碼 從一個到某個特定數量。 36 00:01:56,060 --> 00:01:58,130 我們可以看到,我們 有各種各樣的問題 37 00:01:58,130 --> 00:02:03,880 在這裡,如果我們輸,簡單地說,0 和1時,我們提供的5輸入。 38 00:02:03,880 --> 00:02:07,380 >> 因此,我們已經知道, 有一個問題在這裡。 39 00:02:07,380 --> 00:02:11,662 但是大家可能不知道準確 其中,這個問題確實存在。 40 00:02:11,662 --> 00:02:13,620 現在的方法之一是 我們可以嘗試解決這個問題 41 00:02:13,620 --> 00:02:15,745 是,我們的東西 已經被引入。 42 00:02:15,745 --> 00:02:18,880 我們可以只使用它在更大的規模。 43 00:02:18,880 --> 00:02:21,680 >> 在第14行,我們有 這個printf函數, 44 00:02:21,680 --> 00:02:25,620 這使我們能夠打印出狀態 的各種信息。 45 00:02:25,620 --> 00:02:28,880 這是東西,你 應在程序中利用 46 00:02:28,880 --> 00:02:33,100 要盡量弄清楚到底是什麼 發生在各行代碼。 47 00:02:33,100 --> 00:02:36,350 因此,即使這不是 我們實際上最終的輸出 48 00:02:36,350 --> 00:02:39,830 要生產出 這個計劃,我們仍然 49 00:02:39,830 --> 00:02:42,300 可能有一些調試 聲明我們 50 00:02:42,300 --> 00:02:46,970 可以揣摩正是 正在發生的事情對我們的代碼中。 51 00:02:46,970 --> 00:02:51,210 >> 因此,在這種情況下,我會 printf輸出調試標籤。 52 00:02:51,210 --> 00:02:53,540 在這種情況下,這是 只是一個調試字符串 53 00:02:53,540 --> 00:02:56,840 說我了,把使之成為 在我的代碼的輸出非常明確 54 00:02:56,840 --> 00:02:59,200 它是什麼,我想展示。 55 00:02:59,200 --> 00:03:04,410 而這裡輸出的數量 我們已計算。 56 00:03:04,410 --> 00:03:06,800 >> 在這種情況下,我可能會 想知道準確 57 00:03:06,800 --> 00:03:11,380 發生了什麼之前和 經過一些特定的計算。 58 00:03:11,380 --> 00:03:16,224 所以,我可能會使用前一個printf 與該行代碼後。 59 00:03:16,224 --> 00:03:18,640 在這種情況下,我連 使其多一點點清晰 60 00:03:18,640 --> 00:03:21,960 通過之前說的調試 並經過調試等等 61 00:03:21,960 --> 00:03:26,540 我不混淆自己 多行看起來完全相同。 62 00:03:26,540 --> 00:03:32,290 >> 現在,如果我們重新編譯這個和運行 它,再輸入一個數字到五, 63 00:03:32,290 --> 00:03:35,090 我們可以看到,我們有 現在,前後輸出 64 00:03:35,090 --> 00:03:40,670 並且發現,我們沒有做明確的 數師或明確有 65 00:03:40,670 --> 00:03:43,680 我們真正想要做的。 66 00:03:43,680 --> 00:03:48,660 現在,在這種情況下,這是 不是一個真正的清晰輸出。 67 00:03:48,660 --> 00:03:52,440 這不是一個真正的明確的結果是 我們想從這個特定的程序。 68 00:03:52,440 --> 00:03:54,427 >> 這是,再等 有點做作。 69 00:03:54,427 --> 00:03:57,510 但是,也許的事情之一 我們可以做,如果說明書說 70 00:03:57,510 --> 00:04:01,900 我們希望通過劃分這 2,並添加1--所以換句話說, 71 00:04:01,900 --> 00:04:04,550 我們要舍up--然後 我們能知道我們能 72 00:04:04,550 --> 00:04:08,060 這樣做特別的事情,在這種情況下。 73 00:04:08,060 --> 00:04:14,010 現在,在這裡,我們知道,我們將 能加1到我們的一半數量。 74 00:04:14,010 --> 00:04:16,490 >> 讓我們重新編譯這個 並確認此 75 00:04:16,490 --> 00:04:18,860 行為是我們想要的方式。 76 00:04:18,860 --> 00:04:21,980 我們現在才看到, 有,我們有數字5。 77 00:04:21,980 --> 00:04:26,620 有後,我們有3號, 它根據我們的說明書中, 78 00:04:26,620 --> 00:04:29,292 就是我們想做的事。 79 00:04:29,292 --> 00:04:31,000 但是,如果我們看一下 輸出這裡,我們可以 80 00:04:31,000 --> 00:04:33,760 看到我們可能有另一個 完全錯誤,這是 81 00:04:33,760 --> 00:04:36,940 我們是從0開始計數了。 82 00:04:36,940 --> 00:04:39,390 >> 現在再次,這是一件 我們已經看到在過去 83 00:04:39,390 --> 00:04:42,500 我們可以很容易解決。 84 00:04:42,500 --> 00:04:44,790 但在這種情況下,我們 也有益處 85 00:04:44,790 --> 00:04:48,940 使用printf語句的 直接在for循環 86 00:04:48,940 --> 00:04:52,930 準確地知道在哪裡 該錯誤發生。 87 00:04:52,930 --> 00:04:55,150 所以printf的聲明 在幫助非常有用 88 00:04:55,150 --> 00:04:57,940 你確定, 正是在你的源代碼, 89 00:04:57,940 --> 00:05:00,620 一個特定的錯誤發生。 90 00:05:00,620 --> 00:05:03,650 >> 而且這也是很重要的實現 如此,當我們在寫代碼, 91 00:05:03,650 --> 00:05:06,052 大家可能都假設 約的節目的狀態。 92 00:05:06,052 --> 00:05:08,510 或者我們可能有假設 關於什麼是計劃的一部分 93 00:05:08,510 --> 00:05:13,020 實際上是正確或不正確時, 後來,我們建立在該程序 94 00:05:13,020 --> 00:05:15,950 並使其一部分 複雜的大型項目 95 00:05:15,950 --> 00:05:19,700 我們認識到,某些方面 那其實是馬車。 96 00:05:19,700 --> 00:05:22,680 >> 用printf可以真正幫助 縮小並確定 97 00:05:22,680 --> 00:05:26,430 程序的區域可能不 要準確地行為的方式,我們 98 00:05:26,430 --> 00:05:29,500 預計,基於我們的假設。 99 00:05:29,500 --> 00:05:31,460 但是,還有其他工具 可用,還有, 100 00:05:31,460 --> 00:05:34,860 這使我們能夠揣摩 出在哪裡發生異常 101 00:05:34,860 --> 00:05:39,930 而且,具體而言,有什麼事情 正在發生的程序裡面。 102 00:05:39,930 --> 00:05:41,990 >> 因此,用printf非常 有用當我們要 103 00:05:41,990 --> 00:05:45,900 以確定的特定區域 一個程序,有一定的缺陷。 104 00:05:45,900 --> 00:05:47,730 但它也變得 一段時間後,乏味。 105 00:05:47,730 --> 00:05:50,500 在這種情況下,這是一個 比較簡單的程序 106 00:05:50,500 --> 00:05:52,750 只有一個或兩個變量。 107 00:05:52,750 --> 00:05:57,260 而且它變得非常容易讓我們 打印出這些變量的值 108 00:05:57,260 --> 00:05:59,670 在較大的程序的情況下。 109 00:05:59,670 --> 00:06:02,670 >> 但是,我們可能有不同的 程序,有很多變數。 110 00:06:02,670 --> 00:06:06,530 並且它可能不是很 這麼好用的printf 111 00:06:06,530 --> 00:06:10,120 嘗試評估正在發生什麼 對這些變量中的每一個 112 00:06:10,120 --> 00:06:13,590 作為上述程序的執行。 113 00:06:13,590 --> 00:06:16,960 有一個程序存在 所謂調試程序。 114 00:06:16,960 --> 00:06:20,320 在這種情況下,一個我們將 使用的是GNU調試器或GDB, 115 00:06:20,320 --> 00:06:24,260 這使我們能夠檢查內部 一個程序的在一個更運作 116 00:06:24,260 --> 00:06:25,700 詳細方法。 117 00:06:25,700 --> 00:06:28,810 >> 事實上,我們可以執行 GDB的命令行 118 00:06:28,810 --> 00:06:35,370 在這裡,只需鍵入GDB和 我們要調試命令。 119 00:06:35,370 --> 00:06:37,550 在這種情況下,指望。 120 00:06:37,550 --> 00:06:41,650 現在,在這種情況下,我們可以看到,它 給我們帶來了一個提示GDB的說。 121 00:06:41,650 --> 00:06:44,020 而我們實際上可以 執行命令GDB 122 00:06:44,020 --> 00:06:48,260 實際開始執行的 計劃,停止在某些點, 123 00:06:48,260 --> 00:06:51,060 評估的變量和 檢查變量 124 00:06:51,060 --> 00:06:54,152 存在於程序狀態 在該特定時刻, 125 00:06:54,152 --> 00:06:55,110 等,等等。 126 00:06:55,110 --> 00:06:57,240 它提供了大量的電力給我們。 127 00:06:57,240 --> 00:06:59,960 >> 但它只是恰巧 該CS50 IDE還 128 00:06:59,960 --> 00:07:05,870 提供了一個GUI或用戶 接口GDB的 129 00:07:05,870 --> 00:07:11,120 使我們能夠做到這一點,而無需 命令行界面任何 130 00:07:11,120 --> 00:07:13,560 或甚至全部。 131 00:07:13,560 --> 00:07:16,930 我可以訪問的方法 是通過使用調試按鈕 132 00:07:16,930 --> 00:07:20,120 在CS50 IDE的最頂端。 133 00:07:20,120 --> 00:07:24,280 現在,在過去,我們所擁有的 可見的是,我們使用命令 134 00:07:24,280 --> 00:07:27,660 行編譯,然後運行程序。 135 00:07:27,660 --> 00:07:29,790 >> 調試按鈕的功能 二者的那些步驟。 136 00:07:29,790 --> 00:07:34,380 但它也帶來了 最右邊的調試器選項卡 137 00:07:34,380 --> 00:07:38,280 這使我們能夠檢查各種 該方案的性能的 138 00:07:38,280 --> 00:07:40,500 因為它正在執行。 139 00:07:40,500 --> 00:07:44,280 如果我點擊調試,在此 情況下,它會彈出 140 00:07:44,280 --> 00:07:48,230 在控制台中的新選項卡 窗口在最底層。 141 00:07:48,230 --> 00:07:51,160 >> 你可以看到這個選項卡 一些信息在最高層。 142 00:07:51,160 --> 00:07:52,670 我們可以在很大程度上忽略了這一點。 143 00:07:52,670 --> 00:07:54,800 不過的事情之一 我們要注意 144 00:07:54,800 --> 00:07:57,170 是,它輸出 同樣的事情,我們 145 00:07:57,170 --> 00:08:03,000 會得到,如果我們試圖運行make在 C程序的終端窗口。 146 00:08:03,000 --> 00:08:06,230 >> 在這裡,我們可以看到它的運行鐺, 它有各種標誌, 147 00:08:06,230 --> 00:08:12,660 並且它編譯我們count.c文件, 這在當時所選標籤 148 00:08:12,660 --> 00:08:15,100 我打的調試。 149 00:08:15,100 --> 00:08:18,010 因此,這是因為非常有用的 現在用這個調試按鈕, 150 00:08:18,010 --> 00:08:23,280 我們可以同時編譯,然後 執行程序,我們實際上 151 00:08:23,280 --> 00:08:24,460 要運行。 152 00:08:24,460 --> 00:08:27,880 >> 之一是標誌 重要的是,在這種情況下, 153 00:08:27,880 --> 00:08:30,190 我們實際使用過 時間最長 154 00:08:30,190 --> 00:08:32,450 但也只是做了一些手 揮手[聽不清],其中 155 00:08:32,450 --> 00:08:33,820 這是一個正確的位置。 156 00:08:33,820 --> 00:08:35,790 在鏗鏘,它說-ggdb3。 157 00:08:35,790 --> 00:08:38,570 158 00:08:38,570 --> 00:08:41,250 在這種情況下,我們都 告訴鐺,我們的編譯器, 159 00:08:41,250 --> 00:08:43,820 就是我們要編譯我們的節目。 160 00:08:43,820 --> 00:08:46,810 但也提供了什麼 所謂的符號信息 161 00:08:46,810 --> 00:08:50,940 從而使編譯器實際訪問 來了很多底層信息的 162 00:08:50,940 --> 00:08:52,610 包含在程序中。 163 00:08:52,610 --> 00:08:55,260 >> 更具體地,數 對我有作用, 164 00:08:55,260 --> 00:08:58,000 這些函數的名稱, 變量,其種類 165 00:08:58,000 --> 00:09:01,730 這些變量是,和各種 其他的事情,幫助調試器 166 00:09:01,730 --> 00:09:04,350 執行它的操作。 167 00:09:04,350 --> 00:09:06,600 現在有別的東西 這是重要的提 168 00:09:06,600 --> 00:09:10,280 當我們討論運行 一個程序以這種方式。 169 00:09:10,280 --> 00:09:13,660 >> 請注意,它實際上已經 提出了一個新的標籤在我們的控制台 170 00:09:13,660 --> 00:09:14,780 沿底部。 171 00:09:14,780 --> 00:09:18,600 我們不再需要互動 直接與終端窗口。 172 00:09:18,600 --> 00:09:21,420 但這個新選項卡 實際上是一個終端窗口。 173 00:09:21,420 --> 00:09:26,710 它只是特定於運行 我們已經創建的程序。 174 00:09:26,710 --> 00:09:29,270 >> 注意,在底部,在 一些輸出組合 175 00:09:29,270 --> 00:09:33,500 通過鐺編譯器和GDB, 我們可以在很大程度上忽略了, 176 00:09:33,500 --> 00:09:37,570 它實際上顯示的輸出 我們的節目在最底層。 177 00:09:37,570 --> 00:09:41,240 現在,實現重要 這一個窗口實際上 178 00:09:41,240 --> 00:09:43,360 會告訴你 從你的程序輸出 179 00:09:43,360 --> 00:09:47,190 但也可以接受輸入 該程序,也是如此。 180 00:09:47,190 --> 00:09:49,260 >> 因此,通知,上面寫著 請輸入一個數字, 181 00:09:49,260 --> 00:09:53,050 這是我們有相同的輸出 曾在終端窗口前。 182 00:09:53,050 --> 00:09:55,510 但它現在在這個新的選項卡中顯示。 183 00:09:55,510 --> 00:09:56,550 我可以輸入一個數字。 184 00:09:56,550 --> 00:10:00,900 它實際上 如我們預期的功能 185 00:10:00,900 --> 00:10:05,890 向我們展示了我們的調試輸出, 輸出可能是越野車, 186 00:10:05,890 --> 00:10:07,010 正如我們之前看到的。 187 00:10:07,010 --> 00:10:10,460 而在最底層,它 實際上有一些額外的輸出 188 00:10:10,460 --> 00:10:14,550 從GDP中只是說 這一計劃已完成。 189 00:10:14,550 --> 00:10:16,655 >> 現在,當你在這個看到的 特別是貫穿, 190 00:10:16,655 --> 00:10:19,370 這是沒有特別 有用的,因為即使是 191 00:10:19,370 --> 00:10:23,740 雖然我們已經調試器菜單來 起來,這仍然是一個正在運行的程序。 192 00:10:23,740 --> 00:10:26,790 在任何時候,它實際上 暫停執行對我們 193 00:10:26,790 --> 00:10:30,767 要能夠檢查所有的 內包含的變量。 194 00:10:30,767 --> 00:10:32,850 還有別的東西 我們必須做的,為了 195 00:10:32,850 --> 00:10:36,910 讓GDB認識到,我們要 暫停程序的執行 196 00:10:36,910 --> 00:10:42,820 而不是只允許它繼續 通常,我們會在任何其他情況下。 197 00:10:42,820 --> 00:10:45,530 >> 為了暫停執行, 在一些具體的線路, 198 00:10:45,530 --> 00:10:47,830 我們需要創建什麼 叫一個破發點。 199 00:10:47,830 --> 00:10:52,670 而一個破發點很容易產生 在這CS50 IDE通過利用鼠標 200 00:10:52,670 --> 00:10:57,090 並直接點擊向左 的一些具體的行號。 201 00:10:57,090 --> 00:10:59,920 一旦我做到這一點,一個紅點 出現,這表明 202 00:10:59,920 --> 00:11:02,300 即該行現在是一個破發點。 203 00:11:02,300 --> 00:11:07,540 >> 而下一次我運行GDB,它 將在該斷點停止執行 204 00:11:07,540 --> 00:11:10,280 當它到達該行代碼。 205 00:11:10,280 --> 00:11:12,230 現在,這是一個重要的 事情來實現 206 00:11:12,230 --> 00:11:16,140 這並不一定是 情況下每行代碼 207 00:11:16,140 --> 00:11:17,880 實際上是訪問。 208 00:11:17,880 --> 00:11:23,780 如果我要創建一個函數 在這裡,對於example--空F-- 209 00:11:23,780 --> 00:11:31,230 而只是做一個打印線這裡 - 你好 天下 - 如果我從來沒有調用這個函數, 210 00:11:31,230 --> 00:11:34,770 它會是這樣的情況, 如果我在這裡設置一個破發點, 211 00:11:34,770 --> 00:11:36,220 功能將永遠不會被調用。 212 00:11:36,220 --> 00:11:38,310 因此,這 尤其是破發點 213 00:11:38,310 --> 00:11:43,040 將實際上從未暫停 程序的執行。 214 00:11:43,040 --> 00:11:48,020 >> 所以我們可以說,我正確地創建 在編寫一些代碼行一個破發點 215 00:11:48,020 --> 00:11:50,340 實際上將被執行。 216 00:11:50,340 --> 00:11:53,470 現在,在這種情況下,這是 在主函數中第一行。 217 00:11:53,470 --> 00:11:56,630 因此,這將肯定是這樣的 即,只要我開始執行, 218 00:11:56,630 --> 00:11:58,580 在第一行必達。 219 00:11:58,580 --> 00:12:00,230 廣發行將暫停執行。 220 00:12:00,230 --> 00:12:04,100 然後,我就可以 與調試器進行交互。 221 00:12:04,100 --> 00:12:08,480 >> 您可以設置多條線路為 斷點,如果你想。 222 00:12:08,480 --> 00:12:11,365 我們也可以創建一個排隊 在這裡這段代碼中 223 00:12:11,365 --> 00:12:12,490 永遠不會到達。 224 00:12:12,490 --> 00:12:14,744 而且我們還可以設置一個另外的下面。 225 00:12:14,744 --> 00:12:16,660 究其原因,我們將 要做到這一點,我們將 226 00:12:16,660 --> 00:12:19,119 進入多一點點 詳細一會兒就好了。 227 00:12:19,119 --> 00:12:21,660 所以現在,我只想禁用 這些額外的破發點 228 00:12:21,660 --> 00:12:24,940 這樣我們就可以看看會發生什麼 當我有一個單一的突破 229 00:12:24,940 --> 00:12:27,650 點在我的計劃。 230 00:12:27,650 --> 00:12:29,410 我已經取得了一些 改變這一計劃。 231 00:12:29,410 --> 00:12:30,750 所以,我要保存它。 232 00:12:30,750 --> 00:12:34,490 我會點擊調試,這樣我就可以 開始編譯,然後 233 00:12:34,490 --> 00:12:36,880 執行調試器。 234 00:12:36,880 --> 00:12:40,632 >> 我們將看到,時刻,後 我們選擇作為斷線 235 00:12:40,632 --> 00:12:43,360 點以黃色突出顯示。 236 00:12:43,360 --> 00:12:47,440 我們還可以看到,在 右上角的調試面板 237 00:12:47,440 --> 00:12:50,940 該暫停圖標已經變成 進入一個小播放圖標。 238 00:12:50,940 --> 00:12:54,710 這意味著,我們必須暫停 執行,在該特定情況下。 239 00:12:54,710 --> 00:12:57,840 而且打的播放按鈕會 讓我們繼續執行 240 00:12:57,840 --> 00:13:00,000 在該特定的點。 241 00:13:00,000 --> 00:13:03,240 >> 請注意,還有幾個其他的 在此調試面板可用按鈕, 242 00:13:03,240 --> 00:13:04,220 為好。 243 00:13:04,220 --> 00:13:09,470 步過,這讓我 執行該一行代碼 244 00:13:09,470 --> 00:13:14,030 並加強了該行的 下一個,其中,在這種情況下, 245 00:13:14,030 --> 00:13:17,060 將意味著printf的 被執行的語句。 246 00:13:17,060 --> 00:13:22,310 它將然後暫停 執行第13行,像這樣。 247 00:13:22,310 --> 00:13:25,090 >> 而且還有一個步驟 進入功能, 248 00:13:25,090 --> 00:13:28,950 如果我創建了其他非常有用 功能在源代碼中其他地方。 249 00:13:28,950 --> 00:13:31,420 我想踏進 這些功能,而不是 250 00:13:31,420 --> 00:13:33,050 執行該功能為一體。 251 00:13:33,050 --> 00:13:37,279 但是,我們會看到更多的步驟 成在短短的一瞬間功能。 252 00:13:37,279 --> 00:13:40,320 現在注意到一些其他的東西, 此調試面板中實際存在。 253 00:13:40,320 --> 00:13:44,110 >> 我們有這個小組被稱為 調用堆棧,它向我們展示了 254 00:13:44,110 --> 00:13:45,300 到底在哪我們。 255 00:13:45,300 --> 00:13:48,550 在這種情況下,我們都在裡面 的主要功能。 256 00:13:48,550 --> 00:13:50,880 我們的腳本被稱為count.c。 257 00:13:50,880 --> 00:13:53,820 而我們正好是在 線13,列中的一個,其 258 00:13:53,820 --> 00:13:58,950 正是高亮區域 的源代碼指示,以及。 259 00:13:58,950 --> 00:14:02,435 >> 現在請注意,這也顯示了 在局部變量節 260 00:14:02,435 --> 00:14:06,710 所有的變量是 這個函數中存在。 261 00:14:06,710 --> 00:14:08,930 要注意這一點很重要 所有的變量的 262 00:14:08,930 --> 00:14:12,580 將出現在這個局部變量 一個函數內部分, 263 00:14:12,580 --> 00:14:14,380 甚至在它們被定義。 264 00:14:14,380 --> 00:14:19,160 在這裡我們可以看到,我們有一個變量 中名為num,擁有默認值為0, 265 00:14:19,160 --> 00:14:21,280 它是int類型的。 266 00:14:21,280 --> 00:14:24,110 >> 現在擺在我們實際初始化 所有這些變量, 267 00:14:24,110 --> 00:14:26,685 我們不一定 保證看到的值為0。 268 00:14:26,685 --> 00:14:29,200 和取決於其他處決 已執行 269 00:14:29,200 --> 00:14:32,020 和你的內存時的狀態 你真正運行這個程序, 270 00:14:32,020 --> 00:14:34,605 你可能會發現你 看不到的0值 271 00:14:34,605 --> 00:14:36,550 和,相反,一些其它瘋狂的數字。 272 00:14:36,550 --> 00:14:38,390 >> 但不要擔心。 273 00:14:38,390 --> 00:14:44,610 它不會是相關的,直到 你居然初始化值。 274 00:14:44,610 --> 00:14:49,630 現在,在這種情況下,我們可以看到, 我已經進行了一些輸出。 275 00:14:49,630 --> 00:14:52,131 而我,現在,暫停執行。 276 00:14:52,131 --> 00:14:53,880 但在這種情況下,什麼 我真正想做的事情 277 00:14:53,880 --> 00:14:58,060 就是到現在跨過這條線 的代碼,這樣我實際上可以 278 00:14:58,060 --> 00:15:04,390 查詢該INT用戶的 我們希望在我們的程序中使用。 279 00:15:04,390 --> 00:15:07,060 >> 現在,在這種情況下,當 我打了一步,通知 280 00:15:07,060 --> 00:15:11,940 該暫停或者說恢復 按鈕已更改為這個暫停按鈕 281 00:15:11,940 --> 00:15:14,022 因為這段代碼實際上執行。 282 00:15:14,022 --> 00:15:15,730 怎麼了 現在的問題是,它是 283 00:15:15,730 --> 00:15:21,630 等待我們輸入一些信息 因為我們可以通過我們的輸出文本見 284 00:15:21,630 --> 00:15:23,600 在最底層。 285 00:15:23,600 --> 00:15:25,787 >> 所以,現在,這是 實際上沒有暫停, 286 00:15:25,787 --> 00:15:28,620 即使它,排序,出現 是因為什麼也沒有發生。 287 00:15:28,620 --> 00:15:32,360 但它只是恰巧,在 我對13號線的具體情況, 288 00:15:32,360 --> 00:15:34,210 我在等待用戶輸入。 289 00:15:34,210 --> 00:15:39,130 所以GDB不能檢查 一個程序,因為它正在運行。 290 00:15:39,130 --> 00:15:43,370 >> 現在,我進入了一些,下一次 input--所以我會輸入數字5, 291 00:15:43,370 --> 00:15:46,140 正如我們所看到的 past--按回車,我們 292 00:15:46,140 --> 00:15:51,430 請注意,立即暫停GDB 並再次強調了下一行。 293 00:15:51,430 --> 00:15:55,320 但現在發現,作為 我們的輸入值的結果, 294 00:15:55,320 --> 00:15:58,930 我們裡面更新的價值 我們的局部變量,哪個 295 00:15:58,930 --> 00:16:05,560 為準確地知道非常有用 是什麼數為在內存中。 296 00:16:05,560 --> 00:16:10,650 >> 現在,我可以允許此程序繼續運行 玩到其執行結束 297 00:16:10,650 --> 00:16:12,570 擊中恢復。 298 00:16:12,570 --> 00:16:16,410 我們可以看到,非常快 請問程序執行完畢 299 00:16:16,410 --> 00:16:19,790 具有相同的輸出,我們 收到,調試器關閉, 300 00:16:19,790 --> 00:16:23,170 現在這個計劃 完全停止。 301 00:16:23,170 --> 00:16:25,320 >> 我表明,只有在 用途看什麼 302 00:16:25,320 --> 00:16:27,280 發生在我們居然打簡歷。 303 00:16:27,280 --> 00:16:30,640 但是實際上我們要 要返回到該程序 304 00:16:30,640 --> 00:16:33,820 這樣我們就可以嘗試調試 正是正在發生的事情。 305 00:16:33,820 --> 00:16:37,980 現在,我使用調試器,我可能 並不需要這些調試printf的語句。 306 00:16:37,980 --> 00:16:43,860 >> 所以,我可以將其刪除,因為我會做 現在只是回到我們的簡單的代碼 307 00:16:43,860 --> 00:16:45,950 我們過會兒前。 308 00:16:45,950 --> 00:16:48,790 現在,當我保存 編程並執行它, 309 00:16:48,790 --> 00:16:53,700 它將再次進入初始 突破一點,我對11行。 310 00:16:53,700 --> 00:16:57,700 而我就可以檢查 我的變量我想做的事情。 311 00:16:57,700 --> 00:17:00,695 >> 它只是恰巧,這 部分是不是很有趣, 312 00:17:00,695 --> 00:17:04,364 我知道,我要去 打印出這個聲明。 313 00:17:04,364 --> 00:17:05,280 請輸入一個數字。 314 00:17:05,280 --> 00:17:08,099 然後,我知道我要去 索要該整數用戶。 315 00:17:08,099 --> 00:17:13,329 所以,或許,其實我是想動我的 向下突破點得遠一點。 316 00:17:13,329 --> 00:17:16,710 >> 您可以刪除斷點 通過點擊,再次,直接 317 00:17:16,710 --> 00:17:18,460 到的該行編號的左側。 318 00:17:18,460 --> 00:17:22,200 這紅點消失時表示 這是破發點現在已經沒有了。 319 00:17:22,200 --> 00:17:24,780 現在,在這種情況下, 執行已暫停。 320 00:17:24,780 --> 00:17:27,770 所以它實際上沒有打算 恢復在該特定實例。 321 00:17:27,770 --> 00:17:30,210 但是,我可以設置一個斷點 在稍後一點。 322 00:17:30,210 --> 00:17:33,880 >> 當我現在恢復 代碼,它會繼續,並告訴 323 00:17:33,880 --> 00:17:36,190 如此地步,斷點。 324 00:17:36,190 --> 00:17:37,374 同樣,我打了簡歷。 325 00:17:37,374 --> 00:17:39,040 似乎不喜歡什麼正在發生的事情。 326 00:17:39,040 --> 00:17:41,450 但是,這是因為我的 代碼等待輸入。 327 00:17:41,450 --> 00:17:47,900 我將進入5號,敲回車,和 現在,下一個斷點將受到打擊。 328 00:17:47,900 --> 00:17:50,570 >> 現在,在這種情況下,這 是代碼行 329 00:17:50,570 --> 00:17:53,820 ,在此之前,我們就知道 正好是馬車。 330 00:17:53,820 --> 00:17:57,590 因此,讓我們評估發生了什麼 在這一時代的特殊點。 331 00:17:57,590 --> 00:18:02,620 當行被突出顯示,該 線尚未被執行。 332 00:18:02,620 --> 00:18:06,490 所以在這種情況下,我們可以看到 我有一個數字,它 333 00:18:06,490 --> 00:18:11,610 我有一個名為一個整數 NUM具有值為5。 334 00:18:11,610 --> 00:18:15,090 而我要表演 一些數學上的那個數字。 335 00:18:15,090 --> 00:18:20,130 >> 如果我跳過了,就可以 請注意,對於NUM值 336 00:18:20,130 --> 00:18:23,780 按照已經改變 算術,我們實際上已經完成。 337 00:18:23,780 --> 00:18:26,810 而現在,我們 這個循環裡面 338 00:18:26,810 --> 00:18:29,090 還是現在的for循環 本身是突出, 339 00:18:29,090 --> 00:18:32,450 我們可以看到,我們有一個新的 變量調用我的 340 00:18:32,450 --> 00:18:35,370 將被用在該for循環。 341 00:18:35,370 --> 00:18:38,230 >> 我現在才記 提到,有時你 342 00:18:38,230 --> 00:18:43,470 會看到某種瘋狂 數字作為默認該號碼 343 00:18:43,470 --> 00:18:45,530 或者變量 實際上初始化。 344 00:18:45,530 --> 00:18:49,040 我們可以看到,正是 在這裡的這個可變 345 00:18:49,040 --> 00:18:51,345 稱為I,其具有不 尚未初始化 346 00:18:51,345 --> 00:18:53,560 在突出的時間。 347 00:18:53,560 --> 00:18:57,070 但是,我們可以看到,它有一定的數量 我們不會真正期望的。 348 00:18:57,070 --> 00:18:57,620 >> 沒關係。 349 00:18:57,620 --> 00:18:59,661 別擔心 因為我們有沒有真正 350 00:18:59,661 --> 00:19:04,970 初始化的數量,直到我 跨過這條線與價值 351 00:19:04,970 --> 00:19:08,560 我已經被初始化為值1。 352 00:19:08,560 --> 00:19:11,400 所以一看就知道這其實 的情況下,讓我們跳過。 353 00:19:11,400 --> 00:19:14,420 現在我們可以看到,這 線已經被執行。 354 00:19:14,420 --> 00:19:17,000 而我們現在強調 這個printf的線。 355 00:19:17,000 --> 00:19:22,230 >> 我們現在可以看到我們是如何價值觀 i和3隨時間而變化。 356 00:19:22,230 --> 00:19:26,450 這是非常有用的事,事實上, 是重複步過線。 357 00:19:26,450 --> 00:19:30,480 你可以找到真正是什麼 碰巧你對循環內 358 00:19:30,480 --> 00:19:33,660 並會發生什麼變化 變量內,對於環 359 00:19:33,660 --> 00:19:39,200 作為程序執行 發生一步一個腳印的時間。 360 00:19:39,200 --> 00:19:41,110 >> 現在,在這一點上,我 跨過剛好夠用 361 00:19:41,110 --> 00:19:44,210 那我現在在我的程序結束。 362 00:19:44,210 --> 00:19:46,980 如果我跨過,它會 實際上停止執行 363 00:19:46,980 --> 00:19:48,860 正如我們已經看到在過去。 364 00:19:48,860 --> 00:19:52,110 讓我重新啟動此,再一次,所以 我可以點別的東西出來, 365 00:19:52,110 --> 00:19:53,320 為好。 366 00:19:53,320 --> 00:19:55,350 >> 在這種情況下,它是 現在問我,再次, 367 00:19:55,350 --> 00:19:57,100 為一個數字,其 我會再次進入。 368 00:19:57,100 --> 00:20:00,300 但是這一次,我會在進入 數量較多,使得循環 369 00:20:00,300 --> 00:20:02,540 將重複多次。 370 00:20:02,540 --> 00:20:06,090 在這種情況下,我要去 輸入值11。 371 00:20:06,090 --> 00:20:08,390 >> 現在,再次因為我設置 在第15行一個破發點, 372 00:20:08,390 --> 00:20:10,490 它會高亮顯示該行。 373 00:20:10,490 --> 00:20:12,980 我們可以看到,我們的 11號是正確的 374 00:20:12,980 --> 00:20:15,560 代表我們的局部變量。 375 00:20:15,560 --> 00:20:22,460 現在跨過這一點,我們可以 看著發生在我們的I值是什麼 376 00:20:22,460 --> 00:20:25,680 當我們著手這裡面的for循環。 377 00:20:25,680 --> 00:20:31,960 它被遞增每次我們 達到了頂部循環。 378 00:20:31,960 --> 00:20:35,110 >> 現在,可能的事情之一 是有用的執行過程中做 379 00:20:35,110 --> 00:20:40,490 這一計劃是對我來說,其實 改變變量中游看 380 00:20:40,490 --> 00:20:42,450 發生在我的計劃是什麼。 381 00:20:42,450 --> 00:20:46,540 在這種情況下,其實我可以 雙擊該值。 382 00:20:46,540 --> 00:20:48,040 請注意,它變成了文本字段。 383 00:20:48,040 --> 00:20:50,280 >> 現在我可以進入不同的 價值共 384 00:20:50,280 --> 00:20:55,700 怎麼看我的程序的行為 當我改變了這一切變化。 385 00:20:55,700 --> 00:20:59,560 現在,在這種情況下,可變 我現在包含值10。 386 00:20:59,560 --> 00:21:02,810 但該計劃仍是 在暫停執行。 387 00:21:02,810 --> 00:21:07,610 當我踏上了過來,我看到 我的價值,我輸入為10, 388 00:21:07,610 --> 00:21:12,170 不大於num的值越大, 這立即引起了循環 389 00:21:12,170 --> 00:21:14,240 停止執行。 390 00:21:14,240 --> 00:21:16,210 >> 現在,這不是唯一的 你之所以會 391 00:21:16,210 --> 00:21:19,450 要修改的變量的地方。 392 00:21:19,450 --> 00:21:22,210 你可能真的想 嘗試修改它, 393 00:21:22,210 --> 00:21:24,590 您可以繼續 執行一個循環 394 00:21:24,590 --> 00:21:27,370 或者,讓你可以修改 之前,一些價值 395 00:21:27,370 --> 00:21:32,630 達到某些特定的算術 你是要執行。 396 00:21:32,630 --> 00:21:36,210 >> 所以,現在,我們實際上改變 i的值作為程序執行, 397 00:21:36,210 --> 00:21:39,540 它造成的for循環退出 ,過早地因為突然之間,我 398 00:21:39,540 --> 00:21:42,770 正好是大於該值 NUM的,這意味著,對於循環 399 00:21:42,770 --> 00:21:45,410 不再需要被執行。 400 00:21:45,410 --> 00:21:48,780 此外,它正好是 情況下,我們改變了我的價值 401 00:21:48,780 --> 00:21:53,270 該行17強調的時候, 這是在時間點 402 00:21:53,270 --> 00:21:56,280 該循環執行 實際上正在評估。 403 00:21:56,280 --> 00:22:00,210 >> 如果我改變的價值 我在不同的線路,比如19, 404 00:22:00,210 --> 00:22:03,360 我們會看到不同的 問題是因為19行會 405 00:22:03,360 --> 00:22:08,310 循環之前已經執行 條件進行重新評估。 406 00:22:08,310 --> 00:22:11,900 現在,在這一點上,我再次, 在這個程序結束。 407 00:22:11,900 --> 00:22:15,707 我可以讓這種情況繼續 讓我的程序自然退出。 408 00:22:15,707 --> 00:22:18,290 但有幾件事情 這是很重要的帶走 409 00:22:18,290 --> 00:22:19,960 從這個特定的討論。 410 00:22:19,960 --> 00:22:22,490 您需要評估 你自己的假設 411 00:22:22,490 --> 00:22:24,710 有關如何代碼應表現。 412 00:22:24,710 --> 00:22:28,220 任何時候你覺得有些片 你知道發生了代碼工作, 413 00:22:28,220 --> 00:22:30,940 這可能是一個紅旗去 回顧和評估,並確保 414 00:22:30,940 --> 00:22:33,470 你的假設 如何代碼運行 415 00:22:33,470 --> 00:22:38,290 其實真到是怎麼回事 表現在你的源代碼。 416 00:22:38,290 --> 00:22:41,300 >> 但更要的一點是, 當我們使用調試器, 417 00:22:41,300 --> 00:22:43,920 你可以把斷點 不同的代碼行, 418 00:22:43,920 --> 00:22:48,110 這將導致調試器 暫停執行在每個那些行 419 00:22:48,110 --> 00:22:52,210 這樣就可以評估 內存甚至改變它在的地方。 420 00:22:52,210 --> 00:22:55,630 再次,請記住,你可以 創建多個斷點,這樣你 421 00:22:55,630 --> 00:23:00,390 也可以繼續執行,跳躍 以上代碼的大部分, 422 00:23:00,390 --> 00:23:04,790 它會自動暫停 在下一個破發點。 423 00:23:04,790 --> 00:23:07,760 >> 實際上有更先進 調試器的特性,以及。 424 00:23:07,760 --> 00:23:10,170 但是,我們必須向您推薦 一些後續的視頻 425 00:23:10,170 --> 00:23:14,090 要真正梳理出怎麼樣 使用這些特定的功能。 426 00:23:14,090 --> 00:23:15,990 現在,謝謝 非常適合觀看。 427 00:23:15,990 --> 00:23:18,080 祝你好運調試。