搜尋此網誌

2009年12月26日 星期六

自來水博物館遊記

自從到了台灣大學創新育成中心工作之後,每天看到的風景就是自來水博物館
說實話,自來水博物館裡面真的是甚麼都沒有..有的就是那棟巴洛克風的建築.
不過不可諱言的,那棟建築物在黃昏及夜晚真的很美.
從建築物窗戶透出昏黃的燈光,在外面以略強的燈光直打外牆,配合巴洛克的風格,根本就是絕配.
只是我想不懂的是..為何大家都是白天來這裡拍婚紗...真是浪費此處的美景.

2009年11月6日 星期五

如何執行外部程式,並取得其標準輸出資料

在Qt中,要執行外部程式最容易的方法就是使用 QProcess, 並連結 readyReadStandardOutput 這個signal來取得其標準輸出.

例如,我們要在程式內部執行 ls 這個命令,並取得其結果,我們可以這麼做

// header file ----------

QProcess pls;

// cpp ------------------

connect(&pls, SIGNAL(readyReadStandardOutput()), this, SLOT(sl_readPlsOutput()));

pls.start("ls", QStringList() << "-al");

if (!pls.waitForStarted())
printf("wait for pls\n");
if (!pls.waitForFinished())
printf("wait for pls\n");

// slot -------------------
sl_readPlsOutput()
{
QByteArray tmpArray;
tmpArray = pls.readAllStandardOutput();
}

2009年10月20日 星期二

如何利用QT來取得系統設定

在Linux的環境中,大部分的設定都是標準的文字檔,那要如何取得那些設定的資料呢?
如果我們是用QT開發的話,可以用以下的方式
1. 利用QFile以文字檔的方式開啟設定檔
2. 將設定檔中的資料一行一行的讀出

範例1: 判斷系統是否存在特定型號的DVD
bool isFindDVD()
{
QFile procDVD("/proc/scsi/sg/device_strs");
if (!procDVD.open(QIODevice::ReadOnly | QIODevice::Text))
return false;

QString line;
while(1) {
line = QString(procDVD.readLine());
if (line.isEmpty()) break;
eprintf("isFindDVD = %s\n", qPrintable(line));
if ((line.contains("ATAPI")) && (line.contains("DVD"))) {
return true;
}
}
return false;
}

範例2: 取得 CPU的型號
QString cpuModel()
{
QFile procCPU("/proc/cpuinfo");
if (!procCPU.open(QIODevice::ReadOnly | QIODevice::Text))
return "";

QString line;
while (1) {
line = QString(procCPU.readLine());
if (line.isEmpty()) break;
if (line.contains("model name")) {
return line;
}
}
return "";
}

2009年10月9日 星期五

Function template

Function template 是一種可以依傳入型別的不同,自動產生特定函事實體的方法
Function template最簡單的的定義方法如下:

template
MyType min (MyType a, MyType b) {
return (a < b) ? a : b;
}
其中 < class MyType >, 代表是 template 的參數列, 意即 MyType的型別是可經由傳入的參數改變其型別.
例如, 我們如下的方式呼叫
min(10, 100); // int, int
則產生的函式實體為
int min (int a, int b) {
return (a < b) ? a : b;
}
因為,傳入的參數型態為整數,所以 MyType 的型態就變成了 int.
假設我們呼叫的方式為
min(10.0, 100.0); //double, double
則產生的函式實體為
double min (double a, double b) {
return (a < b) ? a : b;
}
當然, 參數列的參數,不以一個為限,它可以有多個參數
如:
template
Type1 findMax(Type1 a, Type2 b)
{
return ( a > b) ? a : b;
}
假設我們呼叫的方式為
findMax(10, 100.0); // int, double
則產生的函式實體為
int findMax(int a, double b) {
return ( a > b) ? a : b;
}
其中 Type1被 int取代,而 Type2 被double取代.

--------------------------------------------------
然而參數列的參數,不僅僅是要型別參數,也可以是非型別參數,所謂的非型別參數所代表的即為一個數值,這個數值在template的定義式中式一個常數
如:
template
Type min(Type (&arr) [size]) {
………
}
其中的 int size 即為非型別參數
假設我們已如下的方法呼叫
Int i;
int ia[] = {1, 2, 3};
i = min(ia);
則產生的函式實體為
int min(int (&arr) [3]) {
………
}
其中 Type被 int取代, 而 size 被3取代 (因為 ia這個這個陣列有三個元素).

2009年9月29日 星期二

Function Pointer(C)、Delegate(C#) 和Function Object(C++)

摘自 http://oomusou.cnblogs.com

Abstract
Function Pointer(C)、Delegate(C#)和Function Object(C++)這三個其實是一樣的功能,所以在此一併討論。

Introduction
function pointer是C語言中最高級的機制,大概很多人還沒上到這裡已經學期末了,所以不少C語言工程師根本不知道C語言有function pointer;而C#的delegate大抵跟C語言的function pointer功能相同,所以很多書說delegate是物件導向的function pointer;C++的function object功能則比function pointer略強,還可配合泛型使用。

為什麼會需要function pointer、delegate、function object這種機制呢?源於一個很簡單的想法:『為什麼我們不能將function也如同變數一樣傳進另外一個function呢?』,C語言的解決方式是,利用pointer指向該function,將該pointer傳入另外一個function,只要將該pointer dereference後,就如同存取原function一樣。C#解決的方式是,將function包成delegate object,傳入另外一個function。C++的解決方式是,利用class或struct將function包成object,傳入另外一個 function。

一個很簡單的需求,想個別列出陣列中,所有奇數、偶數、和大於2的數字,若使用傳統方式,而不使用function pointer,則寫法如下
1#include
2
3using namespace std;
4
5void printArrayOdd(int* beg, int* end) {
6 while(beg != end) {
7 if ((*beg)%2)
8 cout << *beg << endl;
9
10 beg++;
11 }
12}
13
14void printArrayEven(int* beg, int* end) {
15 while(beg != end) {
16 if (!((*beg)%2))
17 cout << *beg << endl;
18
19 beg++;
20 }
21}
22
23void printArrayGreaterThan2(int* beg, int* end) {
24 while(beg != end) {
25 if ((*beg)>2)
26 cout << *beg << endl;
27
28 beg++;
29 }
30}
31
32int main() {
33 int ia[] = {1, 2, 3};
34
35 cout << "Odd" << endl;
36 printArrayOdd(ia, ia + 3);
37
38
39 cout << "Even" << endl;
40 printArrayEven(ia, ia + 3);
41
42 cout << "Greater than 2" << endl;
43 printArrayGreaterThan2(ia, ia + 3);
44}


執行結果
Odd
1
3
Even
2
Greater than 2
3


以功能而言沒有問題,但每個function都要做迴圈與判斷,似乎重覆了,而且將來若有新的判斷,又要copy整個迴圈,然後改掉判斷式,若能將迴圈與判斷式分離,若日後有新的判斷式,只要將該判斷式傳進來即可,這就是function pointer概念。

使用C語言的Function Pointer
1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename : FuntionPointer.cpp
5Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use function pointer
7Release : 05/01/2007 1.0
8*/
9#include
10
11using namespace std;
12
13typedef bool (*predicate)(int);
14
15bool isOdd(int i) {
16 return i%2? true : false;
17}
18
19bool isEven(int i) {
20 return i%2? false : true;
21}
22
23bool greaterThan2(int i) {
24 return i > 2;
25}
26
27void printArray(int* beg, int* end, predicate fn) {
28 while(beg != end) {
29 if ((*fn)(*beg))
30 cout << *beg << endl;
31
32 beg++;
33 }
34}
35
36int main() {
37 int ia[] = {1, 2, 3};
38
39 cout << "Odd" << endl;
40 printArray(ia, ia + 3, isOdd);
41
42 cout << "Even" << endl;
43 printArray(ia, ia + 3, isEven);
44
45 cout << "Greater than 2" << endl;
46 printArray(ia, ia + 3, greaterThan2);
47}


執行結果
Odd
1
3
Even
2
Greater than 2
3


第13行
typedef bool (*predicate)(int);


宣告了predicate這個function ponter型別,指向回傳值為bool,參數為int的function,值得注意的是(*predicate)一定要括號刮起來,否則 compiler會以為是bool*,我承認這個語法很奇怪,但若仔細想想,若我是C語言發明者,我應該也是這樣定語法,因為也沒其他更好的語法了:D。

這個範例將判斷式和迴圈分開,日後若有新的判斷式,只要新增判斷式即可,funtion pointer提供了一個型別,讓參數可以宣告function pointer型別
void printArray(int* beg, int* end, predicate fn) {


如此我們就可以將function傳進另外一個fuction了。

使用C#的Delegate
C#是個物件導向的語言,為了提供類似function pointer的機制,提出了delegate概念,delegate英文是『委託、代表』,表示可以代表一個function,可以將delegate想成物件導向的function pointer。
1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename : Delegate.cs
5Compiler : Visual Studio 2005 / C# 2.0
6Description : Demo how to use delegate
7Release : 05/01/2007 1.0
8*/
9
10using System;
11
12class main {
13 public delegate bool predicate(int i);
14
15 public static bool isOdd(int i) {
16 return (i % 2) > 0? true : false;
17 }
18
19 public static bool isEven(int i) {
20 return ((i % 2) > 0? false : true);
21 }
22
23 public static bool greaterThan2(int i) {
24 return i > 2;
25 }
26
27 public static void printArray(int[] arr, int size, predicate fn) {
28 for(int i = 0; i != size; ++i) {
29 if (fn(arr[i]))
30 Console.WriteLine(arr[i].ToString());
31 }
32 }
33
34 public static void Main() {
35 int[] ia = {1, 2, 3};
36
37 Console.WriteLine("Odd");
38 printArray(ia, 3, new predicate(isOdd));
39
40 Console.WriteLine("Even");
41 printArray(ia, 3, new predicate(isEven));
42
43 Console.WriteLine("Greater than 2");
44 printArray(ia, 3, new predicate(greaterThan2));
45 }
46}


執行結果
Odd
1
3
Even
2
Greater than 2
3


整個C#程式和C語言程式幾乎是一對一對應,定義function pointer型別變成了13行
public delegate bool predicate(int i);


表示predicate是一個delegate型別,代表一個迴傳為bool,參數為int的function。

而原來宣告function pointer型態的參數,則改成delegate型態
public static void printArray(int[] arr, int size, predicate fn) {


使用C++的Function Object
function object也稱為functor,用class或struct都可以,因為function object是利用constructor和對operator()做overloading,而這些都是public的,所以大部分人就直接使用 struct,可少打public:這幾個字。
1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename : FuntionObject.cpp
5Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use function object
7Release : 05/01/2007 1.0
8*/
9#include
10
11using namespace std;
12
13template
14struct isOdd {
15 bool operator() (T i) {
16 return i%2? true : false;
17 }
18};
19
20template
21struct isEven {
22 bool operator() (T i) {
23 return i%2? false : true;
24 }
25};
26
27template
28struct greaterThan2 {
29 bool operator() (T i) {
30 return i > 2;
31 }
32};
33
34template
35struct greaterThanAny {
36 T _val;
37 greaterThanAny(T n) : _val(n) {}
38 bool operator() (T i) {
39 return i > _val;
40 }
41};
42
43
44template
45void printArray(T beg, T end, U fn) {
46 while(beg != end) {
47 if (fn(*beg))
48 cout << *beg << endl;
49
50 beg++;
51 }
52};
53
54int main() {
55 int ia[] = {1, 2, 3};
56
57 cout << "Odd" << endl;
58 printArray(ia, ia + 3, isOdd());
59
60 cout << "Even" << endl;
61 printArray(ia, ia + 3, isEven());
62
63 cout << "Greater than 2" << endl;
64 printArray(ia, ia + 3, greaterThan2());
65
66 cout << "Greater than any" << endl;
67 printArray(ia, ia + 3, greaterThanAny(1));
68}


執行結果
Odd
1
3
Even
2
Greater than 2
3
Greater than any
2
3


13行
template
struct isOdd {
bool operator() (T i) {
return i%2? true : false;
}
};


使用了template,不過並非必要,只是顯示function object可以搭配template使用,而使用的技巧只是將function內的東西搬到operator()內。

34行
template
struct greaterThanAny {
T _val;
greaterThanAny(T n) : _val(n) {}
bool operator() (T i) {
return i > _val;
}
};


是function object優於function pointer和delegate之處,由C語言和C#的範例可知,我們只能寫一個greaterThan2()的判斷式,若今天需求改變成 greaterThan3,則又得再寫一個判斷式了,但因為function object是透過struct和class,別忘了struct和class還有個constructor,所以能藉由constructor對 class做初始化,因此才能寫出greaterThanAny(),大於多少只要當成constructor帶入即可,而operator()的寫法一樣不變。

Conclusion
C語言、C#、C++皆提供了『將函數傳到另外一個函數』的機制,function pointer和delegate相當類似,而funtion object則功能更強。這裡澄清一個觀念,很多人認為function object就是為了要使用STL的algorithm才使用,這是標準的錯誤觀念,這是果而非因,因為STL的algorithm使用了 function object的方式,所以我們才去配合,並不是只用在這個地方,事實上,我們自己的也可以使用function object,而且其比function pointer優越之處就在於function object多了constructor,所以比function pointer彈性更大。

2009年9月6日 星期日

華山-台灣設計師週半日遊

閒來無事, 去華山看台灣設計師週展.
然而不知是我缺乏設計師對美的觸感,還是台灣的設計師少了一些令人驚艷的設計感動..也許是我走馬看花,沒有深刻走入設計師們的內心世界吧^^
分享一些,我個人還覺得不錯的設計

看起來好像真的可以養生的茶包


如果有女朋友或老婆幫忙敗家的話,讓她拿這些袋子,不知道可以不可以幫忙省點荷包?


好大的燈泡阿!


個不是在設計週展中展出的,而是在另一個展區(奔牛節)展出的,說真的我很喜歡這個創意,不但簡單而且又極富創意....重點是,看了這張圖,讓我真的好想吃碗牛肉麵


原來ㄜ便便的過程是這樣

2009年7月20日 星期一

bit 運算

bit的運算其實沒啥了不起,但除非是作跟硬體相關的程式設計,用到的機會還真是不多.
但很不巧的是,有時就是偏偏會碰上,更不巧的是.因為很少碰.所以也就不知道該怎麼寫處理bit的程式.
其實在C++是使用bitset這個class
bitset的操作行為:
anytrue if any bits are set
countreturns the number of set bits
flipreverses the bitset
nonetrue if no bits are set
resetsets bits to zero
setsets bits
sizenumber of bits that the bitset can hold
testreturns the value of a given bit
to_stringstring representation of the bitset
to_ulongreturns an integer representation of the bitset

範例1 (開啟某個bit):
#include 
#include
using namespace std;

int main ()
{
bitset<4> mybits;

cout << class="comm">// 1111
cout << class="comm">// 1011
cout << class="comm">// 1111

return 0;
}

範例2:
#include
#include
#include
using namespace std;

int main (關閉某個bit)
{
bitset<4> mybits (string("1011"));

cout << class="comm">// 1001
cout << class="comm">// 0000

return 0;
}

2009年7月11日 星期六

品牌與設計

品牌是包含了設計,軟體,硬體與服務.
設計這個名詞代表的涵義很廣.
工業設計是設計,但我熟悉的電腦程式設計也是設計.
其實當設計去除的商業價值之後,它就是一個藝術
工業設計是藝術,程式設計也是藝術
那是發自於人心的自然感動.
自然也就沒有軟體、硬體、服務與品牌.那些充滿商業的包裝.
工程師通常很工程導向,設計師通常很設計導向..但這樣並不是好事.
因為那會造成判斷上的偏頗,
我個人認為如果作為商業(經濟價值)導向的設計,就必須把本身的專業放到第二順位.,
譬如我是學程式設計,我就要把程式設計的重要性放在次要.如此才能看到其他元素的重要性及其影響性.
如此一來,才有利於結合其他元素的特點,開發出更有特色的品牌

2009年7月5日 星期日

後現代主義設計 (Post Modern)

年代: 1960~


特色: (將象徵意義置入設計之中)
  • 後現代主義設計主要是從形式上對現代主義進行修正。
  • 現代主義反對裝飾以節省額外開支,希望讓大眾都享有設計產品。
  • 而後現代主義則恢復裝飾性,無論建築設計師或產品設計師,都強調裝飾性。他們特別從歷史中吸取裝飾營養,採用的對象有各種各樣的歷史風格,從哥德到巴洛克,從古典到文藝復興,無所不包。
  • 後現代主義並不是單純恢復歷史風格,而是在現代主義設計的構造基礎上,對歷史風格採用抽出、混合、拼接等折衷處理方法。

城市風格:
Las Vegas

2009年6月27日 星期六

父親的相機


在我小時後,父親就是用這台相機,幫我們全家留下許許多多的回憶.
雖然父親已經過世,相機早已殘破.
雖然回憶的相片早已泛黃.
但它卻是父親留給我們最珍貴的寶貝.

2009年6月25日 星期四

葉問

葉偉信執導,甄子丹主演


傳統的清末民初武師民族意識的電影,
充滿了商業娛樂性質,卻了無新意,
看了前面就知道結局.
就好像看李連杰主演的霍元甲一般,唯一的差別是他沒打西方人.
視覺效果不錯,但看完之後
我以為我是看 霍元甲2
以這樣的劇情內涵,
它敘說的是不是葉問的故事一點都不重要
因為我只看到視覺上武打特效.
其他部分卻完完全全的乏善可陳
但,
它依舊不失一部可供娛樂的商業電影

2009年6月23日 星期二

取得硬碟序號的方法

硬碟的序號重覆性並不高
所以用來當作防止產品被複製的檢查碼,是有相當的實用價值
以下為取得序號的方式

smartctl -a /dev/hda | grep Serial

以程式截取的方式如下 (qt為例)
QString LinuxSystem::getSerialNumber()
{
struct hd_driveid hd;
int ide;

ide = open("/dev/hda", O_RDONLY);
::ioctl(ide, HDIO_GET_IDENTITY, &hd);
printf("Serial number - %s\n", hd.serial_no);
close(ide);
return QString((const char *)hd.serial_no);
}

xwindow 截取視窗畫面的方法

有時我們在很單純的linux的Xwindow環境中開發程式,
為了寫說明書,常常都需要擷取畫面
以下的指令是很實用的
下了以下的指令後,針對要截取的視窗點一下,即可將畫面儲存下來

xwd | xwdtopnm | pnmtopng > Screenshot.png

如果有缺少的套件,執行下面的指令來安裝必要的套件
yum install netpbm
yum install netpbm-progs

2009年6月6日 星期六

終於把WarcraftIII 的故事模式全破了...雖然遲了好幾年

好感動!
我終於把WarcraftIII (含資料片寒冰霸權)的故事模式全破了..對於我這個做任何事持續力都很差的人來說,能把一個Game全破當然是了不起的成就,當然要記錄起來囉.雖然似乎也沒啥了不起拉^^

2009年6月4日 星期四

POP 普普藝術

1. (初萌發於二十世紀50年代的英國,50年代中期鼎盛於美國) 普普為Popular 的縮寫,意即流行藝術、通俗藝術.
2. 作品中大量運用廢棄物、商品招貼、電影廣告、各種報刊圖片、漫畫做拼貼的組合
3. 以超然的態度歌頌那些被人棄之不顧或已經被人處理過的東西(甚至是複製中的複製)
4. 吸取抽象表現主義的精粹,拓展藝術表現手法。但反對抽象形象,而又重回到具象風格,且畫工極為細膩與明確
5. 是抽象表現主義的反動,描寫日常生活的每一個事物,迫使大家人對週遭事物更加注意。主要描寫廣告招牌,標誌、照片、漫畫等等,與美國的都市文明有關

2009年5月31日 星期日

資訊工程的色彩原理Vs.工業設計的色彩原理

今天上完第一堂課色彩原理的課之後,我發覺這真是一個有趣的課題.
學理工的人習慣把資訊量化,所以建立了許多色彩模型, 如RGB, CMYK,HSB, Lab等等.
但對設計人來說,他們習慣用敘述性的語言去描述Hue(色相), Lighteness(明度), Saturation(彩度),這本是無可厚非.因為他們沒有被訓練量化資訊.但也就因為如此他們也就被訓練出對色彩的敏感度.
設計人常常用色票去溝通顏色,但是其實那是不精確的做法,除非能在相同的光源條件下看色票,不然溝通一定有誤差,當然對有經驗的設計師來說,或許那樣的誤差是可以用經驗來彌補吧?.
設計是一個講求感覺的行為,但不代表那不能被量化
設計師常常抱怨無法和工程師溝通,那是因為他們說著不同的語言
以色彩而言,工程師要的是量化的數值.但設計師給的往往不是如此.
設計是一種藝術,但不但表藝術所有的成分都不能被量化.
設計師除了要培養對藝術的感覺,也要加強對必要資訊量化的技能.
畢竟現在已是一個資訊化的時代.
工業設計曾經經過工業革命的洗禮,現在該是開始要接受新資訊時代的浪潮.

Bauhaus 包浩斯

1. 世界上第一所設計學校
2. 宣言: 一切視覺藝術努力最終目標乃為建築物
3. 發展出 (Point to Line and Plane)的理性分析法
4. Bauhaus 包浩斯課程
  • 工作教育
  1. 石: 雕刻工廠
  2. 玻璃: 玻璃工廠
  3. 木: 木工廠
  4. 色彩: 壁畫工廠
  5. 金屬: 金屬工廠
  6. 紡織: 紡織工廠
  • 型態教育
  1. 觀察: a. 自然研究, b. 材料分析
  2. 表現: a. 幾何學, b. 構成技術, c.設計及模型製作
  3. 構成: a. 空間理論, b.色彩理論, c.設計原理

2009年5月29日 星期五

現代主義 (Modernism)

1. 年代: 1900-1950
2. 特色:

  • 形式提倡非裝飾的簡單幾何概念
  • 功能主義 :
  • 裝飾是罪惡Decoration is sin
  • 形式追隨功能 Form follows function

    『形式追隨功能』法則,可用以下兩者之一的解釋-美感描述或美感傳統。

    『美感描述』的解釋是說,美感來自純粹的功能,沒有其他的裝飾。
    『美感傳統』的解釋是說,設計應注重功能性,美感應該是次要考慮。

    這個法則廣泛地波二十世紀初的現代建築師採用。從此之後,這個法則也被各行的設計師所採用。


    描述解釋-比方說,美感來自純粹的功能-原本是基於自然界中的形式追隨功能信念。但在實際狀況中,這是完全相反的-如果說自然界中有要追隨甚麼的話,那就是功能追隨形式。(演化中的自然淘汰,不會把「意圖」傳給下一代:基因形式只是被傳下來,而每個有機體,必須找到如何使用其形式的方法。)可是,功能性設計跟純美感設計比較起來,是比較沒有那麼主觀的。因此,在品質認定方面,功能性的標準呈現了比較清楚、客觀的標準。結果是比較長久耐用的設計,常被普羅大眾認為是簡單無趣的設計。


    傳統解釋-比如說,設計應注重功能性,美感應該是次要考慮-可能是從描述解釋衍生的。把『形式追隨功能」當做是傳統或設計指導方針會造成問題,因為它讓設計師把
    注意力放在一個錯誤的問題上。這個問題不應該是「哪一方面的形式應該被省略,或是替換成功能?」這個問題應該是「哪一方面的設計,是成功的關鍵?」這些成功的標準,不是對形式或功能的盲目忠誠,而是應該成為設計規格與結論的動力。當時間和資源有限的時候,不管對成功定義為問,設計的替換,應該根據對成功率最小的傷害為準。在特定狀況下,主要的美感考慮會被犧牲。而在其他狀況下,主要的功能會被犧牲。


  • 少就是多 Less is More

建築與設計大師米斯·凡德 洛曾經提出過一句經典設計名言“少即多(less is  more)”,他 主張形式簡單、高度功能化與 理性化的設計理念,反對裝飾化的設計風格,在上個世紀二三十年代,這種極少主義設計風格曾經風靡一時,是西方後現代設計的里程碑,直至今日依然散發 著無限魅力.
以近代產品而言, Apple的產品應為典型之一

小人國遊記

這次遊記分成三個主題,分別是
1. 皓鈞和他的老婆 http://picasaweb.google.com/610823daniel/bkCrpK#
2. 志忠和他的老婆 http://picasaweb.google.com/610823daniel/tAuuY#
3. 丹尼爾沒老婆之燈泡有夠亮... (因為沒有妞..所以也就沒有照片拉@@)

Automake 原理介紹

摘自: http://140.92.88.48/tlog/linux/entry/automake_%E5%8E%9F%E7%90%86%E4%BB%8B%E7%B4%B9
by 鄭治中 in Linux驅動程式開發

Automake 原理介紹

使用 Automake產生 Makefile 的過程和以往自行編寫的方式非常不一樣,只需定義一些用到的巨集即可。

我 們把巨集及目標 (target) 寫在 Makefile.am 檔內,Automake讀入 Makefile.am 檔後會把這一串已經定義好的巨集展開並且產生對應的Makefile.in 檔, 然後再由 configure 這個 shell script 根據Makefile.in 產生適合的 Makefile。

這篇簡介是 Autoconf 及 Automake 的入門,希望這篇檔能幫助你對產生 Makefile有個簡單的依據。其他有關開發 GNU 程式或 C 程式設計及 Makefile 的詳細運用及技巧,我建議你從 GNU Coding Standards3 (GNU 編碼標準規定) 讀起,裏面包含了 GNU Makefile 慣例,還有發展 GNU 軟體套件的標準程式和慣例。這些 GNU 軟體的線上說明文件可以在 http://www.gnu.org/ 這個網站上找到。

1. 編輯 configure.in 檔

configure.in 檔的內容是一連串 GNU m4 的巨集,這些巨集經過autoconf 處理後會變成檢查系統特徵的 shell script。

我們可先用 autoscan 掃描原始檔以產生一個 configure.scan 檔,再對 configure.scan 做些修改成 configure.in 檔。

configure.in 內必須以 AC_INIT 巨集開頭,以AC_OUTPUT 巨集結尾。中間定義多個使用者自定巨集 (User Defined Micro),使用者自定巨集的順序沒有規定。

configure.in常用的範例巨集如下:

dnl

為注解,這個巨集後面的字不會被處理。

AC_INIT(FILE)

這個巨集用來檢查原始碼所在的路徑,autoscan 會自動產生,我們不必修改它。

AM_INIT_AUTOMAKE(PACKAGE,VERSION)

PACKAGE 是我們所要產生軟體套件的名稱,VERSION 是版本編號。

AC_PROG_CC

檢查系統可用的 C 編譯器,如果原始程式是用 C 寫的就需要這個巨集。

AC_OUTPUT(FILE)

設定 configure 所要產生的檔案,如果是 Makefile 的話,configure 便會把它檢查出來的結果帶入 Makefile.in 檔然後產生合適的 Makefile。

2. 產生 aclocol.mr 檔

實 際上,我們使用 Automake 時,還須要一些其他的巨集,這些額外的巨集我們用 aclocal 來幫我們產生。執行 aclocal 會產生 aclocal.m4 檔,如果沒有特別的用途,我們可以不必修改它,用 aclocal 所產生的巨集會告訴 Automake 怎麽做。

3. 產生 configure 檔

有了 configure.in 及 aclocal.m4 兩個檔案後,便可以執行 autoconf來產生 configure 檔了。

Autoconf 是用來產生 'configure' 檔的工具。'configure' 是一個shell script,它可以自動設定原始程式以符合各種不同平臺上 Unix 系統的特性,並且根據系統三數及環境產生合適的 Makefile 檔或是C 的標頭檔 (header file),讓原始程式可以很方便地在這些不同的平臺上被編譯出來。Autoconf 會讀取 configure.in 檔然後產生 'configure' 這個shell script。

4. 編輯 Makefile.am 檔

接下來我們要編輯 Makefile.am 檔,Automake 會根據 configure.in 中的巨集把Makefile.am 轉成 Makefile.in 檔。Makefile.am 檔定義我們所要產的目標:

AUTOMAKE_OPTIONS

Automake 主要是幫助開發 GNU 軟體的人員維護軟體套件,所以在執行 automake 時,會檢查目錄下是否存在標準 GNU 軟體套件中應具備的檔檔案,例如 'NEWS'、'AUTHOR'、'ChangeLog' 等文件檔。

設成 foreign 時,automake 會改用一般軟體套件的標準來檢查。

bin_PROGRAMS

定義我們所要產生的執行檔檔名。如果要產生多個執行檔,每個檔名用空白字元隔開。

hello_SOURCES

定義執行檔所需要的原始檔。

如果 'hello' 這個程式是由多個原始檔所產生,必須把它所用到的原始檔都列出來,以空白字元隔開。

5. 產生Makefile.in

Automake 產生出來的 Makefile.in檔是完全符合 GNU Makefile 的慣例,我們只要執行 configure 這個shell script 便可以產生合適的 Makefile 檔了。

# automake --add-missing

加上 --add-missing 選項是告訴 automake 順便幫我們加入包裝一個軟體套件所必備的檔案。

6.使用 Makefile

執行 ./configure,利用 configure 產生Makefile 檔。

要 注意的是,利用 Autoconf 及 Automake 所產生出來的軟體套件是可以在沒有安裝 Autoconf 及 Automake 的環境上使用的,因為 configure 是一個 shell script,它己被設計可以在一般 Unix 的 sh 這個 shell 下執行。但是如果要修改 configure.in 及 Makefile.am 檔再產生新的configure 及 Makefile.in 檔時就一定要有 Autoconf 及 Automake 了。

Autoconf 和 Automake 功能十分強大,你可以從它們所附的 info 檔找到詳細的用法。你也可以從許多現存的 GNU 軟體或 Open Source 軟體中找到相關的 configure.in 或 Makefile.am 檔,它們是學習 Autoconf 及Automake 更多技巧的最佳範例。

Create Makefile

摘自: http://140.92.88.48/tlog/linux/entry/create_makefile
by 鄭治中 in Linux驅動程式開發

Create Makefile

在 Linux 上寫程式的人大概都要使用 Makefile執行編譯程式的工作,可是要寫出一個 Makefile就不簡單了。網路上介紹 Makefile 的資源很多,可是要變成高手並不容易,難怪許多人聞 Linux 色變。本文將介紹如兩套軟體來協助我們『自動』產生 Makefile 檔: GNU Autoconf 及 Automake

讓開發出來的軟體可以像一般常見的 GNU 軟體一樣,只要用 ``./configure'', ``make all'',``make install'' 就可以完成compile和install的動作。

希望這份簡介能幫助您輕鬆地進入 Linux Programming 的殿堂。

1. 上路之前

程 式設計師只需寫一些預先定義好的巨集 (macro),交給 Automake 處理後會產生一個可供 Autoconf 使用的 Makefile.in 檔。再配合利用Autoconf 產生的自動設定檔 configure 即可產生一份符合 GNU Makefile慣例的 Makeifle 了。

在開始試著用 Automake 之前,請先確認你的系統已經安裝以下的軟體:

l GNU Automake

l GNU Autoconf

l GNU m4

l perl

l GNU Libtool (如果你需要產生 shared library)

我會建議你最好也使用 GNU C/C++ 編譯器、GNU Make 以及其他 GNU 的工具程式來做為開發的環境,這些工具都是屬於 Open Source Software不僅免費而且功能強大。

2. 一個簡單的例子

Automake 所產生的 Makefile 除了可以做到程式的編譯和連結,還把產生相關資源檔 (如 manual page及 info 檔) 都考慮進去。所以原始程式所存放的目錄架構最好符合 GNU 的標準慣例,接下來我拿 hello.c 來做為例子。

在工作目錄下建立一個新的子目錄 ``devel'',再在 devel 下建立一個``hello'' 的子目錄,我們的程式及其相關檔案存放在 ./devel/hello 目錄下:

# mkdir devel

# cd devel

# mkdir hello

# cd hello

用編輯器寫好 hello.c 檔

#include

int main(int argc, char** argv)

{

printf(``Hello world!\n'');

return 0;

}

接下來就要用 Autoconf 及 Automake 來幫我們產生 Makefile 檔了,

2.1. 產生一個 configure.scan 的檔案

執行 autoscan 後會產生一個configure.scan 的檔案,可以用它做為 configure.in檔的原型。

# autoscan

# ls

configure.scan hello.c

2.2. 產生一個 configure.in 的檔案

編輯 configure.scan 檔,並且把它的檔名改成 configure.in, 修改資料內容如下:

dnl Process this file with autoconf to produce a configure script.

AC_INIT(hello.c)

AM_INIT_AUTOMAKE(hello, 1.0)

dnl Checks for programs.

AC_PROG_CC

dnl Checks for libraries.

dnl Checks for header files.

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.

AC_OUTPUT(Makefile)

2.3. 產生 aclocal.m4檔案

執行 aclocal會產生GNU m4 的巨集到aclocal.m4

# aclocal

2.4. 產生 configure檔案

執行 autoconf,Autoconf 會讀取 configure.in 檔然後產生 'configure' 這個shell script。

# autoconf

2.5. 產生 Makefile.in檔案

接下來我們要編輯 Makefile.am 檔,Automake 會根據 configure.in 中的巨集把Makefile.am 轉成 Makefile.in 檔。

Makefile.am內容

AUTOMAKE_OPTIONS= foreign

bin_PROGRAMS= hello

hello_SOURCES= hello.c

這個程式需要 'hello.c'、'main.c'、'hello.h' 三個檔案的話,則定義 hello_SOURCES= hello.c main.c hello.h 如果我們定義多個執行檔,則對每個執行檔都要定義相對的filename_SOURCES。

Automake 會根據 Makefile.am 檔產生一些檔案,包含最重要的 Makefile.in

# automake --add-missing

automake: configure.in: installing `./install-sh'

automake: configure.in: installing `./mkinstalldirs'

automake: configure.in: installing `./missing'

2.6. 最後執行 ./configure

# ./configure

creating cache ./config.cache

checking for a BSD compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

checking whether make sets ${MAKE}... yes

checking for working aclocal... found

checking for working autoconf... found

checking for working automake... found

checking for working autoheader... found

checking for working makeinfo... found

checking for gcc... gcc

checking whether the C compiler (gcc ) works... yes

checking whether the C compiler (gcc ) is a cross-compiler... no

checking whether we are using GNU C... yes

checking whether gcc accepts -g... yes

updating cache ./config.cache

creating ./config.status

creating Makefile

現在你的目錄下已經產生了一個 Makefile 檔,下個 ``make'' 指令就可以開始編譯 hello.c 成執行檔。你還可以試試 ``make clean'',''make install'',''make dist'' 看看會有什麽結果。

# make

gcc -DPACKAGE=\"hello\" -DVERSION=\"1.0\" -I. -I. -g -O2 -c hello.c

gcc -g -O2 -o hello hello.o

# ./hello

Hello! GNU!

2009年5月23日 星期六

送行者:禮儀師的樂章


一個灰色的故事,卻表現出那麼不凡的色彩.
一部不會催淚的電影,卻讓每個人在內心深處動容.

只是,對於片中男主角心境著墨太少,也不夠深刻.是我認為美中不足的地方.

2009年5月22日 星期五

裝飾藝術 (Art Deco)

1. 年代: 1929-1939
2. 代表設計師: Tamara de Lempicka










3. 代表電影:
Sky Captain and World of Tomorrow (明日世界)






Batman (蝙蝠俠)













4. 代表城市: New York













5. 特色
  • 「裝飾藝術」運動是對「新藝術」運動的一種反動。「新藝術」強調中世紀的、哥德式的、自然風格的裝飾,強調手工藝的美、否定機械化時代特徵;而「裝飾藝術」運動恰恰是反對古典主義的、自然(特別是有機型態)的、單純手工藝趨向,而主張機械化的美,因而「裝飾藝術」風格更具有積極的時代意義。
  • 「裝飾藝術」運動風格在形式上受到幾個特別因素的影響:
  1. 埃及等古代裝飾風格的影響:古埃及時代非常普遍的建築裝飾圖案,如盛開的紙草和蓮花圖形,都是簡單明快地從自然抽象出來的幾何圖案加以變形處理,相當壯觀。
  2. 裝飾藝術的表現,大都有傾向抽象的風格。
  3. 原始藝術的影響:非洲部落舞蹈面具的象徵性和誇張特點,非洲木雕的明快簡鍊,都給了西方藝術家和設計師們很大的啟發
  4. 簡單幾何型研究:常用的幾何型包括陽光放射型、閃電型、曲折型、重疊箭頭型,星星閃爍型,埃及金字塔型等
  5. 舞台藝術的影響:
  6. 機器的影響:二十世紀是機器的時代,裝飾藝術是和時代脈動同呼吸的,因此自然會擷取機器的觀點做為創作靈感
  7. 具有鮮明強烈的色彩特徵,特別重視強烈的原色和金屬色彩。
    常用的顏色包括鮮紅、鮮藍、鮮藍、橘紅和金屬色系列(包括古銅、金、銀等色彩。)

2009年5月20日 星期三

新藝術運動 (Art Nouveau)

1.年代: 1890-1905
2.代表人物: Mucha
3.特點:
  • 以自然中的動植物與女性曲線為創作內涵的裝飾風格與圖案為主體的自由藝術式樣,以別於傳統式樣,其曲線大多為細長而捲起的蔓草模樣或花卉、鳥獸、藤鞭似的型態,再配以華麗的色彩,此種以象徵和浪漫的手法 為主導,採取生動優美的浪漫形線條的表現手法塑造出一個全新的造形風格,也使新藝術運動所製作的各類產品有著重裝飾趣味的傾向
  • 新藝術運動沒有像某些其它運動(例如:工藝美術運動)那樣否定機器的作用,而是發揮其所長。
  • 認為在新的世紀裡即要創造符合時代潮流的新藝術形態。從工業革命中可以找尋到一些屬於新藝術風格形式的特徵。有些藝術家非常鼓勵工藝的創作和尋找新的材料 作為藝術另一種新的詮釋,例如鑄鐵。有些藝術家對於機器化大量製造的劣質產品感到痛惜,於是將目標著重於裝飾性藝術,對每一件物品都是追求技藝上和設計方 面的高水準。

2009年5月17日 星期日

美術工藝運動 (The Arts and Crafts Movement)

1. 年代: 1850-1900
2. 代表人物: William Morris
3. 特徵:
  • 強調手工藝,反對機械化的生產
  • 在裝飾上反對嬌柔造作的維多利亞風格和其他古典、傳統的復興風格
  • 提倡哥德風格和其他中世紀的風格講究簡單、樸實無華、良好功能
  • 主張設計上的誠實、誠懇,反對設計上的華眾取寵、華而不實
  • 裝飾上推崇自然主義、東方裝飾和東方藝術的特點
4. 作品

2009年3月7日 星期六

你為什麼交不到女朋友

閒來無事,在網路中閒逛..無意間看到這篇文章 (摘自 http://www.wretch.cc/blog/illyqueen/12056375)
深深的吸引了我...順便貼出來跟大家分享^^

此文是寫給非常渴望交女友,但總是碰壁被發好人卡或是被當火山孝子,每個女人跟你說:「對不起,你真的很 好,我們當朋友就好,我現在還不想交男朋友。」但總是說完不久就挽著新男友。你很哀怨,不知道自己到底哪裡出了問題,你問你身邊的女性好友,她們總是安慰 你:「沒關係,是她不識貨!」可是她們也沒人想「試貨」。你的哥兒們跟你說:「堂堂男子漢,單身多自由,幹嘛談戀愛!(賤ㄟ)」可是他們都有一個或以上的 女友。

(= =凸!)

你在心裡吶喊:「X!我也好想交女朋友!」

在此說明清楚本文的target族群,如果你是崇尚單身不近女色,一點也不想交女友,或是自信十足覺得老子條件太好眼光太高不擔心交不到女友,也請按上一頁離開。其他想看的人,那就來吧。

***

不願面對的真相之一,你真的不帥

如同「為什麼她交不到男友?」的第一項「你真的不美」,對不起,我再說一次,說外表不重要都是善意的謊言。但是,男人跟女人比較起來,男人還是比較視覺的 動物,所以女人對於男人的外表的要求,其實並沒有像男人要求女人一樣嚴苛,這就是為什麼你可以看到很多正妹的男友都不一定是大帥哥,但是大帥哥的女友通常 都一定是正妹。

很多女生都說:「我真的不重視外表。」這句話的翻譯是:「我真的不愛帥哥,但是太醜的我無法接受。」她們說:「感覺比較重要,順眼比較重要。」沒錯,不帥的男人一樣可以讓女人有感覺、看的順眼。甚至有女人說:「我不喜歡帥哥,帥哥都很花。」

很煩耶,你們女人到底愛帥哥還是不愛帥哥?

女人說:
「帥哥美女當然人人愛,女人當然愛帥哥,不然帥哥哪吃得開!但是,也有很多不帥的男生也照樣吃得開啊!所以重點不是在那個臉蛋有多帥,以前流行大 眼漫畫男,現在小眼性格男也受歡迎,所以重點是在『性格』,以前周杰倫一出道我真的覺得他不好看,但是現在越看越帥女人緣好的要死,難道是他眼睛變大還是 整過形嗎?所以一個男人有沒有自己的型,有沒有找到自己的路線很重要。」

「女人所謂的帥其實是很整體、很概念性的認知,不一定長的好看就叫做帥,我們會為了男人的某些特點而覺得他帥,譬如他很有才華、很會唱歌、很會下 廚、很有禮貌、很會穿衣服、很會開車、很有能力、很有個性,很貼心很可愛很紳士,而覺得他很帥。所以我覺得這些覺得長的不好看的男人,要對自己的『長處』 有自信,妳也知道,有自信的男人最迷人,認真的男人最帥氣!」

「但是我很受不了有些男生因為自知長的不好就任由自己自生自滅,整天蓬頭垢面、衣服不穿好也不洗,鼻毛不剪、頭髮不洗、腳指甲很黑腳臭又愛穿拖 鞋,他們覺得不用打扮自己反正也不是帥哥。然後去指責女生重視外表膚淺,可是他們不照照鏡子看看自己是什麼樣子,如果他是女生會想跟自己約會嗎?」

「對啊,你們從來不用心自己的外表,我不是說要穿名牌行頭過度打扮不像自己,但是,基本的整齊清潔是做人基本的禮貌,如果你interview別人會看第一眼印象,女生看到你也會有第一眼印象啊!」

「而且很多受女生歡迎的男生都不是帥哥唷,妳去注意那些男生的外表,他們一定捨得投資幾件適合他們又質感好的衣服鞋子包包,他們知道看場合穿衣 服,他們不太會讓女人覺得傻眼錯愕。比較起來,女生就算天生不美,但都懂得去打扮自己,可是男生對這部分真的落後女生很多,所謂沒有醜女人只有懶女人,我 覺得也適用於男人,沒有醜男人,只有懶男人!」

以上是比較好聽一點的,我還有聽過朋友更慘的例子,有個朋友因為不愛帥哥所以交過一個其貌不揚年紀大她十歲,體重是她兩倍的男友,但是當她與男友甜蜜的走在路上時被朋友看到,朋友卻誤以為她在搞援交還是被包養:「XXX,妳是想不開嗎?」

另一個美女朋友有天把曖昧對象帶來給姊妹淘認識,本來姊妹淘滿心期待興奮不已,結果該男一出現馬上冷場直到退場。姊妹淘尷尬的跟她說:「老實說,我覺得...他配不上妳耶!」

很多美女老實說,只要這個男生很好,她們是可以忽略他的外表,但是她們卻遭人白眼:「妳男友這麼醜,是不是因為他很有錢?」,但是也有女生說:「長的帥會花心,長的不帥也會偷吃,那我不如跟長的帥的在一起。」

唉,會不會太淒涼了一點。

不願面對的真相之二,只會跟電腦講話,不會跟真人聊天

對不起,各位宅男,女王在此向大家深深一鞠躬。因為實在有太多女生受不了只會對電腦講話,上網聊天,但是卻不知道怎麼跟真人聊天的人。這種男生大 多在網路上幽默風趣,聊起天來滔滔不絕,發表文章頭頭是道,耍賤搞笑絕對不輸電視上的諧星,但是妳一看到他的照片,一見到他的本人,再跟他聊兩句話,妳會 錯亂他到底是不是妳在網路上認識那個人。

女人說:
「唉,我就曾經遇過一個心儀的男生,在網路上聊了半年幾乎把對方當作心靈伴侶、男女朋友,怎知好不容易見了面,我卻要一直找話題聊,最後他說,我 們還是回去上網再聊吧!天阿~後來我就不想再跟他聊天了,如果我跟他在一起我們約會要一人帶一台Notebook去找餐廳無線上網還是去網喀聊天嗎?」

「其實也不能怪他們,向我在竹科工作,我工程師男同事他們從以前念理組就都是男生,晚上也只會在宿舍上網,沒事只喜歡打電動根本不想出門,上了班 每天工作超過10個小時都是坐在電腦前,電腦就是他們的生活、他們的愛人,就算妳坐他們旁邊,他們寧可用msn跟妳聊天也不想開口跟妳講話,我想,除非是 也很喜歡每天坐在電腦前超過10個小時還剛好喜歡跟他們一起『練功』的女生,才能跟他們溝通!」

「什麼是練功我真的不知道,上次有個男的說什麼要給我寶物,還跟我講了一堆電玩術語,可惜我是個連手機遊戲都不玩的人,我真的感謝Wii」的發明,至少讓我覺得我的世界可以跟他溝通,但是他說還是喜歡練功。」

「對啊,我就很怕那種網路上很帥氣的男生,出來卻不知怎麼渾身不自在的連正眼看妳都不敢,跟他講話他總是對著天花板、地板或隔壁桌講話,讓我很不爽!」

說真的,女王我也一天到晚蹲在電腦前,每天都在跟人打字聊天,有時候懶的出門真的可以在家邋遢一整天,唉!其實我也是個宅女,所以宅男們通通是我的好朋友,但是我都會硬逼身邊宅男出來聚會,畢竟,要多多跟人群接觸才不會讓自己日趨宅化。(我也是這樣警惕自己)




不願面對的真相之三,害怕被拒絕而顯的沒自信

這年頭的男人不知怎麼了,很多都比女生膽小、不主動、不積極,後來我發現他們是害怕被拒絕。所以他們非常被動,太過小心翼翼,比女人還矜持,搞的 女生很火大:「靠!是我太man了嗎?」親愛的男人,跟你們說句真心話,我們女人瞧得起一個被拒絕但是很勇敢的男人,也勝過一個沒種的男人!我們會跟前者 做朋友,但不會給後者任何一個機會。

女人說:
「我不懂,現在的男生在娘什麼?明明要追女生還在那邊觀望、裝害羞、裝矜持,難道你要我主動約你吃飯,問你要去哪一家餐廳比較好嗎?反正你都要追女生了,為什麼不拿出一點男子氣概來,我真的遇到那種很娘的,本來喜歡他也會整個冷掉。」

「我最怕那種太小心翼翼的男生,我知道他們是好人、個性好、有禮貌,所以跟他出去他什麼事情都緊張兮兮怕你不高興,搞的女生更不自在,害我們要一 直演國民社交禮儀,好累!拜託,這樣跟你出去兩次我就累了,難道在一個花好月圓的情況下,還要我先問『我可以摸你嗎?』,親愛的,矜持給我裝就好了,你不 必比我會裝!」

「還有的男生問他想去哪、想吃啥、想看什麼電影,他都說妳高興就好。喂,我並不想跟一個太監在一起,我又不是慈禧太后,我不要那種一直在旁邊卑躬屈膝唯唯諾諾的男人!」

「我覺得男生要勇敢一點,被拒絕又怎樣,我們女生根本不會看不起被我們拒絕的男生,我們還挺『以被你追求為傲』的呢!但是我們超討厭那種想追又一 臉『我一定會被拒絕』的悲情男,好像我是負心女,說真的,沒自信的男人在一開始就輸定了,就算我一開始對你有好感也會消失殆盡。」

不願面對的真相之四,成也msn,敗也msn!

msn可謂是把妹的最佳工具,更是女王所謂「進可攻、退可守,沒事可封鎖」的現代科技偉大發明,但是,有不少男人被女生宣判死刑,不想跟你見面也懶的跟你聊天,甚至原本對你的好感全消,到底是哪裡出了問題?

女人說:
「我最受不了那種一句話要分五句話講的男人,或是一段話要分好幾句打的男人,搞的我要一直點視窗出來看,讓我很沒耐性。嗨、你好、美女、在嗎、最 近忙嗎、想跟你聊一下、不知妳有沒有空、最近忙什麼?.....以上這段總共分七次丟,難道他是有表達障礙還是愛問問題強迫症?shit!老娘很忙,沒空 每次上線就要跟你報告近況,還要看你一直丟問題,你不累我也會累!」

「還有,沒事愛用一堆表情符號,還愛用表情符號代替字,所以每當他說一句話,我就要去猜中間出現的五個表情符號代表什麼國字,馬的!真的很難閱讀耶,是男人就不要給我在那邊一直裝可愛,表情符號不是這樣用的,你真的以為我都看的懂你哪個符號代表哪個字嗎?」

「沒錯,我也覺得太愛用表情符號的男人很不man!我還是喜歡打字『乾爽』一點的男生,喔!還有,愛用注音文或故意愛用錯別字裝可愛的男生我也很受不了,男人愛用注音文,真的很不man!馬的,連字都打不好真的會讓我懷疑你的智商。」

「最讓我無名火一把冒上來的是那種在msn上很沒禮貌的男生,只要上線遇到你就一定要跟你聊天,也沒看到我都掛忙碌,也跟你說我很忙了,你是聽不 懂嗎?還有那種一直跟你要照片的變態,我幹嘛沒事傳照片給你打手槍?最討厭那種只要你一換暱稱就要一直追問你心情不好嗎?發生什麼事情?很抱歉那真的只是 歌詞。

不願面對的真相之五,沒主見的男人

這年頭的女生真的很討厭沒主見的男人,你問他什麼他都說:「隨便!」出門不帶大腦,做事不擬草稿,你以為說一句隨便我們也跟你一起隨便嗎?

女人說:
「我最討厭要約你出去還要你想地點,他自以為很尊重女性,所以他不敢做任何決定,你問他:『好吧,那我們去吃XX好了。』他說:『隨便啊!都可以啊!看你啊!』看你老師,這麼隨便就不要出來把妹!」

「所以男生平常真的要多做功課,才不會要把妹才發現自己不知道要去哪約會,哪裡有好吃的餐廳、哪裡好停車、哪裡看電影一定買的到票、哪裡最有氣 氛,當她說:『我最喜歡吃XX』你就能說:『我知道哪裡有好吃的XX,我帶你去!』唉,但是很多男生都不會做功課,只有到把妹的時才上網求救。」

「我不知道為什麼現在的男生都很沒主見,一點也不man!好像跟他在一起很多事情還要我幫他想辦法,沒辦法作決定、沒肩膀承擔責任,連要把妹開口表白都不敢,人家問你是不是喜歡哪個女生你也不敢承認你想追她,因為你怕追不到很丟臉。那不然現在是要怎樣?」

「我覺得男生要約女生,他們當然要事先做好計畫,要吃飯一定要先訂位,甚至規劃好路線避免塞車等太久,不要約難找的地方,這是最基本的禮貌吧!不 要連要去哪都不知道,陪你塞車又繞好幾圈找不到車位,好不容易找到餐廳結果沒位還要排隊,你說,就算我對你多有好感也瞬間down到最低點。」

不願面對的真相之六,林志玲才不會看上你

女王我曾遇過幾個男生,當我好心的問他們擇偶標準、喜歡什麼樣的女生時,他們說:「我最喜歡林志玲,真希望可以遇到像林志玲那類的女生!」當場我的笑容僵住,心中OS:「你們這些男人到現在交不到女朋友,不是沒有道理的!」

女人說:
「對啊,叫那些男人醒醒吧,我最受不了那種男生要我幫他介紹女友,還傳一堆美女照片給我指明這是他喜歡的型,我真的很不想澆他冷水跟他說實話: 『這種美女不會看上你的』幫他介紹女生還一直嫌別人不夠正,天曉得他跟那女生站在一起別人一定會覺得是鮮花插在牛糞,我真的很訝異為什麼牛糞還可以嫌別 人?」

「對啊,他們要女生胸部大、腿要細,屁股不能大,有點小腹就嫌人家胖,但是他們自己脫了能看嗎?你是有胸肌、腹肌還是腿長屁股翹?我不懂那些愛惡意批評女生身材的男人,你們這些男人到底是誰的身材能看啊?!」

「而且我真的遇過很多真的很恐怖的醜男要我介紹正妹朋友給他認識耶,天啊!我才不想殘害我自己的朋友!我真的覺得那些男人都有『正妹病』,每天上網看正妹相簿,然後認識女生都非正妹不要,知道妳有正妹朋友就一直要你介紹,長得太普通的又不要!」

「沒錯,我真的很想告訴他們,正妹不會看上你的。你知道他們為什麼總領好人卡嗎?因為他們只要一看到正妹就不管三七二十一大獻殷勤,正妹也不是傻瓜,她們每天要應付這麼多自願當好人的人,而且她們也很瞭你接近她也只是因為她很正,她給你好人卡已經算很仁慈了。」

不願面對的真相之七,你真的沒那麼屌!

當我開始寫這篇文章的時候,好幾個女生要求我一定要寫這一點,她們真是受不了太愛吹噓自己,老是裝闊、裝聰明,說謊不打草稿,又愛自以為很屌,總是說自己認識xxx,就是怕別人不知道他很行!

女人說:
「我最受不了這種男生,他們以為女生都是白癡都看不出來,其實我們只是不好意思拆你的台。不懂就不要裝懂,沒有錢也不用擺闊,我還遇過男生假裝自己是小開,說什麼公司是他們家的,拜託,人家也是會查的,被發現真的很糗耶!」

「還有一種男生愛裝懂,愛裝有品味,以為買幾個名牌、點最貴的酒、買幾張音樂大合輯就是有品味,唉!不然就是說什麼餐廳他很常去,哪一家老闆跟他很熟,結果你隨便一問他就答不出來。」

「有的男生很愛吹噓自己有多強、床上多厲害,結果我發現越愛講的其實都越差,只是打的一嘴好砲!我在想他們以前的女友大概都是演技派的善心人士。」

「我覺得男人誠實最上策,我們反而會覺得你很真誠、很好相處沒壓力。更何況大話說久了真的會有破功的一天,現在的女生沒那麼笨,我們只是不好意思戳破你的謊言罷了。」

不願面對的真相之八,我真的和你沒話聊!

很多男生不懂,有些話題是大部分女生不會感興趣的,譬如說:當兵、改車、球賽、寫程式或是某些宅男圈的語言,我只是舉例,或許你運氣好可以遇到喜歡聊當兵、改車、球賽、寫程式等話題的女生,不過,你的運氣真的要很好。

女人說:
「有些男生就很愛聊這些話題,也不管我們女生有沒有興趣,就自顧自的要跟你分享。而且我最受不了幾個男生一聊當兵就以為我們女生很愛聽,天啊!各位男士請醒醒,我們女人真的對你當兵的事一點興趣也沒有。」

「我也遇過一位工程師長的又帥又會打扮人又nice,正當我要顛覆我對他們的刻板印象,他居然開始講起網路宅男圈的術語,譬如說我們幾個人聊一個 話題很開心,他突然講了一句:『丁丁是個人才』然後自己很嗨的在那邊大笑,現場如同一陣烏鴉飛過去每個人臉上三條斜線,不知道該怎麼接話。唉!我只能說我 們的世界真的很不同,我真的進不了他的圈子。」

「我也怕改車狂,我遇過兩三個改車狂,說真的我尊重你的嗜好,但是他們跟我出去就一直聊他的車,他要換什麼,然後一直問我:『車子亮不亮?底盤換 了坐起來有沒有不一樣?車子好像有雜音有沒有聽到?你看我這個避震器好不好?你知道我換這個花了幾萬塊嗎....』然後最後因為他的車子改太低找不到停車 場可以停車,所以約會被迫結束。害我現在聽到男生說『我想要改車』我就會怕。」

「我覺得啦,很多女生願意跟男友去看球賽都不是真的喜歡球賽,她們是因為男友愛而陪他,他們連啥球賽規則都不懂。所以男生會以為他女友也是真心喜 愛看球賽,所以每次約會都去看球賽,唉!或許真的有的女生是天生熱愛球賽,但男人永遠分不清楚女生是真心喜歡,還是只假裝喜歡。」

所以男生真的平常要多留意女生喜歡的東西,不要老是聊自己的事,當你發現女生的msn回應只剩下一到兩個字,和你講話開始看手錶,注意路人甲,請 馬上切換話題,最好的方式不如問她問題,問她喜歡什麼、對什麼事情的看法...,然後再從她的回答找到話題聊。要把妹前請找女性友人多多練習。


不願面對的真相之九,你還是回家看A片吧!

很多男人A片看了太多,看到誤以為A片就是真實世界,AV女優就像路邊的正妹、認識的學妹、隔壁桌的同事,他們遇到覺得不錯、有點喜歡的女生就馬上露出看A片的表情(請你下次看A片的時候放一面鏡子在旁邊看自己的臉),難道你們以為女生看不出來你的腦袋在想什麼嗎?

女人說:
「我最受不了那種一來搭訕的男生一臉就寫著:『我好想上妳』的表情,馬的!我真的覺得被他多看一眼就像視覺強暴,有夠噁心!」

「有的男生才剛認識就一副好像幾百年沒碰過女人,想盡辦法跟你要電話送妳回家,順便不小心碰到妳幾下,走路還要不小心攬你的腰,這位先生,我自己可以走路不用你扶我,下次坐我旁邊請不要靠這麼近,我知道你很飢渴,但是你再靠近我,我一定賞你耳光!」

「我真的很討厭愛吃豆腐的男生,而且他們都不知道他在吃誰的豆腐其實我們女生都看在眼裡。所以那些假借吃豆腐示愛的男生根本不會有女生要理他,你以為我願意跟你出來吃飯就代表你可以勾肩搭背嗎?你以為摸兩下我沒有馬上把你推開就代表我願意跟你在一起嗎?」

「有些男生真的一臉寫著他很色,他在追你的時候隨時都保持著『妳就是我性幻想對象』的好色表情,他們以為我們女人是瞎子看不出來你心有邪念嗎?我們知道自己很性感,但我們並不一定要當你的性幻想對象!」

2009年2月5日 星期四

GCC 的使用

目前的工作是在Linux的環境中寫程式,自然也就免不了要使用gcc
怕自己忘記該如何使用gcc, 所以就在網路上搜尋一下使用方式的文章,並貼出來跟大家分享.


GCC 的使用
簡介:
GCC 是由 GNU 出的 C 語言編譯器,可將由 ANSI C 或 traditional C 語言寫成的程式碼編譯成可執行檔。由於 GCC 能分別編譯出可執行於許多不同硬體、作業系統下的程式,在 UNIX 系統上是相當多人常用的 C 語言編譯程式。
使用方法簡介

基本的使用方法及常用指令
前言
編譯器在編譯過程中,先將程式碼編譯成 object 檔,然後再和程式庫聯結,成為可執行檔。故一個編譯器須提供的參數主要有幾類:
指定編譯器編出的 object 檔或是可執行檔檔名。
在編譯過程做最佳化,可提升程式的執行速度。
設定搜尋程式庫的標頭檔 (header file) 及程式庫檔的目錄及指定程式庫檔檔名。
提供進一步的資訊以便使用者找尋程式中的錯誤。
以下便以這四個大類分別介紹。
注意:下面在不同類別中所介紹的參數,幾乎都可以混合著使用。

設定編譯出的 object 檔檔名或是可執行檔檔名:
參數: -o out_put_filename
說明: 指定編譯出的檔名為 out_put_filename。

範例: 本例將程式碼 'test.c' 編譯成可執行檔,並設定檔名為 'test'。

gcc test.c -o test

在編譯過程做最佳化
參數: -O
說明: 在編譯過程做最佳化,以提升增快程式執行速度。

範例:本例將程式碼 'test.c' 編譯成可執行檔 'test',並在編譯過程做最佳化'。

gcc -O test.c -o test

設定搜尋標頭檔目錄、程式庫檔的目錄及指定程式庫檔。

設定搜尋標頭檔目錄
參數: -Idir_name
說明: 將目錄 'dir_name' 設定為搜尋標頭檔目錄之一。


設定搜尋程式庫目錄。
參數: -Ldir_name
說明: 將目錄 'dir_name' 設定為搜尋程式庫目錄之一。


設定程式庫檔案。

參數: -lname
說明: 聯結程式庫 libname.a 。

範例一:本例中假設你的程式檔名為test.c,數學函數如 sin等,所要聯結的程式庫為 libm.a。

gcc -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 test.c -o test

範例二:本例中假設你的程式檔名為 test.c,使用到 X window 函數,所需的 include 檔放在 /usr/X11R6/include 中,所須聯結的程式庫放在 /usr/X11R6/lib,所要聯結的程式庫為 libX11.a。
gcc -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 test.c -o test

提供進一步的資訊以便使用者找尋程式中的錯誤。
參數: -Wall

說明: 輸出較多的警告訊息,以便找出程式的錯誤。

範例: 編譯 test.c 時輸出較多的警告訊息。

gcc -Wall test.c

參數: -g

說明: 在編譯出可執行檔時,附加執行時除錯資訊,以供 gdb 讀取 (若要使用 ABSoft 的除錯程式,則須將參數改為 -gdwarf )。

範例: 將 'test.c' 編譯成可執行檔 'test',並附加除錯資訊。

gcc -g test.c -o test



進階參數
1. 僅編譯成 object 檔。
參數: -c

說明: 僅編譯成 object 檔而不進行程式庫聯結。

範例: 將 test.c 編譯成 object 檔 test.o。

gcc -c test.c -o test.o

2. 聯結數個 object 成可執行檔。

範例: 將 'test1.o'、'test2.o' 和程式庫聯結後成為可執行檔 test。

gcc test1.o test2.o -o test

3. 觀察巨集展開情形:

參數: -E

說明:展開程式中的巨集以便了解巨集是否依照預期方式展開。

範例:將 test1.c 中的巨集展開後儲存到 test1.c.ext 。

gcc -E test1.c > test1.c.ext

4. 產生組合語言程式碼:

參數: -S

範例:編譯 test.c 產生對應的組合語言程式碼檔 test.s。

gcc -S test.c -o test.s

編譯參數列表 -o out_put_filename 將編譯後產生的檔名設為 out_put_filename
-O 編譯時做最佳化,以增加程式執行效率。
-c 將原始語言編譯成 .o 檔(object檔) 不做程式庫連結的工作。
-g 編譯出 .o 檔時,保留除錯的資訊,在連結後產生的可執行檔中包含 gdb 需要的資訊。(若要給 ABSoft 的除錯程式使用,須將此參數改為 -gdwarg )
-E 將原始語言編譯將 test.c 中的巨集展開,之後輸出到 stdout。
-L/usr/X11R6/lib 連結程式時,搜尋程式庫檔時,將 /usr/X11R6/lib 列入搜尋目錄。
-lm 在連結程式時,將 libm.a 列入搜尋檔案中。
-I/usr/X11R6/include 到 /usr/X11R6/include 找尋被 include 的檔案。
-S 產生 test.c 對應的組合語言程式檔 test.s 。
-Wall 產生比較多的警告訊息 (平常不須使用,但當找不到程式中的錯誤時,可以加以使用。)



快速入門


範例:將 test.c 編譯成可執行檔 test 並在編譯過程中做最佳化。

gcc -O test.c -o test

範例: 將 test1.c 和 test2.c 編譯聯結成可執行檔 test 並在編譯過程中做最佳化。

gcc -O test1.c test2.c -o test


範例:若程式中有使用數學函數如 sin 等,編譯時須加入 -lm 。

gcc -O test.c -o test -lm

範例:發現程式有執行時錯誤,編譯後需用 GDB 除錯。

gcc -O -g test.c -o test

範例:發現程式有執行時錯誤,編譯後要跟 ABSoft F77 聯結後以 ABSoft 的除錯程式除錯。
gcc -O -gdwarf test.c -o test


更多的說明
man gcc
info gcc

-------------------------------------
看下面的例子:test.c

#include

main()

{ char *str="I like Linux! I advices you jion in the Linux World";

printf("%s\n",str);

exit(0);

}

使 用gcc編譯。輸入gcc -c test.c得到目標文件test.o.-c命令表示對文件進行編譯和彙編。但並不連接。如果再健入gcc -o ../bin/test test.o,那麼將得到名為test的可執行文件。其實這兩不可以一氣呵成,gcc ../bin/test test.c.如果程序沒有錯誤救生成了可執行文件。也許你會覺得基於命令行的編譯器比不上如VC之類的集成開發環境,的確gcc的界面要改進,但是你一 旦熟練了就會感到。gcc的效率如此之高。可以告訴大家的是Linux底下強大的C/C++集成開發環境Kdevelope和Vc一樣強大,使用了Gcc 編譯器。

2009年2月4日 星期三

在Unix命令列下寄送mail

工作的需要,需要寫一小段寄信的程式,雖然在我還是小朋友的時候就在Linux上寫過一個功能不算陽春的寄收件軟體,幾乎可以解80% mime type的信件,不過事隔多年,也忘了差不多了.好在這次要寫的東西功能非常陽春,我也在網路上找到一個應該勉強可以用的文章,就貼出來和大家分享.


在Unix命令列下寄送mail m110092006 發表於 December 18, 2006 04:37 PM

在命令列下寄送mail很多人都會,但是更多人不會。本篇告訴你怎麼寄純文字、加附檔及HTML格式的mail 。


在Unix的系統管理上我們常會把各式各樣指令的輸出導到檔案去,但是檔案在系統上,想看一下內容難免還得要登入上去。於是懶惰的人就會把這些輸出寄出來給相關的人,這樣就不需要還得連進去系統了。
在Unix下寄mail是一件很平常的事,有人可能會覺得這個有點老生常談,但事實是還是有人會來問我命令列下要怎麼寄 mail,而這個問題在網路上應該還是FAQ中的FAQ。

在Unix下最常被用來寄信的指令應該非mail莫屬,因為它普遍的存在各種不同版本不同平台的Unix系統上。或許你習慣用它的加強版 mailx。不過這二個用起來差不多我也不清楚到底有什麼差別,知道的人跟我講一下吧。另外有一個指令叫mutt 它是一個功能相當強大的MUA軟體,如果你有安裝的話,也可以使用它來寄mail。
假設你想把/etc/hosts的內容傳到你的電腦上,你不需要使用ftp來把它抓到你的電腦,只要使用指令來將它寄給你自己。

# cat /etc/hosts |mailx -s 'hosts table' jerry@abc.com

許多人應該都知道要怎麼用,而且也很多人應該是這樣子用的。上面的指令並沒有錯,只是可以直接把檔案導入給 mailx,為什麼要cat給mailx呢?公司薪水給的又不多,實在沒必要多花時間在處理公事上,所以字能少打就少打吧。

# mailx -s 'hosts table' jerry@abc.com < /etc/hosts

-s(Subject)是主旨,如果主旨有空白字元的話,記得要用單引號(')或是雙引號(")括起來。最後一個參數是收件人,如果收件人有多個的時候要用逗號(,)分隔,如jerry@abc.com,jerry@abc.com.tw。
或者你在Linux下,而且又裝了mutt。你也可以使用mutt來寄信,mutt的參數和mail差不多。

# mutt -s 'hosts table' jerry@abc.com < /etc/hosts

可是這樣子寄,/etc/hosts的內容是在信裡面呀,我想把它變成附件可以嗎?當然可以,只要跟其他的程式配合就可以了。

# uuencode /etc/hosts hosts.txt | mailx -s 'hosts table' jerry@abc.com

利用uuencode把/etc/hosts編碼過後丟給mailx就可以了,uuencode第一個參數是要編碼的檔案,第二個參數是編碼後的檔名,在這裡就是附件的檔名。下面的例子示範了把tar檔變成附件直接寄出。

# tar cf - /etc/* | uuencode etc.tar | mailx -s 'hosts table' jerry@abc.com

如果你用的是mutt那就更簡單了。只要加個-a(attach file)

# echo '/etc/hosts'|mutt -a /etc/hosts -s 'hosts table' jerry@abc.com

有人會問說,Jerry,我不要只是寄純文字的mail,可以寄html格式的mail嗎?在我回答之前,可以容許我先打你一拳嗎?如果你有 mutt(1.5.x 以上才行)的話要寄html格式的mail就很容易了(什麼,到這個時候還沒發現mutt有多好用嗎?還不快去裝起來。)。一行指令就可以搞定。

# mutt -e 'set content_type="text/html"' jerry@abc.com -s 'html format' <>

mutt允許我們對要寄出的mail修改它的檔頭(header),所以可以使用-e來設定檔頭的變數content_type 為"text/html",這個變數名稱content_type和真正檔頭Content-type的字不一樣哦!不要搞錯了。最後再導入一個html 格式的檔案給它就可以了。記住,-e後面那一串字不能錯哦!(1.5.x 以上才有這個變數。)
如果沒有mutt呢!裝一個,不然就繼續看下去。絕大多數的Unix系統應該都有內建sendmail,而sendmail有個參數-t可以達成我們的要求。看看下面的範例。

# echo 'Mime-Version: 1.0
> Content-type: text/html; charset="iso-8859-1"
> From: jerry@abc.com
> To: jerry@abc.com.tw
> Subject: test.......
>
>
html file
> ' | sendmail -t

使用echo把檔頭和所要html的內容全部輸出給sendmail這樣子就可以了。不過我想沒人會真的在命令列這樣使用,多半會用在script裡面。下面提供一個script範例給你參考,主要的部份在被#包住的那個區塊,把你要的輸出做成html格式就可以了。

#!/bin/sh
fromuser=jerry@abc.com
touser=jerry@abc.com,abc,boss@abc.com
subject="`uname -n` df output"
sendmail="/usr/sbin/sendmail -t"

header="Mime-Version: 1.0
Content-type: text/html; charset="iso-8859-1"
From: $fromuser
To: $touser
Subject: $subject

"

footer="

"
{
echo "$header"
### replace your code here. ###
df -k |awk '/^//{$5=sprintf("
%2d%",$5) ; print $0}'
###############################
echo "$footer"
} | $sendmail

下面二個script,第一個是shell script;第二個是perl script,你可以把要輸出的內容存成html檔,再用sendhtml直接寄出html格式的mail。寫的不怎麼樣,但最少可以使用啦!也給你一個 想法做參考,你可以以此延伸然後寫一個符合你的script。
使用的方法如下,
sendhtml.pl "my subject" jerry@abc.com my_file.html

#!/bin/sh
## usage : sendhtml.sh subject To_User html_file
subject="$1"
touser="$2"
htmlfile="$3"
fromuser="jerry@abc.com"
sendmail="/usr/sbin/sendmail -t"

header="Mime-Version: 1.0
Content-type: text/html; charset="iso-8859-1"
From: $fromuser
To: $touser
Subject: $subject"
{
echo "$header"
cat "$htmlfile"
} | $sendmail

#!/usr/bin/perl -w
# usage : sendhtml.pl subject To_User html_file
my $sendmail = "/usr/sbin/sendmail";
my $fromuser = "jerry@abc.com";
$subject = $ARGV[0];
$touser = $ARGV[1];
$htmlfile = $ARGV[2];

$header="Mime-Version: 1.0
Content-type: text/html; charset="iso-8859-1"
From: $fromuser
To: $touser
Subject: $subjectn";

open(fd2, "| $sendmail -t");
print fd2 $header;
open(fd1, $htmlfile);
while(my $line=) {
print fd2 "$linen";
}
close(fd2);
close(fd1);

在寄附件的部份,能不用uuencode就不要用,因為uuencode+mailx所寄出來的mail並不會在檔頭的部份加入MIME編碼的訊 息,而現在有越來越多的郵件程式不會正確讀取此種格式的mail。如yahoo, MSN....等webmail,在開啟這些mail時都會顯示亂碼,而不是正確的附檔,所以建議儘量使用別的程式來取代。
在命令列下寄mail的方法不只這些,如使用nail(已經改名叫mailx)或是使用perl、php....等也是可以,但以一般需求來講,我覺得這些應該已經夠了。如果你有什麼好的方法,歡迎你和大家分享。

2009年1月26日 星期一

囧男孩


在過年無聊的機緣下
看了一部片子 "囧男孩",
原本對這部片子的期望並沒有太高.
畢竟連口碑滿檔的國片"海角七號",也不過爾爾.
只是一部名過於實的商業電影,更何況是名不見經傳的 "囧男孩"
但看過之後,我有了點小小的改觀
首先,
它依舊不能算是佳作,但的確比海角七號好,
我想以囧男孩的票房成績的確是適當反映了該片的品質.
至於海角的的票房..我認為那只是奇蹟(一部三流的電影被拱出一流的身價).

看著影片回憶過往童年,會讓人觸發無盡想像空間.
我從來不認為看電影,是要人去領悟體會導演或是編劇所要表達的意含.
因為,人是思考的動物..有回憶也有想像
體驗領悟是經由自身的經驗去消化所得的結果.
那不是導演或編劇所能給你的
而是經由自身的故事去體驗影片的內容所得到的新的領悟.
而看了囧男孩之後
我消化出更多屬於自己的領悟
那是屬於自己的故事
是另一個囧男孩.

2009年1月11日 星期日

2008最後的大事



對我而言2008年,最後的大事就是張志忠終於結婚了!!
雖然說我用"終於"兩個字來形容..但好像還是比我早喔.
等哪天我要結婚了,我還真不知道該用怎樣的形容詞來形容了!!
他們的婚禮算是閃電了.
短短的不到一個月的時間,他們夫妻倆就從男女朋友的交往步向終身的伴侶
說真的,真的讓人佩服阿!!