代碼驅動的程序設計學習

代碼驅動的程序設計學習

這學期的課程已經到了第三週了,很多同窗在博客中連代碼託管還沒弄好。出現的問題有:html

  • Ubuntu上git安裝配置出現問題;
  • 使用git基本的流程不對,連最基本的git add; git commit; git push流程都不會,還直接到git@OSC上經過代碼片段把電腦上的代碼又貼一遍,浪費時間;
  • 有的同窗輸了一週的代碼,最後一塊兒git commit 一下,而不是完成一段代碼就git add;git commit 一下;
  • 因爲上一條的問題,代碼的註釋都同樣,不能精細解釋代碼的功能;
  • ...

上學期的《Java程序設計》中git和git@OSC已經用了一學期了,如今的狀況說明很多同窗要麼上學期學的東西不紮實,學過的知識忘了,要麼上學期就沒學會。我感受沒學會的可能性很大,這麼簡單的東西不大會忘。雖然有「使用開源中國託管代碼」和盧肖明同窗的「Ubuntu下git的安裝與使用」 這些博客指導,好好看實踐相關內容的同窗仍是太少,仍是有必要結合課程寫個step by step 的教程,雖然下面的內容課堂上都演示過,很多同窗仍是沒有學會。git

更大的問題是完成學習任務時缺乏思考,累卻收穫不大,從而失去學習的激情web

學習時問題驅動是個很好的方式,「本學期第一週學習任務」要求根據「別出心裁的Linux命令學習法」的思想學習「Linux 基礎入門(新版)」,目前這門課有13節,很多人要麼沒學完,要麼反映學完了沒搞明白。這時候基於本身的實踐,經過問題驅動來找最經常使用的命令,你會發現3/4/5/6節是學習重點。編程的學習,代碼驅動是個很好的方式,咱們的教材《深刻理解計算機系統V2》是那麼厚的一本書,經過使用git和gdb來積極主動的讀寫代碼是一個很好的方式。積極主動的前提是本身有思考,不是僅僅完成老師的任務,那麼按照下面的方法學習,這學期收穫的不是一門功課的好成績,而是爲學習信息安全專業打下的堅實的計算機基礎:程序設計、操做系統、計算機組成原理、彙編語言、編譯原理、計算機網絡、軟件工程...shell

工具參考

下面的內容涉及到git和gdb的使用,這兒給出這兩個工具的cheatsheet,方便你們參考,固然打印一份夾在教材中隨用隨查更好。編程

  • git cheatsheet

git1

git2

  • gdb cheatsheet

gdb1

gdb2

git的安裝測試

Ubuntu中在bash中輸入git, 若是沒有安裝git,會有以下提示:小程序

no git

git的安裝很是簡單,根據上圖中的提示,咱們在bash中輸入sudo apt-get install git就能夠了,能夠輸入git --version來測試是否安裝成功。以下圖所示:vim

install git

不論是使用本身電腦上的虛擬機仍是使用實驗樓上的虛擬機,新建一個體現本身學號姓名的文件夾很重要,讓老師一眼能看出來這是誰作的。以下圖,輸入mkdir 20145300rocedu 新建一個20145300rocedu文件夾。經過輸入cd 20145300rocedu 進入20145300rocedu文件夾:安全

mdcddir

有的同窗沒有項目的概念,這學期的代碼和上學期的Java課程中的代碼混在一塊兒,很是很差。bash

咱們的教材《深刻理解計算機系統V2》的英文版名爲《Computer Systems :A Programmer's Perspective》,和那本C語言名著《C程序設計語言 (The C Programming Language)》有個專有的縮寫K&R同樣,《深刻理解計算機系統V2》的專用縮寫爲CSAPP,咱們使用的是第二版,因此加上學號信息,經過在bash中輸入mkdir 20145300CSAPP2E 創建教材的項目文件夾。根據C項目的規範,咱們在20145300CSAPP2E文件夾下創建相應的文件夾:微信

  • src:存放源代碼文件
  • include: 存放頭文件
  • bin:存放編譯後的目標文件、可執行文件等
  • lib:存放項目所需的靜態庫、動態(共享)庫
  • res: 存放項目所需的圖標、聲音、圖片等資源
  • docs: 存放項目相關的參考資料、幫助文檔,好比你們的學習博客就能夠放在這裏
  • ...
    此外還能夠創建dist文件夾存放打包,發佈之後的代碼;創建examples文件夾存放示例代碼等。

項目文件夾下能夠經過touch README Makefile新建README和Makefile兩個文件:

  • README 是對項目的簡要介紹:licence、功能、編譯環境等,詳細的要在docs下有幫助文檔
  • Makefile 實現項目編譯自動化
  • 其餘相關文件

咱們的教材有12章,在src文件夾下爲每章創建了一個文件夾。

建好的項目結構以下圖所示:

project structure

咱們的工做目錄通常選擇項目目錄下,其餘的使用相對路徑。好比咱們在src/01intro目錄下輸入教材第一章第一頁的hello world程序hello.c, 咱們使用vim src/01intro/hello.c命令:
vimhello

代碼以下圖所示:
hello.c

在Vim中經過:wq保存hello.c並退出Vim後,咱們使用gcc src/01intro/hello.c -o bin/hello來編譯程序,注意命令中相對路徑的使用。可執行程序hello生成在bin目錄下,咱們可使用./bin/hello來執行hello程序。此時目錄結構以下圖所示:

compilehello

咱們經過git config對git做一下簡單配置,user.name儘可能體現本身的學號信息。
gitconfig

git cheatsheet中有經常使用的配置項:
git

咱們經過git init 把項目歸入git管理。之後就是最經常使用的git add; git commit了,使用git commit時必定要注意解釋一下剛纔作了什麼。好比咱們在這用git commit -m "initiate csapp2e project with hello world program"說明‘咱們用hello world程序初始化了CSAPP2E這個項目’。

git init

以下圖,git cheatsheet中有經常使用的git 查看命令,git log會列出全部歷史記錄,最近的排在最上方,顯示提交對象的哈希值,做者、提交日期、和提交說明。若是記錄過多,則按Page Up、Page Down、↓、↑來控制顯示;按q退出歷史記錄列表。如上圖,咱們此時只有一條git commit記錄。

gitbrowse

咱們創建了項目目錄結構後,編譯命令中要用到相對路徑,命令就長且難以記憶了,好比上面咱們使用gcc src/01intro/hello.c -o bin/hello來編譯hello world程序。咱們能夠經過shell腳原本簡化編譯運行程序。注意咱們要用chmod +x compile.sh給腳本添加可執行權限,咱們就能夠用./compile.sh來執行腳本了。以下圖所示:

compilescript

腳本中是編譯、運行程序的命令,shell腳本中第一行是固定寫法, #後面是註釋:
helloscipt

咱們想體會教材上gcc編譯程序的四個階段:預處理、編譯、彙編、連接。
foursteps

能夠在腳本中增長相關命令:
fourstepsscript

你們要注意,源代碼產生的中間文件是不須要歸入git的管理的,也就是說咱們上面創建的項目目錄結構中的bin是不須要git管理的,不然項目所佔空間可能會很大,往代碼託管網站使用git push推送時,會浪費很多流量,也浪費代碼託管網站的存儲空間。咱們可使用.gitignore文件把不想歸入git管理的文件、文件夾排除掉。
vimgitignore

ignorebin

咱們完成一個小任務,就git add; git commit 一下,注意在註釋中說明剛纔作了什麼:

commit ignore

你們注意不要到週末了寫了幾百行代碼了才git add; git commit 一下,這樣致使全部代碼的註釋都同樣了,不少同窗的註釋都是「Week2」、"Week3"、「第三週代碼」。

積極主動敲代碼

有的同窗說實踐了沒有收穫,主要問題是思考不夠,更多的是動手不夠,致使基本知識都不明白。好比看到教材p21 關於溢出的講解:

overflow

若是你基礎好,一會兒就明白了,就能夠繼續後面的學習了。
若是你沒有見過這種狀況,或者對書上四個式子都會獲得-88490188的結論有懷疑的話,就能夠把代碼敲一下,C程序咱們命名爲testoverflow.c

代碼以下圖所示,像要補充個main函數這件事居然很多人不知道:

p21

在compile.sh中添加相應的編譯、運行命令:

compilep21

而後編譯運行程序,結果驗證了教材上講的沒有問題。

runp21

完成了這個小程序,咱們能夠git add; git commit 一下,這樣如git log的結果所示,git就記錄了你的學習軌跡:

gitcommitp21

一週怎麼也要git add; git commit十幾回、幾十次,若是上學期這麼作了,我不大相信會忘記這兩條命令。

須要不須要寫代碼要根據本身的狀況決定,這樣的學習過程每一個人是不同的,遇到的問題也是不同的,有了不同的過程,不一樣的問題老師才能夠因材施教,大部分人都有人問題就是老師的教學重點。

使用gdb輔助學習

gdb是個調試工具,也是一個很好的學習工具,像「積極主動敲代碼,使用JUnit學習Java」中的JUnit同樣,雖然是單元測試工具,均可以用來做爲咱們積極思考、主動學習的工具。

gdb有兩個替代工具cgdb,ddd,在Ubuntu中可使用sudo apt-get install cgdb, sudo apt-get install ddd來安裝。

咱們以教材上第44頁有符號數和無符號數的轉換爲例。咱們爲代碼命令爲testcast.c
vimp44

咱們補充main函數,輸入相關代碼:
p44code

在compile.sh中添加編譯運行命令,注意爲了使用gdb調試,咱們用了gcc的-g 選項:

p44script

運行結果和教材中的同樣:
p44result

完成一段代碼,測試沒有問題了,咱們就git add;git commit 一下,注意在註釋中解釋一下作了什麼。

若是到這,你可能還不能理解教材中說的「在相同長度的無符號和有符號整數之間進行強制類型轉換時,大多數C語言實現遵循的原則是底層的位模式不變」。什麼是「數值能夠改變,位模式不變」?書上給出了一系列公式,相信有人是看不懂的。

咱們可使用gdb加深理解。

gdb cheatsheet中對print命令(print命令能夠縮寫爲p)有細解,咱們能夠用/t選項查看變量的二進制形式,也就是教材中說的「位模式」:

printt

咱們用cgdb 對testcast進行調試:

cgdbtestcast

咱們經過b p44_t2ub p44_u2t設置兩個函數斷點,使用r運行testcast,程序在第22行中止,咱們運行兩個n(next)命令讓程序停在第24行,這時咱們使用 p /t vp /t uv 查看v和uv的位模式,你會發現都是1100 1111 1100 0111,也就是說有符號整數v被強制轉換成無符號整數uv,從位模式上看都 是1100 1111 1100 0111,不一樣的是對於v,1100 1111 1100 0111最高位1解釋成符號位,表示負數,v的值是-12345,對於uv,1100 1111 1100 0111最高位1就表示2的15次方了,也就是32768,這就是「數值能夠改變,位模式不變」。

t2u

繼續往下調試:

u2t

你能夠看到有符號整數轉換成無符號整數也是同樣:數值變了,位模式沒變。

若是這時候你能想到第一章的一個公式「信息=位+上下文」就更好了。一樣的位模式1100 1111 1100 0111,不一樣的上下文中能夠表示-12345,也可表示53191;一樣的位模式1111 1111 1111 1111,不一樣的上下文中能夠表示4294967295,也能夠表示-1

用這種方式積極主動的學習,我不大相信冰雪聰明的大家會學不明白。固然,這須要極大的時間投入的,像張雪純同窗在「第三週學習總結」中說的那樣:
『原來較爲輕視課本的學習,總想走捷徑,此次一頁頁讀過課本之後發現本身對這些基礎知識有了更深入的瞭解。其實閱讀課本也是很重要的。有時候看上去很笨的方法多是最有效的。』

周筠老師(知乎,微博,豆瓣)評論總結:「課本的內容是通過做者反覆斟酌,去粗取精並作了系統思考而寫成的,因此閱讀課本反而是真正的捷徑。有這樣的認識,是上課的大收穫啊,祝賀!請繼續加油!」,我深表贊成!

思考題

這兩個題目認真作的視狀況會有1-5分的加分:

  • 參考盧肖明同窗的「Ubuntu下git的安裝與使用」,把本身的學習內容新建一個項目,按這篇博客的方式從新整理一下,經過git remote add, git push 推送到git@OSC相似的代碼託管網站。
  • 使用compile.sh有什麼問題?如何使用Makefile改進?要求添加C代碼Makefile不需改動。第一個完成者加5分。

參考資烤料


歡迎關注「rocedu」微信公衆號(手機上長按二維碼)

作中教,作中學,實踐中共同進步!

rocedu



若是你以爲本文對你有幫助,請點一下左下角的「好文要頂」和「收藏該文

相關文章
相關標籤/搜索