今天碰到了這個警告,老老實實的google了一下,以下是收獲:
問題是這樣產生的,先看這個函數原型:
void someFunc(char *someStr);
再看這個函數調用:
someFunc("I'm a string!");
把這兩個東西組合起來,用最新的g++編譯一下就會得到標題中的警告。
為什么呢?原來char *背后的含義是:給我個字符串,我要修改它。
而理論上,我們傳給函數的字面常量是沒法被修改的。
所以說,比較和理的辦法是把參數類型修改為const char *。
這個類型說背后的含義是:給我個字符串,我只要讀取它。
很自然的延伸一下。 如果我既要傳字面常量又要傳字符串變量怎么辦呢?......重載
這些文字之前,我也是認為二進制文件就像空氣一樣,平常得讓人完全忽略了。
很偶然的,今天在寫代碼的時候使用了fopen函數:
FILE * fopen (const char * filename, const char * mode)
大家可以看到第二個參數是mode,而這個參數定義了文件打開的方式,w、a等都可以做為函數的實參。除此之外,還有兩個值:t和
b。這兩個值定義了文件是按照文本(text)還是二進制(binary)方式開發。正是這個兩個值引起了我對二進制文件的興趣,因為它們
讓我想到了很多問題。
首先,出現在腦海的第一個問題是:文本文件和二進制文件有什么區別呢?我想這個問題并不是每個程序員能夠馬上回答
上來的,至少我是不行了。查閱了資料之后,發現答案就在自己的知識范圍之內的:將文件看作是由一個一個字節(byte) 組成的,
那么文本文件中的每個字節的最高位都是0,也就是說文本文件使用了一個字節中的七位來表示所有的信息,而二進制文件則是將字
節中的所有位都用上了。這就是兩者的區別;
接著,第二個問題就是文件按照文本方式或者二進制方式打開,兩者會有什么不同呢?其實不管是二進制文件也好,還是
文本文件也好,都是一連串的0和1,但是打開方式不同,對于這些0和1的處理也就不同。如果按照文本方式打開,在打開的時候會
進行translate,將每個字節轉換成ASCII碼,而以按照二進制方式打開的話,則不會進行任何的translate;
最后就是文本文件和二進制文件在編輯的時候,使用的方式也是不同的。譬如,你在記事本中進行文本編輯的時候,你進
行編輯的最小單位是字節(byte);而對二進制文件進行編輯的話,最小單位則是位(bit),當然我們都不會直接通過手工的方式對二
進制文件進行編輯了。
----------------2---------------
二進制文件和文本文件都是0,1組成,但文件系統對他們的解釋不一樣,一般系統調用(或WIN32API)都會分為字符
式和二進制式(或流式).文本或字符文件代表慢速設備,而二進制文件代表可以大塊數據操作的快速外設,二進制文件內容基本無意義
,系統對它不加解釋地傳給調用者,解釋由調用者負責.而對字符文件,系統把他理解為單字節的ASCII或多字節的UNICODE字符串,并且
對其中的特殊字符(如回車等)加以特殊處理.所以同一個文件,可以使用不同類型的系統調用.
文本文件也叫做ASCII碼文件,與以‘文本方式’打開文件不是同一個概念!文本文件存儲的是ASSCII碼字符,即存儲在磁盤上只占用二進制的0x20--0x7e。另外,還有回車(0x0d),換行(0x0a),TAB(0x09)等,所以有可壓縮的空間。
換行和回車是不同的,而且在不同的操作系統,解釋也不相同。‘\n’一般會操作系統被翻譯成"行的結束",即LF(Line-Feed);‘\r’會被翻譯成"回車",即CR(Cariage-Return)
回車(CR)和換行(LF)符都是用來表示“下一行”的。而標準沒有規定要使用哪一個。于是產生了三種不同的用法:
(1) Dos和windows采用回車+換行(CR+LG)表示下一行
(2) UNIX采用換行符(LF)表示下一行
(3) MAC機采用回車符(CR)表示下一行。
當在不同的系統間傳遞文件,就要涉及格式的轉換。
文本方式和二進制方式的最大區別在于文本方式對于'\n'換行符的理解不同
(1)在DOS平臺下,該字符會被展開成<CR>< LF>兩個控制字符(相當于"\r\n"),在ASCII字符集下是 0DH,0AH
(2)在UNIX平臺下,僅僅是<LF>,不會展開。
(3)在二進制方式下,不管是什么平臺,'\n'都是精確的<LF>。
在linux/unix 系統上,只有一種文件類型的系統,帶b字母的模式和對應的不帶b字母的模式是相同的。(UNIX文本文件通常不包含Ctrl+Z和\r)
關于EOF:
EOF可以作為文本文件的結束標志,但不能作為二進制文件的結束符.feof函數既可以判斷二進制文件,又可以判斷文本文件.
EOF在Windows下是ctrl+z,linux下是ctrl+D.
原地址:http://www.shnenglu.com/jb8164/archive/2009/01/09/71583.html
Ubuntu 方便宜用,最值得讓人稱道的便是其安裝軟件的方式, 一條命令: sudo apt-get install xxx 就幾乎能幫你搞定所有的軟件安裝難題。但是有時你可能有這樣的需求,查看某個軟件包是否安裝、安裝在哪..., 那我們就來介紹一下 Ubuntu 的軟件包管理方式。
一、Ubuntu 采用 Debian 的軟件包管理器 dpkg 來管理軟件包, 類似 RPM. 系統中所有 packages 的信息都在 /var/lib/dpkg/
目錄下, 其子目錄 /var/lib/dpkg/info 用于保存各個軟件包的配置文件列表:
(1).conffiles 記錄了軟件包的配置文件列表
(2).list 保存軟件包中的文件列表, 用戶可以從 .list 的信息中找到軟件包中文件的具體安裝位置.
(3).md5sums 記錄了軟件包的md5信息, 這個信息是用來進行包驗證的.
(4).prerm 腳本在 Debian 包解包之前運行, 主要作用是停止作用于即將升級的軟件包的服務, 直到軟件包安裝或升級完成.
(5).postinst 腳本是完成 Debian 包解開之后的配置工作, 通常用于執行所安裝軟件包相關命令和服務重新啟動.
/var/lib/dpkg/available 文件的內容是軟件包的描述信息, 該軟件包括當前系統所使用的 Debian 安裝源中的所有軟件包,
其中包括當前系統中已安裝的和未安裝的軟件包.
/var/cache/apt/archives 目錄是在用 apt-get install 安裝軟件時,軟件包的臨時存放路徑
/etc/apt/sources.list 存放的是軟件源站點, 當你執行 sudo apt-get install xxx 時,Ubuntu 就去這些站點下載軟件包到本地并執行安裝
二、相關命令使用示例:
(1)查看某軟件包的安裝內容
dpkg -L xxx
(2)查找軟件庫中的軟件包
apt-cache search 正則表達式
(3)顯示系統安裝包的統計信息
apt-cache stats
(4)顯示系統全部可用軟件包的名稱
apt-cache pkgnames
(5)顯示某軟件包的詳細信息
apt-cache show xxx
(6)查找某文件屬于哪個包
apt-file search xxx
(7)查看已經安裝了哪些軟件包
dpkg -l
(8)查詢某軟件依賴哪些軟件包
apt-cache depends xxx
(9)查詢某軟件被哪些軟件包依賴
apt-cache rdepends xxx
(10)增加一個光盤源
sudo apt-cdrom add
注: 顧名思義, 就是安裝更新軟件包時讓其優先從Ubuntu 光盤上找(如果你不能上網安裝/更新, 但有 Ubuntu 的 DVD ISO, 這會對你非常有用)
(11)系統升級
sudo apt-get update
(12)清除所有已刪除軟件包的殘馀配置文件
dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P
(13)編譯時缺少h文件的自動處理
sudo auto-apt run ./configure
(14)查看安裝軟件時下載軟件包的臨時存放目錄
ls /var/cache/apt/archives
(15)備份當前系統安裝的所有軟件包的列表
dpkg --get-selections | grep -v deinstall > ~/somefile
(16)從上面備份的安裝包的列表文件恢復所有包
dpkg --set-selections < ~/somefile
sudo dselect
(17)清理舊版本的軟件緩存
sudo apt-get autoclean
(18)清理所有軟件緩存
sudo apt-get clean
(19)刪除系統不再使用的孤立軟件
sudo apt-get autoremove
(20)查看軟件包在服務器上面的地址
apt-get -qq --print-uris install ssh | cut -d\' -f2
Linux網絡協議棧跟Windows系統中的網絡協議有什么不一樣呢?這個還需要我們來看看具體的內容。下面就來簡單看看它的概念,結構以及相應的一些解說吧。望對大家有所幫助。
Linux網絡協議棧
Linux的協議棧其實是源于BSD的協議棧,它向上以及向下的接口以及協議棧本身的軟件分層組織的非常好。
Linux的協議?;诜謱拥脑O計思想,總共分為四層,從下往上依次是 :物理層,鏈路層,網絡層,應用層。
物理層主要提供各種連接的物理設備,如各種網卡,串口卡等;鏈路層主要指的是提供對物理層進行訪問的各種接口卡的驅動程序,如網卡驅動等;網路層的作用是負責將網絡數據包傳輸到正確的位置,最重要的網絡層協議當然就是IP協議了,其實網絡層還有其他的協議如ICMP,ARP,RARP等,只不過不像IP那樣被多數人所熟悉;傳輸層的作用主要是提供端到端,說白一點就是提供應用程序之間的通信,傳輸層最著名的協議非TCP與UDP協議末屬了;應用層,顧名思義,當然就是由應用程序提供的,用來對傳輸數據進行語義解釋的“人機界面”層了,比如HTTP,SMTP,FTP等等,其實應用層還不是人們最終所看到的那一層,最上面的一層應該是“解釋層”,負責將數據以各種不同的表項形式最終呈獻到人們眼前。
Linux網絡核心架構
Linux的網絡架構從上往下可以分為三層,分別是 :
用戶空間的應用層。
內核空間的網絡協議棧層。
物理硬件層。
其中最重要最核心的當然是內核空間的協議棧層了。
Linux網絡協議棧結構
Linux的整個網絡協議棧都構建與Linux Kernel中,整個棧也是嚴格按照分層的思想來設計的,整個棧共分為五層,分別是 :
1. 系統調用接口層,實質是一個面向用戶空間應用程序的接口調用庫,向用戶空間應用程序提供使用網絡服務的接口。
2. 協議無關的接口層,就是SOCKET層,這一層的目的是屏蔽底層的不同協議(更準確的來說主要是TCP與UDP,當然還包括RAW IP, SCTP等),以便與系統調用層之間的接口可以簡單,統一。簡單的說,不管我們應用層使用什么協議,都要通過系統調用接口來建立一個SOCKET,這個SOCKET其實是一個巨大的sock結構,它和下面一層的網絡協議層聯系起來,屏蔽了不同的網絡協議的不同,只吧數據部分呈獻給應用層(通過系統調用接口來呈獻)。
3. 網絡協議實現層,毫無疑問,這是整個協議棧的核心。這一層主要實現各種網絡協議,最主要的當然是IP,ICMP,ARP,RARP,TCP,UDP等。這一層包含了很多設計的技巧與算法,相當的不錯。
4. 與具體設備無關的驅動接口層,這一層的目的主要是為了統一不同的接口卡的驅動程序與網絡協議層的接口,它將各種不同的驅動程序的功能統一抽象為幾個特殊的動作,如open,close,init等,這一層可以屏蔽底層不同的驅動程序。
5. 驅動程序層,這一層的目的就很簡單了,就是建立與硬件的接口層。
可以看到,Linux網絡協議棧是一個嚴格分層的結構,其中的每一層都執行相對獨立的功能,結構非常清晰。
其中的兩個“無關”層的設計非常棒,通過這兩個“無關”層,其協議棧可以非常輕松的進行擴展。在我們自己的軟件設計中,可以吸收這種設計方法。