網頁

2009年12月20日 星期日

Cloud computing - Networking

VL2 approach

----------------------------------

Virtual Layer 2 Implemented with Layer 3 and Layer 4. (Scalability)

In order to solve congestion but destroy network layer 2 structure. 


Conventional : Hard to scale and too many limitation.

MapReduce -> Google seems to have a better experience on data locality.

2009年12月3日 星期四

C++ 物件導向精神

最近面試常常被問到的問題是物件導向的三大特性

封裝 (Encapsulation)
將資料 (屬性) 與操作此資料的函數 (方法) 包在一起的特性

繼承 (Inheritance)
承接所有父類別 (Parent Class) 所有屬性方法,並可以加以改造的特性

多型 (Polymorphism)
呼叫相同的函式,卻會出現不同的行為的現象
●(Overloading): 將一個函數名稱,賦予一種以上的函數實體,以便依據當時情況,擇一執行。
●(Overriding): 將繼承下來的方法,以同名函數蓋掉的特色

2009年12月1日 星期二

[轉錄]UC/OS和uClinux的比較


     http://os.51cto.com/col/872/ 隨著現代計算機技術的飛速發展和互聯網技術的廣泛應用,從PC時代過渡到了以個人數字助理、手持個人電腦和信息家電為代表的3C(計算機、通信、消費電子)一體的後PC時代。後PC時代裡,嵌入式系統扮演了越來越重要的角色,被廣泛應用於信息電器、移動設備、網絡設備和工控仿真等領域。
    嵌入式系統是以嵌入式計算機為核心,面向用戶、面向產品、面向應用,軟硬件可裁減的,適用於對功能、可靠性、體積、成本、功耗等綜合性能有嚴格要求的計算機系統。隨著嵌入式系統的廣泛應用,傳統的前/後台程序開發機制已經不能滿足日益復雜和荷記得的實現要求,因而現場常常采用嵌入式產時操作系統PROS(Real Time Operation System)開發實時多任務系統。嵌入式實時操作系統一般可以提供多任務的任務調度、時間管理、任務間通信和同步以及內存管理MMU(Memory Manager Unit)等重要服務,使得嵌入式應用程序易於設計和擴展。采用RTOS可以使嵌入式產品更可靠、開發周期更短。在嵌入式應用中使用RTOS已經成為當前嵌入式應用的一個熱點。
    完成簡單功能的嵌入式系統一般不需要操作系統。如,以前許多MCS51系列單片機組成的小系統就只是利用軟件實現簡單的控制環路;但是隨著所謂後PC時代的來臨,嵌入式系統設計日趨復雜,嵌入式操作系統就必不可少了。
    嵌入式RTOS在系統實時高效性、硬件的相關依賴性、軟件固化以及應用的專業性等方面具有較為突出的優勢。一般而言,嵌入式操作系統不同於一般意義的計算機操作系統,它有佔用空間小、執行效率高、方便進行個性化定制和軟件要求固化存儲等特點。
    從20世紀80年代起,國際上就有一些IT組織、公司,開始進行商用嵌入式操作系統和專用操作系統的研發。這其中湧現了一些著名的嵌入式操作系統,如Microsoft公司的WinCE和WindRiver System公司的VxWorks就分別是非實時和實時嵌入式操作系統的代表。但是商用產品的造價都十分昂貴,用於一般用途會提高產品成本從而失去競爭力。
    UC/OS和uClinux操作系統是用兩種性能優良、源碼公開且被廣泛應用的免費嵌入式操作系統,可以作為研究實時操作系統和非實時操作系統的典范。本文通過uC/OS和uClinux的對比,分析和總結嵌入式操作系統應用中的若干重要問題,歸納嵌入式系統開發中操作系統的選型依據。
    1 兩種開源嵌入式操作系統介紹
    uC/OS和uClinux操作系統,是當前得到廣泛應用的兩種免費且公開源碼的嵌入式操作系統。UC/OS適合小型控制系統,具有執行效率高、佔用空間小、實時性能優良和可擴展性強等特點,最小內核可編譯至2KB。UClinux則是繼承標准Linux的優良特性,針對嵌入式處理器的特點設計的一種操作系統,具有內嵌網絡協議、支持多種文件系統,開發者可利用標准Linux先驗知識等優勢。其編譯後目標文件可控制在幾百KB量級。
    UC/OS是一種免費公開源代碼、結構小巧、具有可剝奪實時內核的實時操作系統。其內核提供任務調度與管理、時間管理、任務間同步與通信、內存管理和中斷服務等功能。
    UClinux是一種優秀的嵌入式Linux版本。uClinux是Micro-Conrol-Linux的縮寫。同標准Linux相比,它集成了標准Linux操作系統的穩定性、強大網絡功能和出色的文件系統等主要優點。但是由於沒有MMU(內存管理單元),其多任務的實現需要一定技巧。
    2 兩種嵌入式操作系統主要性能比較
    嵌入式操作系統是嵌入式系統軟硬件資源的控制中心,它以盡量合理的有效方法組織多個用戶共享嵌入式系統的各種資源。其中用戶指的是系統程序之上的所有軟件。所謂合理有效的方法,指的就是操作系統如何協調並充分利用硬件資源來實現多任務。復雜的操作系統都支持文件系統,方便組織文件並易於對其規范化操作。
    嵌入式操作系統還有一個特點是,針對不同的平台,系統不是直接可用的,一般需要經過針對專門平台的移植操作系統才能正常工作。
    進程調度、文件系統支持和系統移植是在嵌入式操作系統實際應用中最常見的問題。下文就從這幾個角度入手對uC/OS和uClinux進行分析比較。
    2.1 進程調度
    任務調度主要是協調任務對計算機系統資源(如內存、I/O設備、CPU)的爭奪使用。進程調度又稱為CPU調度,其根本任務是按照某種原理為處於就緒狀態的進程分析CPU。由於嵌入式系統中內存和I/O設備一般都和CPU同時歸屬於某進程,所以任務調度和進程調度概念相近,很多場合不加區分。
    進程調度可分為「剝奪型調度」和「非剝奪型調度」兩種基本方式。所謂「非剝奪型調度」是指:一旦某個進程被調度執行,則該進程一直執行下去直至該進程結束,或由於某種原理自行放棄CPU進入等待狀態,才將CPU重新分配給其它進程。所謂「剝奪型調度」是指:一旦就緒狀態中出現優先權更高的進程,或者運行的進程已用滿了規定的時間片時,便立即剝奪當前進程的運行(將其放回就緒狀態),把CPU分配給其它進程。
    作為實時操作系統,uC/OS采用的是可剝奪型實時多任務內核。可剝奪型的實時內核在任何時候都運行就緒了的最高優先級的任務。uC/OS中最多可以支持64個任務,分別對應優先級0~63,其中0為最高優先級。調度工作的內容可以分為兩部分:最高優先級任務的尋找和任務切換。
    其最高優先級任務表來實現的。UC/OS中的每一個任務都有獨立的堆棧空間,並有一個稱為任務控制塊TCB(Task Control Block)的數據結構,其中第一個成員變量就是保存的任務堆棧指針。任務調度模塊首先用變量OSTCBHighRdy記錄當前最高級就緒任務的TCB地址,然後調用OS_TASK_SW()函數來進行任務切換。
    UClinux的進程調度沿用了Linux的傳統。系統每隔一定時間掛起進程,同時產生快速和周期性的時鐘性時中斷,並通過調度函數(定時器處理函數)決定進程什麼時候擁有它的時間片,然後進行相關進程切換。這是通過父進程調用fork函數生成子進程來實現的。
    UClinux系統fork調用完成後,要麼子進程代替父進程執行(此時父進程已經休眠),直到子進程調用exit退出;要麼調用exec執行一個新的進程,這時產生可執行文件的加載,即使這個進程只是父進程的拷貝,這個過程也不可避免。當子進程執行exit或exec後,子進程使用wakeup把父進程喚醒,使父進程繼續往下執行。
    uClinux由於沒有MMU管理存儲器,其對內存的訪問是直接的,所有程序中訪問的地址都是實際的物理地址。操作系統對內存空間沒有保護,各個進程實際上共享一個運行空間。這就需要實現多進程時進行數據保護,也導致了用戶程序使用的空間可能佔用到系統內核空間。這些問題在編程時都需要多加注意,否則容易導致系統崩潰。
    由上述分析可以得知,uC/OS內核是針對實時系統的要求設計實現的,相對簡單,可以滿足較高的實時性要求;而uClinux則在結構上繼承了標准Linux的多任務實現方式,僅針對嵌入式處理器特點進行改良。其要實現實時性效果則需要使系統在實時內核的控制下運行。RT-Linux就是可以實現這一功能的一種實時內核。
    2.2 文件系統
    所謂文件系統是反映負責存取和管理文件信息的機構,也可以說是負責文件的建立、撤銷、組織、讀寫、修改、復制及對文件管理所需要的資源(如目錄表、存儲介質等)實施管理的軟件部分。
    uC/OS是面向中小型嵌入式系統的。如果包含全部功能(信號量、消息郵箱、消息隊列及相關函數),編譯後的uC/OS內核僅有6~10KB,所以系統本身並沒有對文件系統的支持。但是uC/OS具有良好的擴展性能,如果需要的話也可自行加入文件系統的內容。
    uClinux則是繼承了Linux完善的文件系統性能。其采用的是romfs文件系統。這種文件系統相對於一般的ext2文件系統要求更少的空間。空間的節約來自於兩個方面:首先,內核支持romfs文件系統比支持ext2文件系統需要更少的代碼;其次,romfs文件系統相對簡單,在建立文件系統超級塊(superblock)需要更少的存儲空間。Romfs文件系統不支持動態擦寫保存,對於系統需要動態保存的數據采用虛擬ram盤的方法進行處理(ram盤將采用ext2文件系統)。
    uClinux還繼承了Linux網絡操作系統的優勢,可以很方便地支持網絡文件系統且內嵌TCP/IP協議。這為uClinux開發網絡接入設備提供了便利。
    由兩種操作系統對文件系統的支持可知:在復雜的需要較多文件處理的嵌入式系統中,uClinux是一個不錯的選擇;而uC/OS則主要適合一些控制系統。
    2.3 操作系統的移植
    嵌入式操作系統移植的目的是指使操作系統能在某個微處理器或微控制器上運行。UC/OS和uClinux都是源碼公開的操作系統,且其結構化設計便於把與處理器相關的部分分離出來,所以被移植到新的處理器上是可能的。以下對兩種系統的移植分別予以說明。
    (1)uC/OS的移植
    要移植uC/OS,目標處理器必須滿足以下要求:
    *處理器的C編譯器能產生可重入代碼,且用C語言就可以打開和關閉中斷;
    *處理器支持中斷,並能產生定時中斷;
    *處理器支持足夠的RAM(幾KB),作為多任務環境下的任務堆棧;
    *處理器有將堆棧指針和其它CPU寄存器讀出和存儲到堆棧或內存中的指令。
    在理解了處理器和C編譯器的技術細節後,uC/OS的移植只需要修改與處理器相關的代碼就可以了。具體有如下內容:
    *OS_CPU.H中需要設置一個常量來標識堆棧增長方向;
    *OS_CPU.H中需要聲明幾個用於開關中斷和任務切換的宏;
    *OS_CPU.H中需要針對具體處理器的字長重新定義一系列數據類型;
    *OS_CPU_A.ASM需要改寫4個匯編語言的函數;
    *OS_CPU_C.C需要用C語言編寫6個簡單函數;
    *修改主頭文件INCLUDE.H,將上面的三個文件和其它的頭文件加入。
    (2)uClinux的移植
    其實,uClinux是Linux針對嵌入式系統的一種改良,其結構比較復雜;相對uC/OS,uClinux的移植也復雜得多。一般而言,要移植uClinux,目標處理器除了應滿足上述uC/OS應滿足的條件外,還需要具有足夠容量(幾百KB以上)外部ROM和RAM。
    uClinux的移植大致可以分為3個層次。
    *結構層次的移植。如果待移植處理器的結構不同於任何已經支持的處理器結構,則需要修改linux/arch目錄下相關處理器結構的文件。雖然uClinux內核代碼的大部分是獨立於處理器和其體系結構的,但是其最低級的代碼也是特定於各個系統的。這主要表現在它們的中斷處理上下文、內核映射的維護、任務上下文和初始化過程都是獨特的。這些例行程序位於lunux/arch/目錄下。由於Linux所支持體系結構的種類繁多,所以對一個新型的體系,其低級例程可以模仿與其相似的體系例程編寫。
    *平台層次的移植。如果待移植處理器是某種uClinux已支持體系的處理器,則需要在相關體系結構目錄下建立相應目錄並編寫相應代碼。如MC68EZ328就是基於無MMU的m68k內核的。此時的移植需要創建的linux/arch/m68knommu/platform/MC68EZ328目錄下,並在其下編寫跟蹤程序(實現用戶程序到內核函數的接口等功能)、中斷控制調度程序和向量初始化程序等。
    *極級移植。如果所用處理器已被uClinux支持,就只需要板級移植了。板級移植需要在linux/arch/?platform/中建立一個相應板的目錄,再在其中建立相應的啟動代碼crt0_rom.s或crt0_ram.s和鍵接描述文檔rom.ld或ram.ld就可以了。板級移植還包括驅動程序的編寫和環境變量設置等內容。
    結語
    通過對uC/OS和uClinux的比較可以看出,這兩種操作系統在應用方面各有優劣。uC/OS佔用空間少、執行效率高、實時性能優良,且針對新處理器的移植相對簡單。UClinux則佔用空間相對較大,實時性能一般,針對新處理器的移植相對復雜。但是,uClinux具有對多種文件系統的支持能力、內嵌了TCP/IP協議,可以借鑑Linux豐富的資源,對一些復雜的應用,uClinux具有相當優勢。例如,CISCO公司的2500/3000/4000路由器就是基於uClinux操作系統開發的。總之,操作系統的選擇是由嵌入式系統的需求決定的。簡單地說就是,小型控制系統可充分利用uC/OS小巧且實時性強的優勢;如果開發PDA和互聯網連接終端等較和為復雜的系統,則uClinux是不錯的選擇。

2009年11月28日 星期六

Cloud computing

Data warehouse
Energy consumption
Electricity output 2X 2002~2007




Ware-house data center
efficiency / centralize / scaling 


K-means clustering
Method:
隨機放用k個centroids,每個centroid向最接近它的所有item的平均位置移動,移動後再重新計算,直到所有的centroid都沒在移動後就結束
遊戲畫面




WSC (warehouse-scale computer)
Aggregation(規模經濟) - cost down


- Platform level software: Kernel
- Cluster-level infrastructure: Distribution File Systems, RPC layers.
- Application-level software: online service and offline computations(Google earth).


Datacenter vs Desktop
- Ample parallelism
data-request
- Workload churn
deploy more quickly
rapid product innovation
costumer focus
short software development cycle
- Platform homogeneity (same power supply, package)
- Fault-free operation


* Datacenter vs Desktop
decrease system complexity


Load-balancing -> cost down power
active -> DVFS
transparency -> load balancing




Application-level Software
reorganization: data-center > algorithm


Server power vs. utilization
power(f, u) = f + u(1-f)


saving time



switch on event
idle -> switch to another thread
CPU (DVFS) -> not easy to power consumption
DRAM -> important issue


Performance weight > Watt weight
Performance / Watt

2009年10月25日 星期日

ASM-C++

#include
using namespace std;

int main(){
int sum;
__asm(
"movl $1,%eax\n\t" // SYS_exit
"xor %ebx,%ebx\n\t"
"int $0x80"
);

return 0;
}

2009年9月25日 星期五

Mail Server

Mail Server

law@gmail.com
law為使用者名稱
gmail.com為主機名稱

Mail server componet
1. MUA ─ Mail User Agent 使用者用以寫信收信的程式。
2. MTA ─ Mail Transfer Agent 負責轉送信的伺服器。(功能是Relay)
3. MDA ─ Msil Delivery Agent 負責將要給本地使用者的郵件分配到使用者信箱中。(Mail)



POP3「Post Office Protocol - Version 3」
支持使用客戶端遠程管理在伺服器上的電子郵件。支援「離線」郵件處理。

Method: 郵件發送到伺服器上,MUA連接伺服器,並下載所有未閱讀的電子郵件。這種離線訪問模式是一種存儲轉發服務,將郵件從server送到terminal上,一旦郵件download,郵件伺服器上的郵件將會被刪除。

Internet Message Access Protocol (IMAP)
類似POP3 但有以下其他功能:
* 支援連線和離現兩種操作模式。
* 支援多個USER同時連線到一個郵箱。
* 支援在伺服器保留訊息狀態資訊。
* 支援在伺服器上存取多個郵箱。

推薦網誌

http://blog.leader.edu.tw/plog/index2.php?blogId=15

2009年9月10日 星期四

Ant Algorithms

演算法原理:
螞蟻可以由蟻穴到食物目的地找到一條最短路線, 它們用的不是視覺, 而是在走過的地方會殘留一種分泌物pheromone, 當以後的螞蟻經過時, 就有較高的機率選擇pheromone濃度高的方向, 因此隨著時間增長, 漸漸螞蟻會走同一路線(亦即最短路線)由蟻穴到食物目的地來回, 利用這種自然界的原理已有效率地解一些最佳化問題(Optimization Problems)


2009年9月7日 星期一

[轉錄]批次檔

甚麼是批次檔:
  在DOS系統下,有三類檔案是可以使DOS執行而進行某些工
作,這三類檔案分別有以下三個不同的副檔名
1. .com (指令檔,命令檔) 例如 Command.com, Edit.com 等。
2. .exe (執行檔) 例如 Copy.exe, Mem.exe 等。
3. .bat (批次檔) 例如 Autoexec.bat 等。
   其中 .com 及 .exe 的檔案是用編譯或組合語言寫出,需要較多工夫來學習編寫,一般終端用者 (end-user) 不會花時間來學習編寫這些程式,但 .bat 的批次檔是一連串的 DOS 內部或外部指令 (批次檔的意思是 指令集) ,或是執行程式的主檔名,因此只要懂得這些指令,加上一些簡單的語法,就可寫出批次檔。終端用者利用自己編寫的批次檔,就可使 DOS 執行自己編定的程序。
  批次檔是由 DOS 指令組成,因此批次檔有錯誤時,就等於我們在提示號 (C)鍵入錯的指令一樣,螢幕會有 Bad command or file name 的回應。
  批次檔必定要是純文字檔案,可使用 DOS 的編輯器(DOS Editor)
 
或用windows內的 記事本 寫出來,這兩個都是簡單的文書處理器,文稿內不含任何控制碼 (如字款和字的大小,文章闊度等等),這就最適合用來編來批次檔。


批次檔的規格:
1. 批次檔要以純文字寫出,每一項指令要在一行中完成,不能分兩行,每行最多是 127 個字。每一行只能容納一個指令,兩個指令就要分兩行 (或用連結符號)。
2. 批次檔的檔案要用 .bat 為副檔名,除了 Autoexec.bat,主檔名由用者自定,但最好避免和 DOS 指令同名,例如不要用 Copy.bat、Del.bat、Dir.bat、Exit.bat 等等。
3. 批次檔需用 DOS 指令加上特定語次寫成,這些指令包括 DOS 內部及外部指令,語法有以下各項:
call choice echo
for...in...do goto if(if exit)(if not exist)
pause rem shift
 指令錯誤會有 "Bad command or file name" 回應,語法錯誤會有 " Syntax error" 的回應。

4. 要 DOS 執行批次檔的指令,只需鍵入主檔名,例如 Menu.bat 或 menu。不過若批次檔的主檔名和 .com 或 .exe 的主檔名相同時,就要鍵入全名,例如批次檔的名稱是 copy.bat 或 edit.bat時,就要鍵入copy.bat 或 edit.bat 才能使電腦執行批次檔的指令,否則電腦會執行 copy.exe 或 edit.com 這些 DOS 指令。
5. 在批次檔執行途中,一起按下 [Ctrl]+[C] 或 [Ctrl]+[Break] 可終止程序。按下這兩個鍵後,螢幕會顯示:Terminate batch job (y/N)?
  按 [Y] 會終止這批次檔和回到 DOS 的提示號,按 [N] 則取消[Ctrl]+[C] 指令,批次檔會繼續執行程序。



早期在DOS系統工作下,都可能需要使用批次檔來執行電腦工作,當文字介面的系統逐漸被Windows、Unix系統(圖形介面)所取代時,現今一般使用電腦的人,可能也不是很清楚什麼是批次檔,我們今天就來介紹何謂批次檔。

批次檔是一種文字檔案(ASCII檔案),由一連串的MS-DOS命令所組成的。
批次檔的命名規則與一般檔案相同,但其副檔名固定為".BAT",即"將 一連串的命令"儲存在檔案中,該批次檔的指令可無限制的重覆使用,永遠得到相同的執行結果。究竟批次檔又該如何使用呢?以下介紹批次檔的常用指令。

批次檔的常用指令如下:

*------------------------------------------
一、 ECHO
*------------------------------------------

在正常的情況下,批次檔中的每道命令執行前都會先出現螢幕上。有了ECHO命令,就可以任意控制是否列印出命令列。
用法:在批次檔中鍵入echo on/off ,on:表示要印出命令列,off:則不印出命令列,若要禁止批次檔的命令顯示在螢幕上,則使用隱藏echo off(@ECHO OFF),用法在命令列的開頭上加上@符號
Ex:
@echo off 表示資料隱藏
echo .... 測試ECHO指令
echo .... 請稍後
echo .... 完成.....

結果:
Test Enter
.... 測試ECHO指令
.... 請稍後
.... 完成.....

*------------------------------------------
* 二、 代換參數
*------------------------------------------
代換參數的標記是一個百分號(%)再跟著一個阿拉伯數字,最多可使用10個代換參數,這些變數的值,則由呼叫批次檔的命令所指定。
Ex:
@echo off
echo .... 測試代換參數指令
echo .... 請稍後
echo .... 完成.....
echo %1 %2 %3 %4

結果:
Test TCP EDU NETWORK CENTER Enter
.... 測試ECHO指令
.... 請稍後
.... 完成.....
TCP EDU NETWORK CENTER

*------------------------------------------
* 三、 PAUSE:是暫停批次檔的執行。
*------------------------------------------
當MS-DOS執行到PAUSE時就暫時中止目前的工作,並印出下列訊息:
press any key to contunue ……
Ex:
@echo off
echo .... 測試代換參數指令
echo .... 請稍後
echo .... 完成.....
echo %1 %2 %3 %4
pause
echo %5 %6

結果:
Test TCP EDU NETWORK CENTER Enter E-Mail chan@ms64.hinet.net
.... 測試ECHO指令
.... 請稍後
.... 完成.....
TCP EDU NETWORK CENTER
Press any key to continue ....

E-Mail chan@ms64.hinet.net

*------------------------------------------
* 四、 REM(REMark)用來在批次檔執行中顯示某些訊息
*------------------------------------------
用法是在批次檔中鍵入rem,後面跟著所要顯示的字串

Ex:
@echo off
echo .... 測試代換參數指令
echo .... 請稍後
echo .... 完成.....
rem 下面指令,開始做代換參數
echo %1 %2 %3 %4
pause
echo %5 %6

*------------------------------------------
* 五、 IF
*------------------------------------------
IF命令在批次檔中用來測試特定的條件,以決定是否執行某些命令。絛件的型態分為四種:
////////////////////////////////////////////////////////////////////
(1) IF EXIST
此條件是用來檢查某一檔案是否存在,若存在則條件成立,便執行指定的命令
Ex:
@echo off
if exist test1.bat type test1.bat

////////////////////////////////////////////////////////////////////
(2) IF String1 = = String2(= = 表相等性的比較)
Ex:
@echo off
echo .... 測試IF指令
echo %1
if '%OS%'=='Windosws_NT' goto good
if %1 == a goto first
if %1 == b goto second
if %1 == c goto three
:good
echo 作業系統%OS%
:first
echo 執行first (a)
goto finish
:second
echo 執行second (b)
goto finish
:three
echo 執行three (c)
goto finish
:finish

結果:
Test1 a Enter
a
執行First(a)
執行程式結束

////////////////////////////////////////////////////////////////////
(3) IF ERRORLEVEL
ERRORLEVEL是由MS-DOS所管理的一個系統變數,目的是監視所有錯誤發生的情況。(類似ErrorMessage)

////////////////////////////////////////////////////////////////////
(4) IF NOT
IF NOT是當測試條件不成立時才執行後面命令

Ex:
@echo off
if not exist test1.bat type test1.bat
echo 執行程式結束

////////////////////////////////////////////////////////////////////

*------------------------------------------
* 六、 GOTO
*------------------------------------------
GOTO命令在批次檔中用來轉移控制權,可以指示批次檔跳至某一標記(line label)由一個冒號(:)跟著字元符號所組成的;label也可使用代換變數
Ex:
goto first 或 goto %1

*------------------------------------------
* 七、 FOR
*------------------------------------------
FOR命令允許批次檔中的其他命令,可以重覆地執行
for %%a IN (file1 file2 file3) DO del %%a
虛擬變數必須以兩個百分號(%%)起頭,in後面著參數列,do後面跟著要執行的命令

Ex1:
@echo off
echo .... 測試FOR指令
echo .... 請稍後
echo .... 完成.....
echo ....
for %%a IN (test_a.bat test_b.bat test_c.bat) do copy %%a prn

結果:
test Enter
.... 測試FOR指令
.... 請稍後
.... 完成.....
....
1 File(s) Copied
1 File(s) Copied
1 File(s) Copied

Ex2:
REM 取得日期
FOR /F "tokens=1-4 delims=/ " %%a IN ("%date%") DO (SET _MyDate=%%a%%b%%c%%d)

REM 顯示去掉分隔符號後的結果
echo %_MyDate%

說明:
/F 是指定將後面 %date% 的環境變數當成檔案來處理,而處理的依據就是在「"tokens=1-4 delims=/ "」這邊。tokens如果按照字面翻譯的話,是權杖的意思,這樣翻不太直覺,在這邊翻成順序可能比較好一些。以這個例子來說,就是要取得順序 1 ~ 4 的字串,那程式怎麼知道這個順序的分法呢?透過 delims 這個引述的設定,程式就知道要怎麼去分析 %date% 環境變數的順序。在 delims 等號右邊的字元就是用來指定分割順序的依據。以這個例子來說,我們用「/」與「 」(空白,White Space)這兩個分隔符號來分割 %date% 的順序。因此原本 %date% 的內容是 2006/03/07 星期二,在程式來看就變成了:

順序 內  容
﹉﹉ ﹉﹉﹉﹉
1    2006
2      03
3     07
4   星期二

%%a 是說把順序 1 的結果指派給名稱為 %%a 的變數,因此順序 2 的變數名稱就會是 %%b,以此類推,最多可以有 52 個變數,原因如下:變數名稱有大小寫之分,所以 %%a 跟 %%A 不同,且僅能以一個英文字母來命名,所以 26(個字母)× 2(大寫跟小寫 2 種)=52(個)。DO 後面的括號內容是用來指定所要執行的命令內容,以這個例子來說,就是指定一個名稱為 _MyDate 的變數,它的內容是由 %%a%%b%%c%%d 所構成的。

再來我們看看使用 FOR 指令去掉時間變數之分隔符號的結果:

MyTime.bat 的檔案內容如下所示:
----程式開始----


REM 取得時間
FOR /F "tokens=1-4 delims=:." %%a IN ("%time%") DO (SET _MyTime=%%a%%b%%c%%d)

REM 顯示去掉分隔符號後的結果
echo %_MyTime%

----程式結束----

看看執行的結果:

C:\>MyTime

螢幕輸出:

14243241

講了這麼多,您知道該怎麼運用 %date% 與 %time% 環境變數了嗎?

*------------------------------------------
* 八、 SHIFT
*------------------------------------------
SHIFT命令允許在批次檔的起動命令中,使用超過10以上的實際參數
(%0~%9)

*------------------------------------------
* 九、 CALL
*------------------------------------------
模組化的程式設計,是將一個完整的程式分割成一個個獨立的模組(module),每個模組負責一項功能
Ex:
@echo off
echo .... 測試CALL指令
echo .... 請稍後
echo %1 %2
call test_b
echo %3 %4
echo 程式模組已執行完畢 (test_a.bat)

@echo off
echo 執行test_b程式
echo 即將執行test_c .....
call test_c
echo 執行test_b程式完畢~~~ (test_b.bat)

@echo off
echo 執行test_c程式
if exist test2.bat type test2.bat
echo 執行test_c程式完畢~~~ (test_b.bat)

*------------------------------------------
* 十、 set
*------------------------------------------
宣告變數;設定變數

set gbs=%OS% 取得作業系統
set xdate=%date% 取得目前日期20080610
set xmonth=%date:~5,2% 取得目前月份06
set select=
set /P select=請選擇: 等待取得使用者所輸入字元


在DOS環境下輸入Set,可列出windows環境變數

2009年9月3日 星期四

[轉錄]C/C++之指標 (pointer),參考 (reference) 觀念整理與常見問題



from: Hung-Hsuan Chen (Sean)


這篇文章是由我舊的blog轉貼過來的


文中某些小細節稍作修改
--------------------------------
前 言
這是以前替人代班教課時寫的一些東西
重新整理後放上來,一方面當作自己的備忘錄 (自己最看得懂的還是自己寫的東西)
另一方面如果有人有這方面的問題,希望此文能對你們也有一點點幫助。
--------------------------------
很多程式員說:學C/C++而不會使用指標,相當於沒學過C/C++。
本文針對C/C++中,指標與參考的常見問題或錯誤,做了一番整理,但求能達到拋磚引玉之效。如有疏漏或錯誤之處,尚請不吝告知指教。


目錄
  1. 何謂指標 (pointer)? 何謂參考 (reference)?
  2. call by value? call by address (或call by pointer)? call by reference? -- swap(int* a, int* b) v.s. swap (int &a, int &b)
  3. pointer to pointer, reference to pointer (int** v.s. int*&)
  4. function pointer
  5. void ** (*d) (int &, char **(*)(char *, char **))....如何看懂複雜的宣告…
1. 何謂指標 (pointer)? 何謂參考 (reference)?
我們先談指標 (pointer)。指標,其實也只是一個變數,只是這個變數的意義是:指向某個儲存位址。很玄嗎? 一點也不。下面這張圖就可以輕易的看出指標為何物。

圖 中,a, b, c, d, p1, p2都是一般的變數,儲存在記憶體 (memory) 中。其中,p1變數所記載的值是變數a的記憶體 (memory) 位址,而p2則記載著b的記憶體位址,像這樣的狀況,我們就稱p1是一個指向a的指標,相同的,p2是一個指向b的指標。
在C/C++中,我們用下面的式子來表示這個關係:
int *p1 = &a;
int *p2 = &b;

其中的&,稱為address of (取址)。即,p1 = address of a,p2 = address of b。
另一個符號*,代表的意義是指標。int *p1要由後往前閱讀來瞭解它的意義:p1 is a pointer points to an integer。因此,int *p1 = &a;這整行,我們可以看成:p1 is a pointer points to integer variable a,即:p1是一個指標,指向整數變數a。


且讓我們暫時打住指標的討論,轉頭看看參考 (reference)。
參考,可以想像成是一個變數或物件的別名 (alias)。通常,當函式 (function) 的參數 (parameter) 在函式中會被修改,而且要把這個修改結果讓呼叫函式的部份繼續使用,我們會用參考來當參數傳入函式中。
讓我們看看下面的例子:
void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}

當其他程式呼叫此交換程式時,只要直接寫swap(x, y)就能交換x與y的值。在這裡,a和b為x與y的別名,即:a就是x,b就是y,如同美國國父就是華盛頓一樣。a和b不是x和y的複製品,任何做用在a與b上的動作都會反應在x與y上面,反之亦然。


指標和參考之所以難懂,有很大一部份的原因是符號上的陌生所致。加上&既能用於取址又能用於參考,容易造成初學者的混淆。下面我們提供幾個建議來幫助各位看懂這些符號。
  • 把int *p視為 int* p。
    把int和*連在一起看,當作是一種型態叫做 "指向整數之指標",要比int *p自然得多。同樣的方式也可以套在char* p或void* p等。但要注意的是下面的狀況:
    int* p, q;
    不要把這行誤解成p, q都是指向int之指標,事實上,q只是一個int變數。上面這行相當於
    int *p, q; int *p; int q;
    如果p, q都要宣告成指向int之指標,應寫成:
    int *p, *q
    或者干脆分兩行寫:
    int* p;
    int* q;

  • &前面有資料型態 (ex: int &),則為參考&前面有等號 (ex: int* p = &a),則為取址
    由於&同時具有多種意義,因此容易造成混淆。這裡列出的這個方法,可以幫助弄清楚每個&的意義。
2. call by value? call by address (或call by pointer)? call by reference? -- swap(int* a, int* b) v.s. swap (int &a, int &b)
JAVA中的reference與C++的reference意義上並不相同,卻使用同一個字,這也是reference容易造成混淆的原因。在此,我們暫不考慮JAVA中reference的觀念 (關於java中reference的觀念,請參考Reference in JAVA -- 淺談java的指標),純粹把主題放在C/C++上。
呼叫副函式時,call by value, address, 或reference是三種不同的參數傳遞方式。其意義如下:
  • call by value
    假設函式A呼叫函式B(p, q),則B中的p和q是「
    複製」自函式A所傳入的參數,B中對p, q所做的任何運算都不會影響到A中的p和q,因為B執行完後,並不會把複製的p, q存回到A中。這種參數傳遞方式,我們稱之為call by value。
    以swap這個常見的函式為例,若swap寫成下面的樣子:

    void swap(int a, int b){
    int tmp = a;
    a = b;
    b = tmp;
    }

    則呼叫
    swap(x, y)後,x和y的值並不會有變化。
  • call by address (或call by pointer)
    利用指標來做參數傳遞,這種方法骨子裡仍是call by value,只不過call by value的value,其資料型態為指標罷了。我們同樣看看用call by address來寫swap交換兩個integer的例子。

    void swap(int* a, int* b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
    }

    呼 叫swap時,要寫成swap(&x, &y)。呼叫swap時,x的指標 (x的儲存位置) 與y的指標 (y的儲存位置) 會被複製一份到swap中,然後把該位置內所記載的值做更換。swap結束後,&x (address of x) 和&y (address of y) 依然沒變,只是address of x所記錄之變數值與address of y所記錄之變數值交換了。因為&x 和&y 其實是利用call by value在傳,因此,
    call by address其實骨子裡就是call by value
  • call by reference
    這是C++才加進來的東西,C本身並沒有call by reference。call by reference基本上是把參數做個別名 (alias),以下面的swap為例:
    swap(int &a, int &b){
    int tmp = a;
    a = b;
    b = tmp;
    }

    未來使用時,只要呼叫swap(x, y),就可以讓x和y的值交換。在這個例子中,a
    就是 x, b 就是 y。這個觀念在上一節已經提過,在此不再贅述。
3. pointer to pointer, reference to pointer (int** v.s. int*&)
當 我們用call by pointer (或address) 來傳遞參數時,被呼叫的函式複製一份pointer的值過去。但是,當我們想在函式內改變pointer的值 (而非pointer所指向之變數的值),而且改變的效果要能在函式外看得到時,call by pointer就不足夠用了。此時應該用的是"call by pointer to pointer"或"call by reference to pointer"。我們先看下面的例子:
int g_int = 0;
void changePtr(int* pInt){
pInt = &g_int;
}
void main(){
int localInt = 1;
int* localPInt = &localInt;
changePtr(localPInt);
printf("%d\n", *localPInt);
}

在這個例子中,印出來的數字仍然會是localInt的1,因為changPtr中的pInt是由localPInt「複製」過去的,對pInt做改變並不會反應到localPInt身上。
我們先用pointer to pointer對localPInt做改變,請看下例。

int g_int = 0;
void changePtr(int** pInt){
*pInt = &g_int;
}
void main(){
int localInt = 1;
int* localPInt = &localInt;
changePtr(&localPInt);
printf("%d\n", *localPInt);
}

本 例中,印出來的數字會是g_int的0。changePtr函式中的pInt是由&localPInt複製所得,因此對pInt做改變並不會影響 main中的&localPInt (資料型態:pointer to pointer to integer)。但在changePtr函式中我們改變的對象是pInt所指向的內容,因此這項改變在main中會顯示出來。


同樣的功能,我們也可改用reference to pointer來完成。但同樣切記,reference是C++才有的功能,因此reference to pointer也只能在支援C++的環境中使用。
int g_int = 0;
void changePtr(int* &refPInt){
refPInt = &g_int;
}
void main(){
int localInt = 1;
int* localPInt = &localInt;
changePtr(localPInt);
printf("%d\n", *localPInt);
}

這 段程式印出來的數字會是0。因為在changePtr中,我們宣告的參數型態為int* &,即:reference to pointer to integer。因此,main中的localPInt與changePtr函式中的refPInt其實是「同一件東西」。


另一種 常見的混淆是pointer array (指標陣列) 與pointer to pointers,因為兩種都可以寫成**的型式。如,int**可能是pointer to pointer to integer,也可能是integer pointer array。但pointer array的觀念相對來講要簡單且直觀許多,這裡我們就暫不花篇幅敘述。常見的例子:main(int argc, char** argv)其實應該是main(int argc, char* argv[])。


4. function pointer
變數的指標指向變數的位址,同樣的,function pointer (函式指標) 也是指向函式的位址的指標。
函式指標的加入,讓C/C++的符號更複雜,也使更多人望之而卻步。在說明函式指標的用途前,我們先直接由語法來看看函式指標該怎麼宣告、怎麼理解。
假設有個函式長成下面的樣子:
void func1(int int1, char char1);
我們想宣告一個能指向func1的指標,則寫成下面這樣:
void (*funcPtr1)(int, char);
這樣的寫法應理解成:funcPtr1是一個函數指標,它指向的函數接受int與char兩個參數並回傳void。如果今天有另一個函式長成
void func2(int int2, char char2);
則funcPtr1也能指向func2。
指標指向的方法,寫成下面這樣:
funcPtr1 = &func1;
取址符號省略亦可,效果相同:
funcPtr1 = func1;
若欲在宣告時就直接給予初值,則寫成下面這樣:
void (*funcPtr1)(int, char) = &func1; //&亦可省略


stdlib.h中提供的qsort函式是函式指標最常見的應用之一。此函式之prototype長得如下:
void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*));
其中的int (*cmp)(const void*, const void*) 就使用到函式指標。


函式指標常見的使用時機是multithread時。函數指標負責把函數傳進建立執行緒的API中。
另外,callback function也是常使用函式指標的地方。所謂callback function即:發生某事件時,自動執行某些動作。在event driven的環境中,便時常使用callback function來實現此機制。
事實上,函式指標還能讓C語言實作polymorphism。但礙於篇幅,在此不再詳述。


5. void ** (*d) (int &, char **(*)(char *, char **))....如何看懂複雜的宣告…
在這裡,我們介紹兩種方式來看懂複雜的宣告。第一種要判斷的是:常數與指標混合使用時,到底const修飾的是指標還是指標所指的變數? 第二種是面對如標題所示這種複雜的宣告時,我們要怎麼讀懂它。


5.1 常數與指標的讀法
const double *ptr;
double *const ptr;
double const* ptr;
const double *const ptr;

以上幾個宣告,到底const修飾的對象是指標,還是指標所指向的變數呢?
其實,關鍵在於:*與const的前後關係!
當*在const之前,則是常數指標,反之則為常數變數。因此,
const double *ptr; // ptr指向常數變數
double *const ptr; // ptr是常數指標
double const* ptr; // ptr指向常數變數
const double *const ptr; // 指向常數變數的常數指標

事實上,在The C++ Programming Language中有提到一個簡單的要訣:由右向左讀!!讓我們用這個要訣再來試一次。
const double *ptr; // ptr is a pointer points to double, which is a constant
double *const ptr; // ptr is a constant pointer points to double
double const* ptr; // ptr is a pointer points to constant double
const double *const ptr; // ptr is a constant pointer points to double, which is a constant

結果完全相同 :-)


5.2 複雜宣告的讀法 void ** (*d) (int &, char **(*)(char *, char **)).......
其實閱讀C/C++中複雜的宣告有點像是讀英文的長句子,看多了,自然知道句子是怎麼構造出來的。
但對於句子還不熟的人,難免得藉助文法來拆解一個句子。關於C語言複雜宣告的解析文法,最令我印象深刻的,莫過於印度工程師Vikram的"The right-left rule"。他是這麼說的:
「從最內層的括號讀起,變數名稱,然後往右,遇到括號就往左。當括號內的東西都解讀完畢了,就跳出括號繼續未完成的部份,重覆上面的步驟直到解讀完畢。」
舉個例子:void ** (*d) (int &, char*)依下面方式解讀:
1. 最內層括號的讀起,變數名稱: d
2. 往右直到碰到) : (空白)
3. 往左直到碰到( :是一個函數指標
4. 跳出括號,往右,碰到(int &, char*): 此函式接受兩個參數:第一個參數是reference to integer,第二個參數是character pointer。
5. 往左遇上void **: 此函式回傳的型態為pointer to pointer to void。
==> d是一個函式指標,指向的函式接受int&和char*兩個參數並回傳void**的型態。
如何,是不是好懂很多了呢?


標題中的void ** (*d) (int &, char **(*)(char *, char **))其實和上面的例子幾乎一樣,只是函式的第二個參數又是一個函式指標,接受char*和char**兩個參數並回傳char**的型態。



行文至此,把指標和參考的常見問題與混淆大致地提了一些。希望能讓使用C/C++的人在面對或使用指標、參考、或取址時,不再有疙瘩在心中。文中若有不足或錯誤之處,也請高手不吝指教囉。:-)


C++ Learning

C++ Learning


C 語言常見問題集 http://twpug.net/docs/ccfaq/ccfaq.html

侯捷網站 - 出了非常多有關C/Window/Java書籍的老師,網站內容有許多書籍的勘誤與問答,內容非 常扎實,還有電子書可以下載

CSDN -大陸最大的IT技術網站,寫程式必去的地方。

C Programming and C++ Programming - C/C++ very Good English Site.

C++ Language Tutorial -C++教學網站 還滿不錯的 資料滿齊全的 但是是英文網站,必須要有點耐心。

C++學習筆記-C++教學網站 資料範例也都很齊全,講解也蠻清楚的,重點他是中文滴,適合初學者。

VC++知識庫-裡面有許多好的文章以及範例,雖然叫做VC++知識庫但是內容包羅萬象,是個不錯滴地方,我也常到那邊看文章,是簡體網站。有些文章是翻譯英文網站滴,雖然不是原作,但是至少有翻譯的文章對應,台灣哪時候才能有這樣的網站呢?

Codeguru - 與Code porject網站差不多,也是值得一去的好地方。

CodeProject - Source Code相當豐富的網站,內容相當豐富,不侷限於一種程式語言,找Code的好地方。

工程師的家

移動技術網 - 相關嵌入式系統的網站,資料相當豐富的大陸網站。

WinCE MS官方網站

Visual C++ Tutorial - Widow SDK & MFC,不錯的英文網站。

DevX - 不錯的C/C++學習網站。

乘風原創程序- BCB 相關文章,還有一些BCB控制硬體相關文章。大陸網站。

第二學堂- BCB相關基本教學網站。

香港學網 - C ,8051,Perl,JavaScript,Oracle..等程式語言基本教學。

Java examples - Java、C/C++、C#、PHP、Python、VB.Net、SQL相關教學文章。

C++ 程式討論版(內含教學文件)

C程式簡介

cs9-C++ 部落格文章

NTOU CS 程式設計課程

駱思安老師的教學網站

C++ FAQ Lite

International ACM Programming Content

Lucky 貓的 ACM 園地

部落格文章(Embeded linux 教學)

OpenCV中文教程 - 影像處理的函式庫。

C++ Standards Committee Papers

Just software solutions-Blog Archive for / cplusplus /

C Language I/O

http://www.eefocus.com/html/09-05/5311327060403cJqm.shtml



除了人工的分析之外,最簡單最直接的調試方法要算printf了。不過,我們這裡推薦使用的並不是初學C語言時使用的函數int printf(const char *format, ...),而是稍微複雜一點的fprintf()函數,因為它更方便我們之後重定向錯誤輸出信息到指定的設備。 fprintf()函數的原型如下:
int fprintf(FILE *stream, const char *format, ...)

可以看到,它與printf()函數相比多出來了第一個參數FILE *stream,其意義是將打印的內容輸出到文件流指針stream指向的流。所謂流,通常是指程序輸入或輸出的一個連續的字節序列,設備(例如鼠標、鍵盤、磁盤、屏幕、調製解調器和打印機)的輸入和輸出都是用流來處理的,在C語言中,所有的流均以文件的形式出現——不一定是物理磁盤文件,還可以是對應於某個輸入/輸出源的邏輯文件。 C語言提供了5種標準的流,你的程序在任何時候都可以使用它們,並且不必打開或關閉它們。以下列出了這5種標準的流。
----------------------------------------
名稱 描述 例子
stdin 標準輸入 鍵盤
stdout 標準輸出 屏幕
stderr 標準錯誤 屏幕
stdprn 標準打印機 LPT1端口
stdaux 標準串行設備 COM1端口
----------------------------------------



其中,stdprn和stdaux並不總是預先定義好的,因為LPT1和COM1端口在某些操作系統中是沒有意義的,而stdin,stdout和stderr總是預先定義好的。此外,stdin並不一定來自鍵盤,stdout也並不一定顯示在屏幕上,它們都可以重定向到磁盤文件或其它設備上。我們在頭文件stdio.h中可以找到stdin,stdout和stderr的定義如下:
/* Standard streams. */
extern struct _IO_FILE *stdin; /* Standard input stream. */
extern struct _IO_FILE *stdout; /* Standard output stream. */
extern struct _IO_FILE *stderr; /* Standard error output stream. */


在使用fprintf()函數時,通常我們可以將第一個參數設為stdout或者stderr,打印出錯調試信息的時候則推薦使用stderr而不是stdout,這是一種慣例,同時也由於內核在處理stdout和stderr時的優先級不一樣,後者的優先級要高一些,因此有時候如果程序異常退出時,stderr能得到輸出,而stdout就不行。
printf(...)實際上相當於fprintf(stdout, ...),這也是為什麼我們不推薦使用它的原因。在輸出調試信息的時候,我們推薦使用fprintf(stderr, …),或者使用某個指定的文件流fprintf(some_stream, …)。

那麼具體如何在必要的時候重定向fprintf()中的調試信息呢?來看看下面的一些方法:
當調試信息的量比較大,需要一些時間或者其他輔助工具來搜索過濾時,僅僅利用顯示屏幕來輸出調試信息是不夠的,這時我們經常將這些信息輸出到所謂的日誌文件(log)中,之後再仔細的分析log文件來發現問題。
利用Shell的I/O重定向
簡單的寫log方法可以通過shell的I/O重定向機制來實現,比如下面的代碼:
1 #include
2
3 int main()
4 {
5 fprintf(stdout, "This is a standard output info!\n");
6 fprintf(stderr, "This is a standard error output info!\n");
7 return 0;
8 }


在默認條件下,編譯運行的結果是打印信息都輸出在屏幕上:
$ gcc fprint.c -o fprint
$ ./fprint
This is a standard output info!
This is a standard error output info!


這是因為默認情況下,shell所打開的stdout和stderr設備都是顯示屏幕。不過我們可以通過shell的重定向功能來將打印信息寫到文件中去。比如:
$ ./fprint >output.log
This is a standard error output info!
$ cat output.log
This is a standard output info!


這樣,我們把stdout的輸出寫到了文件output.log中,不過stderr的輸出還是在屏幕上。如何重定向stderr呢?這需要用到shell定義的文件描述符。在shell下stdin, stdout,和stderr的文件描述符分別是0, 1和2,我們可以用下面的方法重定向:

$ ./fprint >output.log 2>error.log
$ cat output.log
This is a standard output info!
$ cat error.log
This is a standard error output info!
$
$ ./fprint >output.log 2>&1
$ cat output.log
This is a standard error output info!
This is a standard output info!

其中./fprint >output.log 2>error.log分別將stdout和stderr的輸出寫入到文件output.log和error.log中,而./fprint >output.log 2>&1則表示將stderr的輸出追加到stdout的文件output.log中(結果是output.log中既有stdout輸出也有stderr輸出)。

一些常用的shell I/O語法如下:
cmd > file把stdout重定向到file文件中
cmd >> file把stdout重定向到file文件中(追加)
cmd 1> fiel把stdout重定向到file文件中
cmd > file 2>&1把stdout和stderr一起重定向到file文件中
cmd 2> file把stderr重定向到file文件中
cmd 2>> file把stderr重定向到file文件中(追加)
cmd >> file 2>&1把stderr和stderr一起重定向到file文件中(追加)

在平時的簡單調試中,我們可以靈活利用這些方法來快速得到log文件。

用freopen()進行重定向
有時候我們要求在程序中能夠控制標準流的重定向,這時可以利用標準C庫函數freopen()。 freopen()的函數原型如下:
FILE *freopen(const char *filename, const char *mode, FILE *stream)
下面的代碼用來測試用函數freopen()重定向stderr:

1 #include
2
3 int main()
4 {
5 if (freopen("err.log", "w", stderr)==NULL)
6 fprintf(stderr, "error redirecting stderr\n");
7 fprintf(stdout, "This is a standard output info!\n");
8 fprintf(stderr, "This is a standard error output info!\n");
9 fclose(stderr);
10 return 0;
11 }

在第5行我們用freopen()函數將stderr重定向到了”err.log”文件,這樣得到的結果如下:
$ gcc print_log.c -o print_log
$ ./print_log
This is a standard output info!
$ cat err.log
This is a standard error output info!


可見第8行打印到stderr的信息被重定向到了err.log文件中,而第7行stdout的打印信息則還是輸出到了屏幕上。

printf( ) 的列印格式、控制字元、修飾子


列印格式--輸出敘述
%c-字元
%s-字串
%d-十進位整數
%u-無號十進位整數
%o-無號八進位整數
%x-無號十六進位整數,以 0 ~ f 表示
%X-無號十六進位整數,以 0 ~ F 表示--
%f-浮點數,小數點型式
%e-浮點數,指數e型式
%E-浮點數,指數E型式
%g-印出 %f %e 較短者
%G-印出 %F %E 較短者
%p-指標位址
%%-印出百分比符號
-
-控制字元---功能
\a-警告音
\b-倒退
\f-換頁
\n-換行
\r-歸位
\t-跳格
\’-印出單引號
\”-印出雙引號
\\-反斜線
\/-斜線
\d-八進位 Ascii 碼
\x-十六進位 Ascii 碼--
-
-修飾子--功能-範例
--向左對齊-%-3d
+-將數值的正負號顯示出來-%+5d
空白-數值為正值時,留一格空白;為負值時,顯示負號-% 6f
0-將固定欄位長度的數值前空白處填上 0;與 – 修飾子同時使用時,此修飾子無效---%07.2f--
數字-欄位長度,當數值的位數大於所定的欄位長度時,欄位會自動加寬它的長度-%9d
.-數值以 %e, %E, %f 型式表示時,決定小數點後所要顯示的位數-%4.3f
h-表示 short int 或是 unsigned short int-%5h
l-表示 long int 或是 unsigned long int-%lu

2009年7月8日 星期三

這是一切的開端 - 2009開放原始碼創新應用開發大賽

存在的意義也許有很多種
我想要不斷地進步
能夠感受自己的存在
就是自己的東西受到肯定

對我來說
這是一切的開端
是這個workshop的起源

談到這個workshop要進行的軟體設計是甚麼
我還有沒確切的構想
但是卻有這樣的雄心壯志要開始進行
好久沒有熱衷於一件事

我想知道自己究竟可以走多遠

2009開放原始碼創新應用開發大賽

2009開放原始碼創新應用開發大賽

報名須知

1、報名方式

線上方式報名(請點選上方我要報名)

2、報名時間

自5月4日(星期一) 9時起至6月30日(星期二) 17時止

3、報名程序

3-1、參賽者(或團隊)線上報名後,需再上傳繳交「企畫書」(檔案格式需為pdf格式)始完成報名,「企畫書」內容如下:

  1. 提案構想:主題及功能描述
  2. 系統設計:使用平台、技術與系統架構設計
  3. 計畫管理:時程規劃與實作方式
  4. 專案網址:說明在 SourceForge.net OpenFoundry 開啟的專案網址
  5. 版權宣告:說明參賽作品宣告的版權,需為開放原始碼促進會(OSI)所核准之開放原始碼授權
  6. 其他:其他補充說明

3-2、參賽團隊需在下列自由軟體網站開啟新專案,持續更新,並在企畫書中說明清楚。

  1. SourceForge.net(http:⁄⁄sourceforge.net⁄)
  2. OpenFoundry(http:⁄⁄of.openfoundry.org⁄)
------------------------------------------------------------------------------------------------

競賽主軸

  • 以Linux 作業系統的筆記型電腦、平價電腦或行動裝置(例如智慧型手機、MID等)上的應用程式功能新增或強化為此次競賽主題。

作品開發建議(隨時更新):

  • 工具套件功能新增或強化:包含使用者操作介面或功能新增或改善等
  • 檔案內容預覽應用程式
  • 虛擬化應用程式
  • 網路管理應用程式
  • 多媒體應用:
    • 影音:例如隨選視訊應用
    • 教育學習
    • 遊戲娛樂

----------------------------------------------------------

活動時程規劃如下:


5/4(一)~7/31(五) 競賽報名
9/21(一)~10/2(五) 作品收件
10/12(一)~10/16(五) 作品評選(詳細時間將另行公佈)
11/26(四)(暫訂) 頒獎典禮與成果發表