嗯,
說到最近,
說實在的,時間還蠻多的(因為,我感覺到我浪費很多時間)~
每每看到新聞還是網路上,
有人都非常認真到時間不夠~
就覺得實在非常心虛,
有時候今天讀不完,但是,常拿要保持作習正常來當藉口,
明天再把要讀的讀完~
常常這樣就沒有應有的進度~
另外,fuzzy的課,應該不會去上了~
因為,單單做一個模擬器不加上fuzzy的功能,就要非常多的時間,
我想這一個功能,若有學弟的話,就留給他們做吧~
人不是萬能的,不需要每一件事情都要自己做~
不過,我發現,我花很多時間在雜事上,每三十分鐘會開網頁或是bbs來看~
我現在實在很想早上到晚上六點之前在圖書館,然後,晚上六點之後才來實驗室~
說實在的,沒有電腦在的環境,我的讀書效率比較高~
想到準備研究所的那一段時間,其實我也是可以把時間利用的很好的~
加油!!
感覺是因為沒有給自己進度的壓力,所以,才會一直拖,由現在開始,要給自己明確的進度~
2008年12月29日 星期一
時間利用率非常低落
2008年12月28日 星期日
Qt - 在座標不動,放大縮小
為了要顯示無線網路的無線波,必需要知道如何讓空心圓在原地放大縮小。
因此,透過scale可以放大縮小整個圖的某一個元件。
在每一個GraphicsItem都有一個自己的座標系統,而放大縮小與旋轉都是依自己的座標系統的原點來決定的。
例如以下的程式碼:
QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(0,0,30,30);
就是建立一個直徑為30pixel的圓,且其左上角剛好在自已的座標系統的(0,0)
若這個時候用放大的話,會依原點放大,所有,它會往右下角放大
QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-15,-15,30,30);
這個因為設定圖的左上角是在此小座標系統的(-15,-15),所以,(0,0)剛好是在圖的球心,這個時候放大,就會根據原點放大~
而把這一個放到QGraphicsScene的(0,0),則要在QGraphicsScene的函數中
MyScene::MyScene(qreal x,qreal y,qreal width,qreal height,QObject *parent):QGraphicsScene(x,y,width,height,parent) {
QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-15,-15,30,30);
addItem(ball); // 把這一個圓加入此QGraphicsScene中
ball->setPos(this->width()/2,this->height()/2); // 設定球的小座標系統的左上角落在QGraphicsScene的(width()/2,this->height()/2)這一個位置
}
安裝Qt for XP and Ubuntu
在Ubuntu下安裝Qt有兩個方法:
1. 透過apt-get
[user@host ~]$ sudo apt-get install qt4-designer qt4-doc qt4-dev-tools qt4-qtconfig
不過透過上面的方法,得到的版本是Qt4.3.2的版本
2. 到官方網站下載原始碼,自己編譯,這裡下載的是qt-x11-opensource-src-4.4.3.tar.gz
不過,若用此方法的話,要執行demo程式,直接打指令列qtdemo就可以啦
先解壓縮檔案吧~
[user@host ~]$ sudo tar -zxvf qt-x11-opensource-src-4.4.3.tar.gz
進入資料夾後
[user@host ~]$ ./configure -help
這樣會列出幾頁參數,可以調整一堆雜七雜八的安裝內容 ( 其實預設就差不多了 )。比較重要的是預設 -shared 會讓之後編譯 Qt 專案時產生較小 binary file,需要使用 shared library,沒有 library 的系統不能跑。
而 -static 則會包 runtime library 進去,不過檔案大小會增加很多。
-shared 和 -static 可以並存,但是需要個別 configure & make 在不同的資料夾 ( 用 -prefix 來設定安裝路徑 )。
確定後開始 configure
為了保持相容性,我基本上不會加上-no-qt3support
[user@host ~]$ ./configure -no-qt3support -optimized-qmake
[user@host ~]$ make
若出現X11/Xlib.h: No such file or directory
則要安裝libx11-dev
出現cannot find -lXext
則要安裝libxext-dev
(其實,這裡有一個偷吃步,先用sudo apt-get install qt4-designer qt4-doc qt4-dev-tools qt4-qtconfig,它會幫你安裝所有相依的套件,到時候再移除以上四個檔案,再用手動安裝目前這一個步驟)
[user@host ~]$ sudo apt-get install libx11-dev libxext-dev
[user@host ~]$ sudo make install
預設是用 -shared 裝在 /usr/local/Trolltech/Qt-4.3.1,編譯完之後大約為 410MB。-static 則約 1.2GB ( 因為每個 example application / demonstration 都會包 runtime library 進去... )。
安裝完成了,就要調校 $PATH 變數啦!免得 compile 時啥 header 都找無。
到.bashrc下加入這一行
PATH=/usr/local/Trolltech/Qt-4.4.3/bin:$PATH
完成啦~
在Windows XP安裝Qt:
1. 在 http://www.bloodshed.net/devcpp.html 下載最新版的 Dev C++,直接下載含 MinGW 的版本
2. 在 http://trolltech.com/products/qt 下載 Qt 4.x Open Source (MinGW) for Windows
3. 安裝 Dev C++
4. 安裝 Qt 4.x,在 Previously installed MinGW 中設定 Dev C++ 的安裝位置
5. 開啟主控台,切換到 Qt 安裝目錄的 bin 目錄下,執行 qtvars.bat compile_debug 建置 Debug library,這要一些時間,去作些別的事吧!(這兩個選項可以在程式集下的Qt找到喔)
6. 要 make 寫好的程式,執行 qtvars.bat 可以幫你設好一些 Qt 所需的環境變數,以後要執行qmake,或make都必需要透過此qtvars.bar去執行
7. 另外,跑完之後,要把編譯過程中的檔案刪掉,就請到qtvars.bat執行make clean
參考資料:
在Ubuntu下安裝Qt
在Windows XP下安裝Qt
2008年12月27日 星期六
讓Qt程試碼可以在windows xp下執行
Qt是一個跨平台的函式庫,
然後,我希望我寫的程式可以在windows和linux下都可以跑~
在windows下安裝Qt請參考良葛格學習筆記
在linux下,寫好程式碼之後,
用qmake -project指定產生.pro檔,
再用qmake依.pro產生Makefile檔
再make編譯程式,就這樣,非常簡單
但是,在windows下,依上面的步驟,確出現錯誤,找不到檔案,
決解方法就是到Makefile.Debug在INCPATH的最後面加入所有我們自己所建立的header file的目錄…
例:
INCPATH = -I"c:\Qt\4.4.3\include\QtCore" -I"c:\Qt\4.4.3\include\QtCore" -I"c:\Qt\4.4.3\include\QtGui" -I"c:\Qt\4.4.3\include\QtGui" -I"c:\Qt\4.4.3\include" -I"." -I"c:\Qt\4.4.3\include\ActiveQt" -I"debug" -I"." -I"c:\Qt\4.4.3\mkspecs\win32-g++" -I"src\widget" -I"src\items"
後面藍色的部分就是我新增的部分~
解決!!
[2009.02.06] 補充
在觀查完linux與windows下的*.pro檔之後,知道為什麼會出現這一個問題了。
可能是windows下運行qmake -project的程式沒有寫好吧~
在windows下qmake -project下的*.pro的INCLUDEPATH的欄位只有 .
所以當然就找不到我所需要的header file啦~
只要在後面加上所有的header file的路徑即可,此問題只有在windows下用qmake -project會出現
TEMPLATE = app
CONFIG = qt warn_on release
DESTDIR = ./ # 執行檔被建立後,擺放的位置
HEADERS = miniwin.h # 我們建立的class header
SOURCES = miniwin.cpp \ # 我們建立的class主程式
main.cpp
INCLUDEPATH += ./ # 指定include的路徑,例如/usr/local/xxx.h,則要加入/usr/local
DEPENDPATH += ./ # 所有cpp檔案的路徑
LIBS += # 指定要使用到的Library,應該是.so之類的動態library
INTERFACES =
TARGET = miniwin # 被建立的執行檔名稱
[2013.01.05 補充]
今天嘗試在Windows XP安裝Qt 4.8.4的流程如下:
先去下載MinGW Compiler for Windows,
因為,我們要下載的Qt 4.8.4是指定要MinGW 4.4 Compiler,
若用比較新的MinGW反而會有一些不預期的問題,
所以,要先去尋找MinGW 4.4,
不過,現在大部分官方網站都找不到MinGW 4.4,
我是直接用MinGW-gcc440_1.zip關鍵字在網路上尋找,
一下子就找到了。
下載頁面
下載之後,把它解壓縮到C:\MinGW
再來是安裝Qt,
Qt的下載頁面
下載完後,裡面就已經有編譯好的Demo的application,
如果要重新compiler成Open source的license的話,則必需要重新Compiler,則在
「開始」→「所有程式」→「Qt by Digia v4.6.4 (MinGW OpenSource)」→「Qt 4.6.4 (Build Debug Libraries)」
這樣會重新開始編譯所有demo的source code。
Build完之後,直接打qtdemo就可以執行demo的application了。
若一般的compiler自己的程式的話,則使用
「開始」→「所有程式」→「Qt by Digia v4.6.4 (MinGW OpenSource)」→「Qt 4.6.4 Command Prompt」
會把Qt的環境設定好。
Build code的流程請參考如何build出不需要另外建置環境的QT exe檔
QtCreator則是用Qt Creator 2.6.1的版本
可以完整編譯完qtdemo的組合
因為不像windows其它IDE一樣,全部都是包好的情況下,
所以,記錄一下整合的版本
[MinGW-gcc440_1.zip]
[qt-creator-windows-opensource-2.6.1.exe]
[qt-win-opensource-4.6.4-mingw.exe]
參考資料:
用QT建立一個基本視窗
windows上安装MinGW 4.4、Qt library 4.8.4和Qt Creator
2008年12月26日 星期五
Qt 資源系統
在qt4中,可以透過資源系統,把圖片嵌入到程式碼中。這樣圖片不見,也沒有關係啦~
Qt 資源系統(Resource System)可以提供與平台無關的機制,讓您把應用程式的圖檔、語系檔、資料等儲存於可執行檔之中,避免相關的資源檔案遺失的問題,Qt資源系統是基於 qmake、rcc(resource compiler),並搭配QFile來使用,您必須在產生的.pro檔之中,告知資源群集檔(Resource Collection File)的位置與名稱。
資源群集檔的副檔名為.qrc,實際的內容為XML格式的檔案,當中告知了這個應用程式所要使用到的資源檔案,例如您想要將QListWidget 與 QListWidgetItem 中所使用到的圖檔儲存在可執行檔案之中,則可以撰寫一個resourcefile.qrc:
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>images/bee_head.jpg</file>
<file>images/bush_head.jpg</file>
<file>images/cat_head.jpg</file>
<file>images/caterpillar_head.jpg</file>
<file>images/momor_head.jpg</file>
</qresource>
</RCC>
檔案的路徑是相對於.qrc檔案的位置。接著您要在產生的.pro檔案中,增加一行,告知.qrc檔案的位置,例如:
RESOURCES = resourcefile.qrc
qmake會產生出製造qrc_resourcefile.cpp的規則,之後使用rcc產生.cpp檔案,當中會將想要嵌入的相關檔案,壓縮並轉換為代表二進位資料的C++靜態無號字元陣列,如果您的.qrc檔案內容有變動,在編譯時.cpp檔案也會重新產生。
如果要使用嵌入的資源,則要在路徑的前端放置:/,例如:
QListWidget *listWidget = new QListWidget;
listWidget->insertItem(0, new QListWidgetItem(QIcon(":/images/caterpillar_head.jpg"), "caterpillar"));
listWidget->insertItem(1, new QListWidgetItem(QIcon(":/images/momor_head.jpg"), "momor"));
listWidget->insertItem(2, new QListWidgetItem(QIcon(":/images/bush_head.jpg"), "bush"));
listWidget->insertItem(3, new QListWidgetItem(QIcon(":/images/bee_head.jpg"), "bee"));
listWidget->insertItem(4, new QListWidgetItem(QIcon(":/images/cat_head.jpg"), "cat"));
您也可以為資源檔案的路徑設置別名(Alias),例如:
<file alias="caterpillar_head.jpg">images/caterpillar_head.jpg</file>
之後在程式中指定路徑時,就可以直接使用別名,例如:
listWidget->insertItem(0, new QListWidgetItem(QIcon(":/caterpillar_head.jpg"), "caterpillar"));
您也可以為別名設置前置(Prefix),例如:
<qresource prefix="/resources">
<file alias="caterpillar_head.jpg">images/caterpillar_head.jpg</file>
</qresource>
之後每個別名都會自動加上前置,使用時如下:
listWidget->insertItem(0, new QListWidgetItem(QIcon(":/resources/caterpillar_head.jpg"), "caterpillar"));
您也可以搭配語系來使用嵌入的資源檔,例如若這麼設定:
<qresource>
<file>caterpillar_head.jpg</file>
</qresource>
<qresource lang="zh_TW">
<file alias="caterpillar_head.jpg">caterpillar_head_zh_TW.jpg</file>
</qresource>
當路徑指定為:/caterpillar_head.jpg,如果使用者是使用zh_TW語系,則會自動對應使用caterpillar_head_zh_TW.jpg,此一方法也可以用來載入.qm檔案,以實現多國語系支援,可參考 翻譯應用程式 與 多國語系選擇與切換。
參考資料:
Qt資源系統
全域變數
區域變數就是只能在一個區塊中被使用
例:
void foo1(){
int x=4;
cout << x << endl;
}
void foo2(){
cout << x << endl; // 出現錯誤
}
以上這一個例子的x就是區域變數,只能在foo1()內使用而不能在foo2()內使用。
而全域變數的例子呢
int x=4;
void foo1(){
cout << x << endl;
}
void foo2(){
cout << x << endl;
}
而以上的例子的x可以在foo1()與foo2()使用,而這就是全域變數。
#include <iostream>
#include <string>
using namespace std;
string color("red");
void local();
int main()
{
extern string color; // 告知這一個變數宣告在別處,這裡是可以省略的,因為是在同一個檔案,若string color("red");是在其它檔案,而且我們沒有include進來,則這一行就是必要的
cout << "Global color: " << color << endl;
local();
return 0;
}
void local()
{
string color("blue");
cout << "Local color: " << color << endl;
cout << "Global color: " << ::color << endl;
}
透過::運算子告知,我要全域變數的color,而沒有加::的表示,選擇宣告比較近的那一個
2008年12月25日 星期四
exit()與return()的差別
在main函數中我們通常使用return (0);這樣的方式返回一個值。
但這是限定在非void情況下的也就是void main()這樣的形式。
exit()通常是用在例程中用來終結程式用的,使用後程式自動結束跳會作業系統。
但在如果把exit用在main內的時候無論main是否定義成void返回的值都是有效的,並且exit不需要考慮類型,exit(1)等價於return (1)
參考來源:
exit()與return()的差別
2008年12月23日 星期二
Qt3與Qt4共存
因為學長留下來的程式碼是Qt3寫的,
而其中主要用到的類別QCanvas我在Qt4中竟然找不到!
所以本來打算就繼續用Qt3改程式,但是,最近看了一下Qt4的demo程式,還有其中有興趣的程式碼,發現,其實,QCanvas的類別在Qt4中還是存在的,只不過它沒有顯示在主要的類別頁面中。
而且類別名稱也改成Q3Canvas的,所以,若真的要原來的程式碼可以在Qt4上跑的話,必須要把有改過的類別名稱都改成Qt4中新的名稱,不過,我不會做這樣的事情的!
所以,就想說把Qt4與Qt3共存~
在不確定是否能共存的時候,就只好先用vmware來作實驗啦~
在實驗之後,確定是可以共存的~
不過,有兩個情況,就是安裝Qt3與Qt4的順序。
在只有一個版本的時候,只會有一個qmake,但是,當有兩個版本之後,就會出現qmake-qt3與qmake-qt4。
當安裝完Qt3再安裝Qt4,此時的qmake是指到qmake-qt3
而若相反的話,則系統的qmake是指到qmake-qt4
若原本是指到qmake-qt3的話,要把它改到qmake-qt4的話使用以下指令,以下是建立一個qmake的捷徑是指到qmake-qt4
[root@host ~]# ln -T /usr/bin/qmake-qt4 /usr/bin/qmake
這樣就可以同時跑qt3和qt4啦~
若過透過qmake產生Makefile時,若是qt3則用qmake-qt3而qt4則使用qmake-qt4
2008年12月22日 星期一
event
Qt的事件跟Signal、Slot機制是不同的。
Signal與Slot的機制是同步的(Synchronous),Signal是由物件發出的,使用QObject的connect()連接物件上定義的Slot來立即處理。
Qt的事件可以是非同步的(Asynchronous)的,Qt使用一個事件佇列來維護,新的事件產生時基本上會被排到佇列的尾端,前一個事件處理完成,再從佇列的前端取出下一個佇列來處理,必要的時候,Qt的事件也可以是同步的,而事件還可以使用「事件過濾器」進行過濾處理。
跟網路要傳封包感覺很像,先學起來~
在qt3的教學文件中有一個部分範例
建立一個自定的事件
class ColorChangeEvent : public QCustomEvent
{
public:
ColorChangeEvent( QColor color ) : QCustomEvent( 346798 ), c( color ) {};
QColor color() const { return c; };
private:
QColor c;
};
// To send an event of this custom event type:產生一個事件,並傳送給receiver
ColorChangeEvent* ce = new ColorChangeEvent( blue );
QApplication::postEvent( receiver, ce ); // Qt will delete it when done
// To receive an event of this custom event type:接收事件
void MyWidget::customEvent( QCustomEvent * e )
{
if ( e->type() == 346798 ) { // It must be a ColorChangeEvent
ColorChangeEvent* ce = (ColorChangeEvent*)e;
newColor = ce->color();
}
}
下面是我自己寫的一個例子
myevent.h
#ifndef MYEVENT_H
#define MYEVENT_H
#include <qevent.h>
class MyEvent:public QCustomEvent
{
public:
MyEvent(int );
int value() const;
private:
int x;
};
#endif // MYEVENT_H
myevent.cpp
#include "myevent.h"
MyEvent::MyEvent(int y):QCustomEvent(346798),x(y){
// do nothing
}
int MyEvent::value() const{
return x;
}
mywidget.h
#ifndef MYWIDGET_H
#define WYWIDGET_H
#include <qwidget.h>
#include "myevent.h"
class MyWidget:public QWidget
{
public:
MyWidget(QWidget *parent,const char *name=0);
protected:
void customEvent(QCustomEvent *);
};
#endif // MYWIDGET_H
mywidget.cpp
#include "mywidget.h"
#include <iostream>
using namespace std;
MyWidget::MyWidget(QWidget *parent,const char *name):QWidget(parent,name)
{
// do nothing
}
void MyWidget::customEvent(QCustomEvent *e){
if (e->type() == 346798) {
MyEvent *ce = (MyEvent *) e; // 透過父類別的子標變數接收,要強制轉換成子類別的子標
cout << "有接收到事件啦" << ce->value() << endl;
}
}
main.cpp
#include <qapplication.h>
#include "mywidget.h"
int main(int argc,char **argv)
{
QApplication app(argc,argv);
MyWidget w(0);
MyEvent *m = new MyEvent(22);
QApplication::postEvent(&w,m);
w.resize(300,300);
app.setMainWidget(&w);
w.show();
return app.exec();
}
C++事件(Event)機制的實現一例
2008年12月21日 星期日
struct
這裡說明一個struct的範例,並且初始化這一個struct
#include <stdio.h>
struct // 這一個結構沒有名稱,即匿名結構
{
int id;
char *path;
int frames;
}
kas_animations [] = // kas_animations就是上面建立的結構,而下面就是初始化
{
{01,"first",12},
{02,"second",24},
{03,"third",36}
}; // 記得要在最後加分號
struct person // 定義一個名為person的結構
{
char *first_name;
char *second_name;
};
int main()
{
int i;
for (i=0;i<3;i++){
printf("id:%d\tpath:%s\tframes:%d\n",kas_animations[i].id,kas_animations[i].path,kas_animations[i].frames);
}
struct person ren = {"Fang","renyang"}; // 初始化一個person結構的ren變數,在c中必需要加struct,但是,在c++中可以省略
printf("The first name is %s, and the second name is %s\n",ren.first_name,ren.second_name);
return 0;
}
以下是純記錄別人網站的東西,以後搞不好有機會用到
C/C++語言struct深層探索
1. struct的巨大作用
面對一個人的大型C/C++程式時,只看其對struct的使用情況我們就可以對其編寫者的編程經驗進行評估。因為一個大型的C/C++程式,勢必要涉及一些(甚至大量)進行資料組合的結構體,這些結構體可以將原本意義屬於一個整體的資料組合在一起。從某種程度上來說,會不會用struct,怎樣用struct是區別一個開發人員是否具備豐富開發經歷的標誌。
在網路協定、通信控制、嵌入式系統的C/C++編程中,我們經常要傳送的不是簡單的位元組流(char型陣列),而是多種資料組合起來的一個整體,其表現形式是一個結構體。
經驗不足的開發人員往往將所有需要傳送的內容依順序保存在char型陣列中,通過指標偏移的方法傳送網路報文等資訊。這樣做編程複雜,易出錯,而且一旦控制方式及通信協定有所變化,程式就要進行非常細緻的修改。
一個有經驗的開發者則靈活運用結構體,舉一個例子,假設網路或控制協定中需要傳送三種報文,其格式分別為packetA、packetB、packetC:
struct structA
{
int a;
char b;
};
struct structB
{
char a;
short b;
};
struct structC
{
int a;
char b;
float c;
}
優秀的程式設計者這樣設計傳送的報文:
struct CommuPacket
{
int iPacketType; //報文類型標誌
union //每次傳送的是三種報文中的一種,使用union;union有一點類似struct,只不過,每宣告一個變數,只能代表內容中的其中一個
{
struct structA packetA;
struct structB packetB;
struct structC packetC;
}
};
在進行報文傳送時,直接傳送struct CommuPacket一個整體。
假設發送函數的原形如下:
// pSendData:發送位元組流的首位址,iLen:要發送的長度
Send(char * pSendData, unsigned int iLen);
發送方可以直接進行如下調用發送struct CommuPacket的一個實例sendCommuPacket:
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
假設接收函數的原形如下:
// pRecvData:發送位元組流的首位址,iLen:要接收的長度
//返回值:實際接收到的位元組數
unsigned int Recv(char * pRecvData, unsigned int iLen);
接收方可以直接進行如下調用將接收到的資料保存在struct CommuPacket的一個實例recvCommuPacket中:
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
接著判斷報文類型進行相應處理:
switch(recvCommuPacket. iPacketType)
{
case PACKET_A:
… //A類報文處理
break;
case PACKET_B:
… //B類報文處理
break;
case PACKET_C:
… //C類報文處理
break;
}
以上程式中最值得注意的是
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
中的強制類型轉換:(char *)&sendCommuPacket、(char *)&recvCommuPacket,先取位址,再轉化為char型指標,這樣就可以直接利用處理位元組流的函數。
利用這種強制類型轉化,我們還可以方便程式的編寫,例如要對sendCommuPacket所處記憶體初始化為0,可以這樣調用標準庫函數memset():
memset((char *)&sendCommuPacket,0, sizeof(CommuPacket));
2. struct的成員對齊
Intel、微軟等公司曾經出過一道類似的面試題:
#include <iostream.h>
using namespace std;
#pragma pack(8)
struct example1
{
short a;
long b;
};
struct example2
{
char c;
example1 struct1;
short e;
};
#pragma pack()
int main(int argc, char* argv[])
{
example2 struct2;
cout << sizeof(example1) << endl;
cout << sizeof(example2) << endl;
cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;
return 0;
}
問程式的輸入結果是什麼?
答案是:
8
16
4
不明白?還是不明白?下麵一一道來:
2.1 自然對界
struct是一種複合資料類型,其構成元素既可以是基本資料類型(如int、long、float等)的變數,也可以是一些複合資料類型(如 array、struct、union等)的資料單元。對於結構體,編譯器會自動進行成員變數的對齊,以提高運算效率。缺省情況下,編譯器為結構體的每個成員按其自然對界(natural alignment)條件分配空間。各個成員按照它們被聲明的順序在記憶體中順序存儲,第一個成員的位址和整個結構的位址相同。
自然對界(natural alignment)即默認對齊方式,是指按結構體的成員中size最大的成員對齊。
例如:
struct naturalalign
{
char a;
short b;
char c;
};
在上述結構體中,size最大的是short,其長度為2位元組,因而結構體中的char成員a、c都以2為單位對齊,sizeof(naturalalign)的結果等於6;
如果改為:
struct naturalalign
{
char a;
int b;
char c;
};
其結果顯然為12。
2.2指定對界
一般地,可以通過下面的方法來改變缺省的對界條件:
• 使用虛擬指令#pragma pack (n),編譯器將按照n個位元組對齊;
• 使用虛擬指令#pragma pack (),取消自定義位元組對齊方式。
注意:如果#pragma pack (n)中指定的n大於結構體中最大成員的size,則其不起作用,結構體仍然按照size最大的成員進行對界。
例如:
#pragma pack (n)
struct naturalalign
{
char a;
int b;
char c;
};
#pragma pack ()
當n為4、8、16時,其對齊方式均一樣,sizeof(naturalalign)的結果都等於12。而當n為2時,其發揮了作用,使得sizeof(naturalalign)的結果為8。
在VC++ 6.0編譯器中,我們可以指定其對界方式,其操作方式為依次選擇projetct > setting > C/C++功能表,在struct member alignment中指定你要的對界方式。
另外,通過__attribute((aligned (n)))也可以讓所作用的結構體成員對齊在n位元組邊界上,但是它較少被使用,因而不作詳細講解。
2.3 面試題的解答
至此,我們可以對Intel、微軟的面試題進行全面的解答。
程式中第2行#pragma pack (8)雖然指定了對界為8,但是由於struct example1中的成員最大size為4(long變數size為4),故struct example1仍然按4位元組對界,struct example1的size為8,即第18行的輸出結果;
struct example2中包含了struct example1,其本身包含的簡單資料成員的最大size為2(short變數e),但是因為其包含了struct example1,而struct example1中的最大成員size為4,struct example2也應以4對界,#pragma pack (8)中指定的對界對struct example2也不起作用,故19行的輸出結果為16;
由於struct example2中的成員以4為單位對界,故其char變數c後應補充3個空,其後才是成員struct1的記憶體空間,20行的輸出結果為4。
3. C和C++間struct的深層區別
在C++語言中struct具有了“類” 的功能,其與關鍵字class的區別在於struct中成員變數和函數的默認訪問許可權為public,而class的為private。
例如,定義struct類和class類:
struct structA
{
char a;
…
}
class classB
{
char a;
…
}
則:
struct A a;
a.a = 'a'; //訪問public成員,合法
classB b;
b.a = 'a'; //訪問private成員,不合法
許多文獻寫到這裏就認為已經給出了C++中struct和class的全部區別,實則不然,另外一點需要注意的是:
C++中的struct保持了對C中struct的全面相容(這符合C++的初衷——“a better c”),因而,下面的操作是合法的:
//定義struct
struct structA
{
char a;
char b;
int c;
};
structA a = {'a' , 'a' ,1}; // 定義時直接賦初值
即struct可以在定義的時候直接以{ }對其成員變數賦初值,而class則不能,在經典書目《thinking C++ 2nd edition》中作者對此點進行了強調。
4. struct編程注意事項
看看下面的程式:
#include <iostream>
using namespace std;
struct structA
{
int iMember;
char *cMember;
};
int main(int argc, char* argv[])
{
structA instant1,instant2;
char c = 'a';
instant1.iMember = 1;
instant1.cMember = &c;
instant2 = instant1;
cout << *(instant1.cMember) << endl;
*(instant2.cMember) = 'b';
cout << *(instant1.cMember) << endl;
return 0;
}
14行的輸出結果是:a
16行的輸出結果是:b
Why?我們在15行對instant2的修改改變了instant1中成員的值!
原因在於13行的instant2 = instant1賦值語句採用的是變數逐個拷貝,這使得instant1和instant2中的cMember指向了同一片記憶體,因而對instant2的修改也是對instant1的修改。
在C語言中,當結構體中存在指標型成員時,一定要注意在採用賦值語句時是否將2個實例中的指標型成員指向了同一片記憶體。
在C++語言中,當結構體中存在指標型成員時,我們需要重寫struct的拷貝構造函數並進行“=”操作符重載。
轉載自CSDN
Qt Runtime Installer for Windows
若我在a這一台電腦寫出一個程式,但是,想要在b這一台電腦上跑,
但是,有一堆函式庫沒有在b這一台電腦上,
這個時候就要安裝Qt runtime for Windows
雖然目前都在linux下寫qt,但是,這個資料先留下來吧~
DLL List
- Qt3Support4.dll
- QtAssistantClient4.dll
- QtCore4.dll
- QtDesigner4.dll
- QtDesignerComponents4.dll
- QtGui4.dll
- QtNetwork4.dll
- QtOpenGL4.dll
- QtScript4.dll
- QtSql4.dll
- QtSvg4.dll
- QtTest4.dll
- QtXml4.dll
參考資料:
Qt Runtime Installer for Windows
2008年12月20日 星期六
日本報告之行~
最近剛從日本報告回來~
第一次出國,還好是跟團出去,就是一群要去Conference的人一起組個團,
因為這次的報告,所以,10月底開始就在準備要報的這一個paper,
因為,跟我的之後要做的論文沒有什麼關係,所以,這算是額外花的時間。
去日本五天四夜還不錯玩~12/10-12/14
我是跟一個高應大的電子系博班是室友,
跟他討論到老師的問題,
他也說老師也沒有辦法真的教他們東西~
東西也是要自己學~
研究所跟大學最大的不同就是沒有人會教你~
大部分要自己學~
而現在我最主要的困難是有很多蠻基礎的東西我之前沒有學過,
所以要另外花時間去學~
但是,就是因為太多東西要學,又不知道從哪裡開始學~
像是我要寫的論文中,打算寫一個車用模擬器,來收集我針對某一台中的開車行為,
然後,透過fuzzy來學習,使得這一台車的行為模式就是我~
所以,我必需要學
「fuzzy」:這一個學期有去旁聽,但是,還蠻理論的,覺得我可能只需要實作的部分就好
「C++」:耶~算是看的差不多了,常用的東西都應該ok吧,就算不熟,查一下應該就有了,這個應該是寫程式最基本要會的
「Qt」:因為Qt是C++的延申,而且,有很多API,再來要透過它展示我的模擬器,現在有一個問題是學長寫的模擬器是用Qt3寫的,而現在最新的是Qt4,而模擬器中最主要的Canvas類別在Qt4中竟然沒有了,所以,最近在找Qt4是否有取代QCanvas的類別,似呼有看到一個例子是動畫的,就是QCanvas的主要功能,近期要研究一下
「軟體工程UML」:寫程式人人會,但是,要如何寫出一個可以讓後面的人好維護的程式,這才是一個課題,若不需望rework這麼多,code的重覆使用性就好高,所以,規畫要清楚
「英文」:英文很重要,不用多說,現在每一天都會讀5個單子本的句子。
「DSRC規格書」:因為,要做車間通訊,所以,還是要讀這一個spec,想起來就頭大
「Linux」:因為前景看好,我還喜歡打指令的~這想感覺好像是MIS喔
「PHP」:可以自己架站,因為,活用性比較高,可以收集很多自己的資料,就可以不用靠blogger,沒有空間上的上限啦~不過,要另外,維護的成本
分析:基本上因為,現在不景氣,所以,就算隨便畢業,出去也一定找不到工作。我是打算好好寫這一個模擬器,並且用軟體工程的方法好好規畫一下,用這一個模擬器來demo,到時候讓公司知道我有規畫的能力,而不是只會coding,若是只會coding,那真的只是在做coding黑手而以。當一個新的IDE出來,寫程式會比你更快,更好~重點是要會規畫~就像html現在用frontpage隨便拉都比十年前寫出來的還要漂亮。
目前還蠻想打算先放棄fuzzy,先把沒有fuzzy的模擬器先寫出來,以後,再把fuzzy的部分再加上去~但是,一直沒有那一個勇氣(基本上這樣應該要三年,但是,若三年真的可以把實力打的紮實,其實也是ok的)~
人生那麼長,有時候多個一年去好好把底子打好是相對值得的。比直接去公司,若公司訓練不好,都只是做雜事,那會更浪費時間~
真的要好好想一想~do it small, do it right
照片
2008年12月2日 星期二
三抓三放 時間用在刀口上!
作者/ 台大化工研究所教授 呂宗昕
捨棄一切的無關緊要
每天都從「專心去做最重要的事」開始,有一天,你也會向比爾蓋茲一樣成功。
你經常需要搶時間工作嗎?工作好像總是做不完?成天被客戶、老闆追跑?
待辦文件堆積如山?如果你正為這些問題困擾,「時間管理」是最佳解決之道。
管理大師彼得‧杜拉克 (Peter Drucker) 說過:
「時間是世界上最短缺的資源,除非善加管理,否則一事無成。」
每個上班族都可望時間。我們需要時間處理辦公室內應做之事,也需要時間在繁忙與休閒生活間取得平衡。即使每個人對時間的冀求如此強烈,但實際上多數人對時間管理的概念都十分模糊,更何況無論學校教育或職前訓練,都未曾教過這重要的一課。
天資聰穎者在職場中,藉著經驗累積及失敗的歷練,可以在跌跌撞撞中順利摸索出掌握時間的訣竅;天資平庸者即使經歷挫敗,也未必能適時調整方向,領悟出適合自己的時間應對模式。
管理,全靠「學習」與「練習」
其實,時間管理是需要學習的,正如同你過去曾努力學習任一專業技能與科目一樣
時間管理也需要練習,在明瞭相關原則與技巧之後,必須身體力行、加以實踐才能為自己「搶」得寶貴的時間。
有一次,和某家電子公司總經理晤談時,他提到對於龐大的企業體而言,提高營運績效是終極目標,而他自己的首要目標是簡化工作。
那次談話讓我深有所感。
比爾蓋茲大概是科技業最忙碌的總裁之一,他年輕時就已懂得要跟時間賽跑。
他熱愛電腦,尚未自哈佛大學畢業,就迫不急待地在車庫裡創業。創立微軟那年,還未滿20歲。
在創業最初的7年裡,他只休15天假。比爾蓋茲認為工作是一場競賽,他喜歡在緊要關頭全力以赴的感覺,也深深享受伴隨而來的快樂與成就感。
他勇於追逐時間,結果打造出有史以來最強大的電腦軟體王國,為全世界數以億計的人們提供工作上的幫助及便捷。
他最喜歡的是電腦,最想積極擁抱的是高科技,所以才心甘情願,將絕大部分時間資源,都投注電腦科技。
深入瞭解比爾蓋茲的故事後,可將他的成功歸因於3大要素:
1.設立明確目標
他知道電腦是明日科技的夢想,也深信自己就是實現那夢想的人。
在心中訂立明確工作目標,設定清楚的工作藍圖,詳細規劃工作進度,就義無反顧努力追夢。
2.集中焦點攻擊
「Focus」這個單字是名詞,也是動詞。名詞是指焦點,動詞則是指集中焦點,比爾蓋茲將精力及時間全部投注在電腦科技的研發,集中焦點猛力攻擊,所以能在短時間內締造驚人的卓越成果。
3.簡化工作內容
比爾蓋茲一心一意專心經營他的軟體王國,無暇兼顧其他事務。他大幅簡化工作內容,使自己可以心無旁鶩地專於本業。工作簡化,讓他能專心思考,大幅減少無謂的時間浪費,進而獲得關鍵性的勝利。
「電視冠軍」節目曾介紹一位「水果達人」他為了讓果樹結出最碩大、最甜美的果實,總在果樹開花後摘掉大部分花朵,僅留兩、三個花苞。(這技術在農業上被稱為「疏果」)
「這樣不就會使果實產量大減嗎?」訪問者不解地問。
「我要讓全部養分都灌注在這幾個花苞上,這樣自然能夠結出最大、最甜的果實。」
達人自信滿滿地說。
水果達人的秘訣非常值得我們參考。
為自己的生活大樹 進行疏果
如果把樹木的主樹幹比喻為本業工作的話,那些旁生的細小枝幹就可能相當於瑣碎的雜務、不具意義的是、冗長無聊的會議、徒具表面功夫的人際交往等。以「時間養分」來說,這些細小枝幹與主樹幹是競爭者,所有養份將悉數灌注在主樹幹上,可使樹幹迅速拔高,成為頂天立地、高聳入雲的大樹。
我非常同意那位總經理的看法。工作必須適當簡化,有限的時間資源才能被有效利用。
我本身在忙碌生活中,也是利用簡化工作的概念,替自己爭取更多時間。
該如何簡化工作?「三抓三放」原則可供參考:
1.抓大事,放小事
集中思考工作上的大事,對於微不足道的小事,無須過度煩心。
高階管理者必須為公司明確定位,掌握未來發展的重要方向,別為枝微末節而操心;
基層員工應將時間用於可明顯提升業績的事務上,無關緊要的小事則盡量刪除。
2.抓正事,放雜事
要順利完成一件工作,有必要的程序及步驟,也就是完成任務的正事,而與完成任務無關的則稱為雜事。
一個有智慧的工作者應抓緊正事,將心力和時間集中投資於處理與該任務最相關的核心問題;至於與正式無關的雜事,可交由旁人處理,或是盡量避免,以簡化工作內容。
3.抓要事,放閒事
重要又緊急的事情應該再第一時間完成;
沒有時間壓力的閒事,則利用工作空檔,簡單處理即可。
要事與閒適的差別,在於對績效的貢獻度以及時間的緊迫程度。
高績效貢獻度、高時間緊迫性的要事必須優先處理,
低績效貢獻度、低時間緊迫性的閒事則可暫緩或刪除。
比爾蓋茲之所以能夠成功,是因為他熱愛電腦,也熱愛時間。
如果你也希望再事業上有一番大成就,就請抓住主幹,放棄枝幹,
有一天你也會成就大事業。
本文摘自《30雜誌》10月號
2008年11月30日 星期日
cast - 轉換
reinterpret_cast:
reinterpret_cast<T*>(a)
任何類型的指標均可以轉換成其它類型的指標(反正,就是無敵轉換)
表達式reinterpret_cast<T*>(a)能夠用於諸如char* 到 int*,或者One_class* 到Unrelated_class*等類似這樣的轉換,因此可能是不安全的。
class A { ... };
class B { ... };
void f()
{
A* pa = new A;
void* pv = reinterpret_cast<A*>(pa);// pv 現在指向了一個類型為B的對象,這可能是不安全的
...
}
static_cast:
例:
int num = 0;
double number = 3.14;
num = static_cast<int> (number); // 由double強制轉換成int
在C中可以由以下取代
int num = 0;
double number = 3.14;
num = (int) number; // 由double強制轉換成int
const_cast:
在某此情況下,我們需要改變唯讀區域的值,這時可以使用const_cast改變指標的型態
例:
#include <iostream>
using namespace std;
void foo(const int*);
int main() {
int var = 10;
cout << "var = " << var << endl;
foo(&var);
cout << "var = " << var << endl;
return 0;
}
void foo(const int* p) {
int* v = const_cast<int*> (p);
*v = 20;
}
dynamic_cast:
C++提供了dynamic_cast用來將一個基底類別的指標轉型至衍生類別指標,稱之為「安全向下轉型」(Safe downcasting),它在執行時期進行型態轉換動作,首先會確定轉換目標與來源是否屬同一個類別階層,接著才真正進行轉換的動作,檢驗動作在執行時期完成,如果是一個指標,則轉換成功時傳回位址,失敗的話會傳回0,如果是參考的話,轉換失敗會丟出 bad_cast例外。
由於dynamic_cast轉換失敗的話會傳回0,因而運算的結果不可使用,必須先行對轉換結果作檢查才可以。
如果使用參考的話,dynamic_cast在轉換失敗之後會丟出bad_cast例外,所以您必須使用try...catch來處理例外
#include <iostream>
#include <typeinfo>
using namespace std;
class Base {
public:
virtual void foo() = 0;
};
class Derived1 : public Base {
public:
void foo() {
cout << "Derived1" << endl;
}
void showOne() {
cout << "Yes! It's Derived1." << endl;
}
};
class Derived2 : public Base {
public:
void foo() {
cout << "Derived2" << endl;
}
void showTwo() {
cout << "Yes! It's Derived2." << endl;
}
};
void showWho(Base &base) {
try {
Derived1 derived1 = dynamic_cast<Derived1&>(base);
derived1.showOne();
}
catch(bad_cast) {
cout << "bad_cast 轉型失敗" << endl;
}
}
int main() {
Derived1 derived1;
Derived2 derived2;
showWho(derived1);
showWho(derived2);
return 0;
}
總結C++中的所有強制轉換函數
2008年11月28日 星期五
auto_ptr自動管理配置資源
對於使用new動態配置的資源,在不使用時必須記得delete,以釋放記憶體空間,然而動態記憶體配置很容易發生忘了delete,或是對同一個記憶體位址delete兩次(例如一個物件被指定給兩個指標),或是對一個已經被delete的位址再作讀寫動作。
C++標準函式庫中提供auto_prt,可以協助您動態管理new而建立的物件,要使用auto_prt,您要含入memory表頭檔,例如:
#include <memory>
auto_ptr可以指向一個以new建立的物件,當auto_ptr的生命週期結束後,所指向的物件之資源也會被釋放,在建立auto_ptr時必須指定目標物件之型態,例如:
auto_ptr<int> iPtr (new int(100));
auto_ptr<string> sPtr (new string("caterpillar"));
操作auto_ptr就像操作沒有使用auto_ptr的指標一樣,例如:
cout << *iPtr << endl; // 顯示100
if(sPtr->empty())
cout << "字串為空" << endl;
您也可以建立一個未指向任何物件的auto_prt,例如:
auto_ptr<int> iPtr;
未指向任何物件的auto_ptr不可以取值,否則會發生不可預期之結果,既然不可取值,如何判斷它是否有指向物件呢?您可以使用get()函式,它會傳回所指向物件的位址,如果傳回0,表示不指向任何物件,如果不指向任何物件,您可以使用reset()來讓它指向一個物件,例如:
if(iPtr.get() == 0) {
iPtr.reset(new int(100));
}
reset()可以接受一個指標或是0表示不指向任何物件,reset()會先delete目前指向的物件,然後重新指向新的物件,您也可以使用 release()釋放auto_ptr管理所指向物件的職責。
auto_ptr可以使用另一個auto_ptr來建立,這會造成所有權的轉移,例如:
auto_ptr<SafeArray> ptr1(new SafeArray(19));
auto_ptr<SafeArray> ptr2(ptr1);
當使用ptr1來建立ptr2時,ptr1不再對所指向物件的資源釋放負責,職責交給了ptr2,在使用指定運算時,也有類似的行為,例如:
auto_ptr<SafeArray> ptr1(new SafeArray(19));
auto_ptr<SafeArray> ptr2(new SafeArray(20));
ptr2 = ptr1;
ptr2所指向的物件會先被delete,然後ptr1的屬性會複製至ptr2,也就是ptr1所指向的物件,現在由ptr2指向它了,ptr1不再負責所指向物件的資源釋放。
auto_ptr的資源維護動作是以inline的方式來完成,也就是在編譯時會被擴展開來,所以使用auto_ptr並不會犧牲效率。
最後要注意的是,auto_ptr不能用來管理動態配置而來的陣列,如果用它來管理動態配置而來的陣列,結果是不可預期的。
我的想法:
使用auto_ptr有兩個角色:
第一個是本身auto_ptr的功能,此時,變數為物件,可以使用.來使用以下函數get()、reset()、release()的功能。
第二個是表示其它物件的指標,用來使用管理的指向物件的職責。
參考資料:
C++ Gossip: auto_ptr 自動管理配置資源
2008年11月27日 星期四
typedef
typedef主要有三個功能~依序如下...
簡單型態的別名:
// 定義無號單字節的型態
// 則宣告BYTE x;
// 就是宣告unsigned char x;
typedef unsigned char BYTE;
typedef unsigned short WORD;// 定義無號雙字節的型態
typedef unsigned long DWORD;// 定義無號四字節的型態
結構型態的別名:
typedef struct StructTag{
int mA;
int mB;
} STRUCTTAG, *PSTRUCTTAG;
當要建立這個結構的物件時,就可以用別名 STRUCTTAG 和 PSTRUCTTAG,例如
STRUCTTAG StructObj;
PSTRUCTTAG pStructObj;
就相當於
struct StructTag StructObj;
struct StructTag *pStructObj;
函數的別名:
main.cpp
#include <iostream>
#include "sort.h"
using namespace std;
int main() {
int number1[] = {3, 5, 1, 6, 9};
sort(number1, 5, larger);
cout << "大的在前 ";
for(int i = 0; i < 5; i++) {
cout << number1[i] << " ";
}
cout << endl;
int number2[] = {3, 5, 1, 6, 9};
sort(number2, 5, smaller);
cout << "小的在前 ";
for(int i = 0; i < 5; i++) {
cout << number2[i] << " ";
}
cout << endl;
return 0;
}
sort.h
typedef bool (*CMP)(int, int); // 把它想成說CMP是變數,且它取代bool (*) (int,int)這一個回傳值為bool,參數值為(int,int)的型態
void swap(int&, int&);
bool larger(int a, int b);
bool smaller(int a, int b);
void sort(int*, int, CMP);
sort.cpp
#include "sort.h"
void swap(int &a, int &b) {
int t = a;
a = b;
b = t;
}
bool larger(int a, int b) {
return a > b;
}
bool smaller(int a, int b) {
return a < b;
}
void sort(int* arr, int length, CMP compare) {
int flag = 1;
for(int i = 0; i < length-1 && flag == 1; i++) {
flag = 0;
for(int j = 0; j < length-i-1; j++) {
if(compare(arr[j+1], arr[j])) {
swap(arr[j+1], arr[j]);
flag = 1;
}
}
}
}
參考資料:
C++ Gossip: 函式指標
《教學》typedef 知多少?
延伸閱讀:
typedef 與 link list的配合使用
2008年11月26日 星期三
IO - 使用string型態
要使用字串型態,必需要加入
#include <string>
empty():測試字串是否為空。
用==比較兩個字串是否相同。
且可以使用C-Style的字串指定給string。
string name("caterpillar");
char str[] = "justin";
name = str;
且可以用+運算子來串接字串。
str1 = str2 + str3;
str1 = str2 + "\n";
也可以用[]指定索引來存取相對應位置的字元,就有如字元陣列的操作一般。
assign(string,start,num):從string的第start個字元取出num個字元來指定給另一個字串物件。
append(string,start,num):從string的第start個字元取出num個字元來附加至另一個字串之後。
insert(start,string):將string插入引發insert的字串物件第start個字元之後。
length():傳回字串的長度。
find(string,0):從引發find的字串物件第0個字元尋找是否有符合string的子字串。
#include < iostream>
#include < string>
using namespace std;
int main(){
string s;
cout << "Please input a string include the space:";
getline(cin,s);
cout << "You typed:" << s << endl;
s.find("good",0);
string::size_type loc = s.find("good",0);
if (loc != string::npos){
cout << "In the sentence, there is keyword \"good\" "<< endl;
} else {
cout << "In the sentence, there is no keyword \"good\"" << endl;
}
return 0;
}
如果用cin來輸入的話,是以空白為分隔,
若要輸入中含空白,就必需使用gets。
c是用gets,但是會有問題,最好還是用getline比較好,也一樣可以得到相同的結果哩。
main.cpp
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
cout << "Please input a string include the space:";
getline(cin,s);
cout << "You typed:" << s << endl;
s.find("good",0);
string::size_type loc = s.find("good",0);
if (loc != string::npos){
cout << "In the sentence, there is keyword \"good\" "<< endl;
} else {
cout << "In the sentence, there is no keyword \"good\"" << endl;
}
return 0;
}
[2008.11.29 補充]
stringstream:可用於基本型態與string型態的轉換
main.cpp
#include <sstream>
#include <iostream>
using namespace std;
int main(){
int index = 5;
string str1;
stringstream sstr;
sstr << index;
sstr >> str1;
cout << "the answer is " << str1 << endl;
return 0;
}
[2008.12.19 補充]
要用string除了要包含string之外,還要用using namespace std;
[2008.12.19 補充]
另外,在C中要把數字轉成字串,可以使用sprintf
例
#include <stdio.h>
int main(){
int a=100;
char b='x';
char c[]="abcd";
char buf[100];
sprintf(buf,"%3d%c%s",a,b,c); // buf是轉換完後的儲存字串
printf("your input is %s\n",buf);
return 0;
}
[2009.03.16 補充]
眾所周知,sprintf不能檢查目標字符串的長度,可能造成眾多安全問題,所以都會推薦使用snprintf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int ac, char **av)
{
char *str;
int len;
// snprintf(NULL, 0, fmtstring, /* 其它參數 */ );
// 相對於sprintf安全的多
len = snprintf(NULL, 0, "%s %d", *av, ac);
printf("this string has length %d\n", len);
if (!(str = malloc((len + 1) * sizeof(char))))
return EXIT_FAILURE;
// 把後面的變數轉換成字串設定到str指標上
// 而len+1是後面總合長度的上限
// 超過上限的部分會被刪掉,不會印出來
len = snprintf(str, len + 1, "%s %d", *av, ac);
printf("%s %d\n", str, len);
free(str);
return EXIT_SUCCESS;
}
談談snprintf
[2009.03.22 補充]
char *strerror(int errno);
strerror, strerror_r - get error message string
若上一個函數有出現錯誤,會把錯誤號碼存到erron,可以透過strerror來取得代表此錯誤數字的訊息
網址
[2009.04.03 補充]
void perror ( const char * str );
會這把這一個字串列印在stderr,且會在最後面加'\n'的換行字元
int fprintf ( FILE * stream, const char * format, ... );
這是一個非常好用的函式,可以把後面的字串寫入到檔案中
另外有一個特殊用法,就是使用stdout,stderr可以值接設定是要輸出到哪裡
例:
fprintf(stdout,"Hello World!!");
fprintf(stderr,"Hello Error!!");
int vsprintf (char * str, const char * format, va_list arg );
int vsnprintf(char *restrict s, size_t n, const char *restrict format,va_list ap);
可以參考C/C++ : 不定長度引數(Variable-length argument)
參考資料:
C++ Strings
良葛格學習筆記
2008年11月25日 星期二
機車被拖吊日記~
今天下午把明天要去高雄報告的paper先看過一遍,
好,剛好我在圖書館預約的書「Qt程式設計」今天是最後一天了,一定要去領。
進去出來,我的機車不見了,看對面,有一台拖調車正在對面拖吊,
我一看,我的車剛好在上面,
趕快去拜託員警可不可以還我的車?
若是現在正在移的車子是可以還我,但是,是對面的機車的話,是沒有辦法還我的。
沒有辦法,為了不要坐計程車過去領車,我拜託他能不能讓我一起坐去拖吊場,最後他是答應了。
跟車上的工作人員聊了一下,其實,他們沒有拖越多,領越多的事情。不過,不知道有沒有業績壓力就是了。
回來之後,一直在想如何把這一個開銷賺回來。
是要少吃幾餐?還是在其它地方省下來?
最後,有一個感想,倒不如現在好好認真唸書,
以後,若可以的話,可以早一點出去工作。這才是真正的方法啊。
感想:
1. 多走幾步路找位置比較好。
2. 若真的要被拖吊時,這個時候一定要跟警察說有困難,一定要拖個五分鐘十分鐘,其實,外面還有很多台可以拖吊,他不一定要拖你這一台,反正就講說很可憐,學生沒有錢~在資料還沒有KEY到電腦前,都有機會。離拖吊場越遠,要回來的機會越大。到拖吊場的話,有很多其它人,機會會非常小。
3. 認真唸書,以後才可以真的賺錢。
4. 快把腳踏車修好,不要靠機車通勤了
5. 大約9~17都很危險。
這樣一共花了200(拖吊)+600(罰單)。
都可以買一本我要借的書了~還有剩哩~
最後看完這一本書,竟然也不是我要的,天啊,那我幹麻去借這一本啊
2008年11月22日 星期六
清晨學習的效果是深夜學習的六倍!
熬夜讀書不只沒用還有害
書讀到深夜很了不起嗎?不,完全不是。一但變成夜貓子,把深夜當成讀書時間,那麼不只學習效果不會提升,反而會把身體搞壞,精神上也會陷入空洞的狀態。因為深夜讀書違反了人類身為生物的自然原理。
控制內臟功能或體溫調節等等的身體功能,是我們體內的自律神經。自律神經裡面有交感神經和副交感神經,交感神經在活動或是緊張、興奮的時候會工作,而放鬆的時候則是副交感神經在工作。
白天主要是交感神經在工作,到了晚上交棒給副交感神經。副交感神經負責身體的修復與再生等等維修工作。交感神經則好好休息準備應付明天的工作。
至於深夜讀書的人,可以說是用副交感神經來讀書的。這樣就是把武器搞錯了。就好像拿著豆腐去打架一樣,實在很可笑。尤其是年輕人,特別容易產生深夜讀書很帥氣的錯覺,但深夜懶散的讀書,效果其實並不値得期待。
與其這樣,還不如早起短時間讀書,效果更好。
清晨的二十分鐘,相當於晚上的兩小時
夜晚比較領先的副交感神經大概是在天亮的時候,也就是清晨五點左右和副交感神經互換的。
因此盡量選擇五點左右,要是沒辦法就六點左右起床吧。好好的早起,先看看戶外的陽光。讓陽光接觸視神經,可以重新設定一整天的節奏,讓大腦跟身體認為「已經早上啦」,進而開始活躍起來。
原本人類的生理時鐘就是二十五小時。而一天只有二十四小時,所以如果放著不管,這一小時的偏差就會越來越嚴重,讓人變成夜貓子。更別說當今社會不管商店或電視,都是二十四小時的營業的。更加速了夜貓子的增加。
人類體內每秒有三億個生化反應在進行,如果交感神經和副交感神經沒有妥善運作,這些生化反應就不會順利進行。若早起的「晨間型的人」,自律神經的平衡也不會崩壞。而且在維護身心健康上,早起也非常有效。
每當建議大家在早上學習,有人會說「早上太忙了,沒辦法讀啦」,但是其實只要二十分鐘就好了。就像前面(我的前一篇文章)「分段模組學習」所提到的,二十分鐘其實是最有效率的學習時間。安排學習十五分鐘 + 複習檢查五分鐘。只要一個模組就可以了。這樣應該就辦得到了吧。
在學習方法論的世界裡面,認為在早晨,尤其是早餐之前進行學習,效果是深夜的六倍。也就是說早上一個模組二十分鐘的學習,效果可以與晚上的兩小時匹敵。
另外,每天早上學習二十分鐘,也能對自己建立一份小小的自信。
這麼做可以讓自己感覺到,自己心中的核心意識一天比一天穩固。
因為這樣就可以給自己一個小小歡呼,「我也是挺能幹的呢。」
只要二十分鐘的習慣,就可以徹底改變人生。讓我們打破「睡到快要遲到」的習慣吧。
如果不這麼做,不管是明年、後年,還是會一直賴床下去。
※養成清晨學習的習慣,人生將會大幅改觀。
參考資料:
▁▂▃▄ⓟⓔⓣⓔⓡⓙⓐⓜⓔⓢ▄▃▂▁
在程式中執行shell的指令
今天發現,可以在程式中執行shell的指令,
就跟awk指令一樣,可以在程式中執行shell的指令。
但是,目前還不知道能不能把執行的結果傳回程式中?
#include <iostream>
using namespace std;
int main(int argc, **char argv)
{
system("pwd");
return 0;
}
這個時候就會列印你目前的所在位置。
2008年11月21日 星期五
在linux下設定程式斷點
「聽說」在windows下,要設定斷點,只要在程式中加system("PAUSE");
不然的話,就必需要用IDE所提供的工具才可以去慢慢trace程式,
而我是比較習慣用vim寫程式,今天剛好找到一個可以提供讓程式先暫體的一個方法~
定義一個巨集,PAUSE
#include <stdio.h>
#define PAUSE printf("Press any key to continue..."); fgetc(stdin);
完整程式範例
#include <stdio.h>
#define PAUSE printf("Press any key to continue..."); fgetc(stdin);
int main(void)
{
PAUSE
printf("system(\"pause\") for Linux!\n");
return 0;
}程式雖然說按任何按鍵,但是,實際上只有按Enter才有效果。
我記得有一個函式是按任何按鍵就會有動作的~
下次有找到再補上吧~
噹噹~找到啦~如何在linux下實作一個getch()
在linux下沒有conio.h這一個檔案,所以,只好實作它啦~
請參考以下檔案。
debug.h
#ifndef _DEBUG_H
#define _DEBUG_H
#include <termios.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
/*------------------------------------------------*/
int getch(void) {
int c=0;
struct termios org_opts, new_opts;
int res=0;
//----- store old settings -----------
res=tcgetattr(STDIN_FILENO, &org_opts);
assert(res==0);
//---- set new terminal parms --------
memcpy(&new_opts, &org_opts, sizeof(new_opts));
new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
c=getchar();
//------ restore old settings ---------
res=tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
assert(res==0);
return(c);
}
#endif // _DEBUG_H
參考資料:
#define KNOWLEDGE FREE
在 Linux 上實作 C++ 在 VC++ 的 getch()
忘記linux的root的密碼的解決方法
如果是在redhat, fedora, centos可以用以下方法
方法一:
1.當開機出現到Grub的畫面是,先按一下"空白鍵space"去停止其運作!
2.之後按"
變成:"kernel /boot/vmlinuz-2.4.19-16mdk root=/dev/hda1 1"
3.按"B"按鈕離開,Linux就可以開到Run level 1(單人模式)囉!
4.Lilo的畫面就更簡單了!直接按下"Ctrl + X "後,輸入:"linux 1"就直接開進去囉!
5.進到單人模式後,就可以直接用"passwd root"指令去改root密碼囉!
方法二:
grub boot時按a,在command後面加 1 (s/S/single)
方法三:
用live CD或是rescue CD來boot, 使用single user mode, 之後chroot回去, 再來改root passwd
chroot是把某一個目錄當成開機目錄~
過程:
先把指定的磁區掛載到某一個目錄上。
以下的指令是把/dev/sda1這一個磁區掛載到/tmp這一個目錄上# mount -t ext3 -o remount,rw,auto /dev/sda1 /tmp
然後到/tmp/etc/shadow裡面修改root的密碼的那一個欄位,也就是第二個欄位,把它清空# vi /tmp/etc/shadow
這樣再重新啟動電腦,要用root進入時,他就不會詢問你密碼啦!
參考資料:
開機過程的問題解決
2008年11月17日 星期一
用電腦的人必須要瞭解的常識
OFFICE裡,電腦是我們最重要的一件辦公用品,很難想像,如果沒有了電腦,我
們將如何工作。但遺憾的是,當我們享受著電腦帶給我們的一切方便的同時,也不得不
接受它在身心兩方面對我們健康的威脅。所以,瞭解電腦「病」,防治電腦「病」,已
經成為我們刻不容緩的事情。為了全面瞭解電腦對OL身心的負面影響,我們特地組織這
次策劃,全面介紹緩解OL們最難逃脫的八大電腦「病」的竅門和方法。
罪狀一:電磁輻射
症狀:失眠、內分泌紊亂
致病原因:顯示器熱度過高,在工作時就會有相當多的電磁輻射,它會使空氣發生電離作用,不斷產生正電荷(正離子),並不斷與空氣中的負離子中和,導致負離子的含量幾乎為零。負離子多有益,正離子就多有害,長期處於正離子過多的環境中,它們通過呼吸進入肺,然後隨血液循環被輸送到人體的各個組織,使人的血液、體液呈酸性,延緩身體正常的代謝功能,使毒素囤積在體內。使人失眠、免疫力下降、女性內分泌紊亂等。
緩解方法
1.仔細地打掃辦公環境。因為正離子會牢牢地吸附在灰塵顆粒上,灰塵越多,則正離子越多。
2.多喝茶。茶葉中含有的茶多酚等活性物質,有助吸收放射性物質。
3.顯示器散發出的輻射多數不是來自它的正面,而是側面和後面。因此,不要把自己顯示器的後面對著同事的後腦或者身體的側面。
4.常喝綠茶。綠茶是近幾年來最為人所津津樂道的養生飲品,因為其中含強效的抗氧化劑兒茶酚及維他命C,不但可以清除體內的自由基,還能使副腎皮質分泌出對抗緊張壓力的荷爾蒙,對於情緒暴躁有很大改善。不過,最好在白天飲用,以免影響睡眠。
5.綠豆可清熱解毒、利尿消腫,薏仁則可以健脾止瀉、輕身益氣,經常需要熬夜工作或是心煩氣躁、口乾舌燥、便秘時,對於消除煩躁情緒非常有幫助。
6.勤洗臉可以防止輻射波對皮膚的刺激。
7.在電腦桌下擺放一盆植物或水,可以吸收電腦所發出的電磁波。
8.盡量使用液晶顯示器。
9.穿著防輻射肚兜。
罪狀二:灰塵場
症狀:皮膚過敏
致病原因:處於開機狀態的顯示器周圍會形成一個靜電場,它差不多會把整個房間的空氣中懸浮的灰塵吸入自己的場中,從而使得面部皮膚受到刺激,會出現過敏起疹等現象。坐在電腦前,你的周圍便充滿了含有大量灰塵顆粒的空氣,因此,使用者的皮膚非常容易產生皮疹等過敏現象。
緩解方法
1.不要在電腦周圍擺放堆積如山的紙和文件,應該把所有必需的文件分門別類地放進櫃子,因為紙張和文件上的灰塵通常不易清潔。
2.電腦桌表面用濕布蘸著抗靜電劑擦拭。
3.經常開窗通風。
4.使用電腦之前在臉上擦些保濕霜,或者用洋甘菊浸液浸濕毛巾(更簡單的方法是用濕的洋甘菊茶袋)直接敷在額頭和臉頰上。
5.在電腦桌上擺放一盆仙人掌,因為仙人掌的針刺能夠吸收灰塵。
6.經常清潔鍵盤,使用鍵盤時及使用後應先洗手再進食,不使用時用布將鍵盤遮蓋。因為鍵盤凹凸不平,非常容易積累灰塵,更會成為皮膚病病菌、感冒病菌隱藏的場所。
罪狀三:畫面閃爍、散發熱度造成環境乾燥
症狀:乾眼症
致病原因:雖然肉眼無法看出來,但事實上顯示器上的畫面是一直在閃爍的。看顯示器時,我們往往會長時間地盯著某一個點,很少眨眼,因此眼肌容易疲勞,眼黏膜發乾,眼睛發紅、發炎、疼痛。在電腦前不間斷工作4小時後,幾乎所有人的眼睛都會出現酸痛和沙眼的感覺。電腦工作者的工作環境密閉,環境中的濕度低,計算機不斷散發熱度,在乾燥環境下,淚液層幾秒鐘就蒸發掉了,成為干眼症的重要誘因。
緩解方法
1.距顯示器需要 70厘米以上,放置位置應比雙眼視線略低,並使眼球暴露於空氣中的面積減小到最低。
2.把亮度調整到不使眼疲勞的程度。
3.在電腦前工作時,房間既不能太昏暗,也不能太明亮。理想的辦公環境是-房間的亮度和屏幕的亮度相同。
4.因為要避免屏幕上顯現出你的臉、燈光以及物體的影像(所有的光影會加倍地使眼睛疲勞),所以,要避免室內的光線直接照射在屏幕上而產生干擾光線。光源最好來自電腦使用者的左邊或右邊。如果你戴眼鏡,應該給自己配一副帶有防反光加膜的鏡片。
5.為了防止結膜發乾,在使用電腦時滴一些與我們眼淚成分相同的眼藥水。
6.眼睛疲勞時,用以淡紅茶水煮過的濕巾敷幾分鐘眼睛,會很快消除充血和疲勞。
7.將黑豆500克,炒熟後待冷,磨成粉。核桃仁500克,炒微焦去衣,待冷後搗如泥。取以上兩種食品各1匙,衝入煮沸過的牛奶1杯後加入蜂蜜1匙,早晨或早餐後服食。能增強眼內肌力,加強調節功能,改善眼疲勞的症狀。
罪狀四:長期使用鼠標
症狀:鼠標手(即腕關節綜合征)
致病原因:長期使用電腦鍵盤和鼠標,可能與一種稱為腕關節綜合征的疾病掛上鉤,出現食指或中指疼痛、麻木和拇指肌肉無力感,發展下去可能導致神經受損,進而引起手部肌肉萎縮。問題出在每天重複在鍵盤上打字或移動鼠標,手腕關節長期、密集、反覆和過度活動,導致周圍神經損傷或受壓迫,使神經傳導被阻斷,從而造成手掌的感覺與運動發生障礙。另外,肘部經常低於手腕,而手高高地抬著,神經和肌腱經常被壓迫,手就會開始發麻,手指失去靈活性,經常關節痛。手指頻繁地用力,還會使手及相關部位的神經、肌肉因過度疲勞而受損,造成缺血缺氧而出現麻木等一系列症狀。據調查,女性發生「鼠標手」比男性多,這是因為,女性手腕通常比男性小,腕部正中神經容易受到壓迫。
緩解方法
1.盡量避免上肢長時間處於固定、機械而頻繁活動的工作狀態下,使用鼠標或打字時,每工作一小時就要起身活動活動肢體,做一些握拳、捏指等放鬆手指的動作。
2.使用電腦時,電腦桌上的鍵盤和鼠標的高度,最好低於坐著時的肘部高度,這樣有利於減少操作電腦時對手腕的腱鞘等部位的損傷。
3.使用鼠標時,手臂不要懸空,以減輕手腕的壓力,移動鼠標時不要用腕力而盡量靠臂力做,減少手腕受力。
4.不要過於用力敲打鍵盤及鼠標的按鍵,用力輕鬆適中為好。
5.鼠標最好選用弧度大、接觸面寬的,有助力的分散。
6.使用鼠標時配合使用「鼠標腕墊」墊在手腕處。
罪狀五:腦功能減弱
症狀:記憶力帥退
致病原因:隨著個人電腦的日益普及,人們正越來越多地受到記憶力減退的困擾,主要原因是他們對電腦的依賴過強,從而使得自己的腦功能反而減弱。
緩解方法
1.睡前平躺在床上,全身放鬆,將頭仰放在床沿以下,緩解大腦供血及供氧的不足。
2.保證充足的睡眠。不論工作有多緊張,每日8小時的睡眠是必不可少的,而且要盡量保證睡眠質量,使大腦皮層的血液循環得到適時的調節。
3.靜想練習。最好每天能有20-30分鐘時間靜想生活中輕鬆美好的事情,聆聽自己呼吸的節律,讓情緒盡量放鬆。姿勢不拘,或坐或臥,以舒適為準。
4.平時能用手寫的文字就盡量不要使用電腦輸入,即便一定需要電子文件,也可以盡量使用手寫板輸入文字。
5.改變不健康的飲食結構,多食用健腦食品。
罪狀六:長時間採用不正確坐姿
症狀:頸、肩、腰部疼痛
致病原因:如果使用電腦時高高地架著胳膊,低著頭,並且在桌子下艱難地蹺著二郎腿,那麼,工作一小時你就會感到腰背酸痛,脖子和肩膀麻木,手臂也不靈活。這樣的坐姿保持一年至一年半,你就可以獲得雙下巴、頸椎關節僵硬。
緩解方法
1.上半身應保持頸部直立,使頭部獲得支撐,兩肩自然下垂,上臂貼近身體,手肘彎曲呈90度,操作鍵盤或滑鼠,盡量使手腕保持水平姿勢,手掌中線與前臂中線應保持一直線。下半身腰部挺直,膝蓋自然彎曲呈90度,並維持雙腳著地的坐姿。
2.必須選擇符合人體工學設計的桌椅,使用專用的電腦椅,坐在上面遵循「三個直角」:電腦桌下膝蓋處形成第一個直角,大腿和後背是第二個直角,手臂在肘關節形成第三個直角。肩胛骨靠在椅背上,雙肩放下,下巴不要靠近脖子。兩眼平視電腦螢幕中央,座椅最好有支持性椅背及扶手,並能調整高度。
3.放風箏:放風箏時,挺胸抬頭,左顧右盼,可以保持頸椎、脊柱的肌張力,保持韌帶的彈性和脊椎關節的靈活性,有利於增強骨質代謝,增強頸椎、脊柱的代償功能,既不損傷椎體,又可預防椎骨和韌帶的退化,實在是老祖宗留給我們防治頸椎病的一個好方法。
4.游泳:因為游泳的時候頭總是向上抬,頸部肌肉和腰肌都得到鍛煉,而且人在水中沒有任何負擔,也不會對椎間盤造成任何的損傷,算得上是比較愜意的鍛煉頸椎的方式。
5.使用電腦每隔一小時應休息5至10分鐘,做柔軟操或局部按摩,同時養成規律運動習慣,針對肩頸、上肢進行拉筋及肌力訓練,以增加柔軟度及肌力。
6.電腦的擺放高度要合適。將電腦屏幕中心位置安裝在與操作者胸部同一水平線上,最好使用可調節高低的椅子。應有足夠的空間伸放雙腳,膝蓋自然彎曲呈90度,並維持雙腳著地,不要交叉雙腳,以免影響血液循環。
7.眼睛與顯示器保持恰當的距離。眼睛與電腦顯示器形成輕度向下注視螢光屏的角度,這樣可使頸部肌肉得到放鬆。
8.舒緩體操
A:基本姿勢:
每次做各項訓練動作前,先自然站立,雙目平視,雙腳略分開,與肩同寬,雙手自然下垂。全身放鬆。
B:前俯後仰:
雙手叉腰,先抬頭後仰,同時吸氣,雙眼望天,停留片刻;然後緩慢向前胸部位低頭,同時呼氣,雙眼看地。做此動作時,要閉口,使下頜盡量緊貼前胸,停留片刻後,再上下反覆做4次。動作要旨是:舒展、輕鬆、緩慢,以不感到難受為宜。
C:左右旋轉:
雙手叉腰,先將頭部緩慢轉向左側,同時吸氣於胸,讓右側頸部伸直後,停留片刻,再緩慢轉向右側,同時呼氣,讓左邊頸部伸直後,停留片刻。這樣反覆交替做4次。
D:提肩縮頸:
做操前,先自然站立,雙目平視,雙腳略分開,與肩平行,雙手自然下垂。
動作時雙肩慢慢提起,頸部盡量往下縮,停留片刻後,雙肩慢慢放鬆地放下,頭頸自然伸出,還原自然,然後再將雙肩用力地往下沉,頭頸部向上拔伸,停留片刻之後,雙肩放鬆,並自然呼氣。注意在縮伸頸的同時要慢慢吸氣,停留時要憋氣,鬆肩時要盡量使肩、頸部放鬆。回到自然式後,再反覆做4次。
E:左右擺動:
做操前,先自然站立,雙目平視,雙腳略分開,與肩平行,雙手叉腰。動作時頭部緩緩向左側傾斜,使左耳貼於左肩,停留片刻後,頭部返回中位;然後再向右肩傾斜,同樣右耳要貼近右肩,停留片刻後,再回到中位。這樣左右擺動反覆做個4次。在頭部擺動時需吸氣,回到中位時慢慢呼氣,做操時雙肩、頸部要盡量放鬆,動作以慢而穩為佳。
罪狀七:思維形成定式,不習慣與人相處
症狀:電腦憂鬱症
致病原因:長時間的電腦操作形成「非此即彼」的思維定式,不習慣與人達成妥協和諒解,喪失自信,身心疲憊,以致工作難以展開。
緩解方法
1.做好自我心理調整,及時糾正思維方式。
2.積極處理好人際關係,尤其與同事的關係。
罪狀八:過度依賴電腦而情緒緊張煩躁
症狀:電腦躁狂症
致病原因:由於對電腦過度依賴,所以當電腦出現故障後,會精神緊張,情緒煩躁、不安,甚至有對電腦「動武」的傾向,如通過用力敲打鍵盤、鼠標,大罵電腦,摔砸電腦等方式發洩怒火,有的還將不滿情緒發洩在家人或同事身上。
緩解方法
1.一旦電腦出現故障,立即找專業人士來維修,避免獨自坐在電腦桌前,應當盡快轉移視線和注意力,放鬆心情。
2.隨時保存工作文檔,用移動硬盤將資料備份,這樣一旦電腦出現問題,不會受到太大損失,情緒不至於驟然失控。
3.不要長時間坐在電腦前工作,每隔一段時間走開喝杯茶、咖啡或活動一下四肢。
電腦一族的健康食品
健腦元素
1.脂肪:它是健腦的首要物質。它在發揮腦的複雜、精巧的功能方面具有重要作用。代表性食物有堅果、芝麻、自然狀態下飼養的動物等。
2.蛋白質:它是智力活動的物質基礎,是控制腦細胞興奮與抑制過程的主要物質。代表性食物有瘦肉、雞蛋、魚類等。而碳水化合物是腦活動的能量來源,它在體內分解為葡萄糖後,即成為腦的重要能源。代表性食物有雜糧、糙米、紅糖、糕點等。充足的維生素C可以使大腦功能靈活、敏銳,並提高智商。代表性食物有鮮果類、黃綠色蔬菜等。
3.B族維生素:它是智力活動的助手。包括維生素B1、維生素B2、葉酸等,當B族維生素嚴重不足時,就會引起精神障礙,易煩躁,思想不集中,難以保持精神安定。代表性食物有香菇、野菜等。堅果含有大量的蛋白質、不飽和脂肪酸、卵磷脂、無機鹽和維生素,經常食用,對改善腦營養供給很有益處。香菇對高血壓、動脈硬化有較為明顯的療效,有消除疲勞、提神、穩定精神、防止貧血和癌症等功效。
4.雞蛋:它含有豐富的蛋白質、卵磷脂、維生素和鈣、磷、鐵等,是大腦新陳代謝不可缺少的物質。
天將降大任於是人也
用這一句話來鼓勵自己吧,但是,遇到困難,還是要試著找出路~
【原文】
孟子曰:「舜發於畎畝之中,傅說舉於版築之閒,膠鬲舉於魚鹽之中,管夷吾舉於士,孫叔敖舉於海,百里奚舉於市。故天將降大任於是人也,必先苦其心志,勞其筋骨,餓其體膚,空乏其身,行拂亂其所為,所以動心忍性,曾益其所不能。人恆過,然後能改;困於心,衡於慮,而後作;徵於色,發於聲,而後喻。入則無法家拂士,出則無敵國外患者,國恆亡。然後知生於憂患而死於安樂也。」
【註釋】
[1]畎(quan)畝:田間,田地。[2]傅說(yuo):殷武丁時人,曾為刑徒,在傅險築牆,後被武丁發現,舉用為相。[3]版築:一種築牆工作, 在兩塊牆版中,填人泥土夯實。[4]膠鬲(ge):殷紂王時人,曾以販賣魚、鹽為生,周文王把他舉薦給紂,後輔佐周武王。[5]管夷吾:管仲。士:此 處指獄囚管理者。當年齊桓公和公子糾爭奪君位,公子糾失敗後,管仲隨他一起逃到魯國,齊桓公知道他賢能,所以要求魯君殺死公子糾,而把管仲押回自己處理。魯君於是派獄囚管理者押管仲回國,結果齊桓公用管仲為宰相。[6]孫叔敖:是春秋時楚國的隱士,隱居海邊,被楚王發現後任為令尹(宰相)。[7]百里奚舉於市:春秋時的賢人百里奚,流落在楚國,秦穆公 用五張羊皮的價格把他買回,任為宰相,所以說「舉於市」。[8]曾:同「增」。[9]衡:通「橫」,指橫塞。[10]征:表徵,表現。[11]法家拂士:法家,有法度的大臣;拂,假借為「弼」,輔佐;拂士即輔佐的賢士。
【譯文】
孟子說:「舜從田間勞動中成長起來,傅說從築牆的工作中被選拔出來,膠鬲被選拔於魚鹽的買賣之中,管仲被提拔於囚犯的位置上,孫叔敖從海邊被發現,百里奚從市場上被選拔。所以,上天將要把重大使命降落到某人身上,一定要先使他的意志受到磨練,使他的筋骨受到勞累,使他的身體忍饑挨餓,使他備受窮困之苦,做事總是不能順利。這樣來震動他的心志,堅韌他的性情,增長他的才能。人總是要經常犯錯誤,然後才能改正錯誤;。心氣鬱結,殫思極慮,然後才能奮發而起;顯露在臉色上,表達在聲音中,然後才能被人瞭解。一個國家,內沒有守法的大臣和輔佐的賢士,外沒有敵對國家的憂患,往往容易亡國。由此可以知道, 憂患使人生存,安逸享樂卻足以使人敗亡。」
【讀解】
吃得苦中苦,方為人上人。
孟子所舉的例證是舜帝、傅說、膠鬲、管仲、孫叔敖、百里 奚六人。其實,為人所熟知的,還有姜子牙的故事。
所謂「天將降大任於是人也,必先苦其心志……」云云,成 為《孟子》最著名的篇章之一,後人常引以為座右銘,激勵無數志士仁人在逆境中奮起。其思想基礎是一種至高無上的英雄觀念 和濃厚的生命悲劇意識,一種崇高的獻身精神。是對生命痛苦的認同以及對艱苦奮鬥而獲致勝利的精神的弘揚。
借用悲劇哲學家尼采的話來說,是要求我們「去同時面對人 類最大的痛苦和最高的希望。」(《快樂的科學》)
因為,痛苦與希望本來就同在。
說到生於憂患死於安樂,太史公說得好:
周文王被拘美裡而演《周易》,孔子困陳蔡而編《春秋》,屈 原遭流放而賦《離騷》,左丘明失明而寫《國語》,孫胺腳殘而著 《兵法》,呂不韋遷蜀地而出《呂覽》,韓非子被秦國囚有《說難》、 《孤憤》,《詩經》三百篇,大多都是發憤所作。(《史記‧太史公 自序》)
之所以如此,正是因為他們身處逆境的憂患之中,心氣鬱結, 奮發而起,置之死地而後生的緣故。
至於死於安樂者,歷代昏庸之君,荒淫逸樂而身死國亡,其 例更是不勝枚舉。
所以,對人的一生來說,逆境和憂患不一定是壞事。生命說 到底是一種體驗。因此,對逆境和憂患的體驗倒往往是人生的一筆寶貴財富。當你回首往事的時候,可以自豪而欣慰地說:「一切都經歷過了,一切都過來了!」這樣的人生,是不是比那些一帆風順,沒有經過什麼磨難,沒有什麼特別體驗的人生要豐富得多,因 而也有價值得多呢?
2008年11月15日 星期六
2008年11月12日 星期三
在ubuntu下看影音檔
看rm,rmvb檔
安裝real player
先到RealPlayer官方網站下載:
RealPlayer10GOLD.bin保存到自己資料夾裡面,即/home/[yourusername]下。
打開终端機:
[user@host ~]$ chmod +x RealPlayer10GOLD.bin
[user@host ~]$ sudo ./RealPlayer10GOLD.bin
顯示
Welcome to the RealPlayer (10.0.8.805) Setup for UNIX
Setup will help you get RealPlayer running on your computer.
Press [Enter] to continue...
enter進入下一步:
Enter the complete path to the directory where you want
RealPlayer to be installed. You must specify the full
pathname of the directory and have write privileges to
the chosen directory.
Directory: [/home/shixinyu/RealPlayer]:
預設安装到使用者資料夾下的RealPlayer目錄下,如果你想要安装到别處,就在此處輸入路徑
You have selected the following RealPlayer configuration:
Destination: /home/shixinyu/RealPlayer
Enter [F]inish to begin copying files, or [P]revious to go
back to the previous prompts: [F]: F
按下F即可。
Copying RealPlayer files...configure system-wide symbolic links? [Y/n]:
按下Y即可,基本上就安装好了,你可以到“應用程式,影音”下找到RealPlayer10
如果RealPlayer無反應,Ubuntu安装的是SCIM输入法,SCIM與RealPlayer的衝突,要修改:
[user@host ~]$ sudo gedit /home/[username]/RealPlayer/realplay \\[username]你的資料夾名字
在打開的文本编辑器的第一行加入下面這一行
export GTK_IM_MODULE=xim
------------------------------------------------
看avi
安裝vlc
[user@host ~]$ sudo apt-get install vlc
------------------------------------------------
看mpeg
[user@host ~]$ apt-get install libxine1-ffmpeg
參考資料:
這裡
[Ubuntu]用xine 看avi
2008年11月11日 星期二
會做事,更要會做人
T公司為了幫助主管能力往上提升,高薪挖了一位大企業的主管「空降」來當副總,人家果然是大企業出身,他的工作能力及效率之快真是沒話說,可是他有一個毛病卻是讓大家很受不了,每次一開口就說:「我以前公司的規模多大,資源有多豐富,我底下有好幾十人,我們效率有多高,你們真的要加油。」有次老闆實在是聽不下去了,就直接嗆他:「現在你的手下只有兩個人,這就是你的公司,你能做好才能活下去。」
【手無寸鐵,有本事才利害】
就是有這種人,誰管你以前是多利害,你現在的環境才是最現實的世界,好好的針對眼前的任務去想一想該如何達成?別用嘴巴吹了!動手吧!
看到卸任總統「一點權力都沒有」,很多人非常感慨吧?別老是緬懷以前自己的風光,那些你回家在床上自己慢慢想,人家沒興趣聽。你以前有多風光都過去了,
如今來到這裡「一切歸零」重新開始,我們不想聽,只想看你表演!
這位新主管的EQ真的有問題,我發現他們以前公司太注重績效了,所以把他們訓練成猶如「沒人性」的機器人,現在身處「要什麼沒什麼」的小公司,才曝露出他的「做人」有問題,其實「你會做事全靠公司資源,你要做人只得靠自己」,這一點可能那些大企業的員工都不懂。
【是誰欺負誰?等著瞧】
目前我輔導公司會把重心放在「品格修練」,至於「制度化」反而是其次,這個時代的確有許多人的人格都有偏差,包括老闆自己,何謂「偏差」?就是「思想不正」,舉例說,你只看到自己的利益,確枉顧別人利益,還有,你只看別人缺點,卻對人家優點隻字不提,這種人甚至也唸到博士,不信?你看政論節目那些名嘴,不就是這付德行?
上個月85度C連鎖店的工讀生檢舉公司給他們的時薪太低,老闆一付無辜出來解釋:「你應徵時自己還簽字同意這條件才上班的,怎可以事後反悔去抗議?你不接受就不要上班啊?我又沒拿槍押著你來!」
遇到這種員工,老闆絕對是輸的,因為大家同情弱者,據我知道,有些老闆好可憐的,因為負債累累,連房子都被拍賣了,別以為老闆多風光啊?
【別只顧賺錢,做人也要用心】
我想很多老闆都有被不肖員工「恐嚇」(檢舉、發黑函)的經驗,但有的確實是老闆自己不對,所以才讓員工忍無可忍報復,在我看來,更多是雙方的誤會所致。
做人本來就是很主觀的一種藝術,「誰負了誰」有時候很難認定,那就有各自解讀之空間,這時候一定要「往善意想」,不然就是所謂的「誤會」。
如果去「欺負」別人本來就是不對,像是我前不久發生車禍,對方公司竟然全推給自己員工(我是被車子撞的,又不是被人撞),這真的一點擔當也沒有,如果你的員工得到奧運冠軍,你是否也推說「與我無關」?如果他們公司發生車禍,別人也這樣對待時,他們如何想?(自己將心比心吧!)
這是一家上市大企業,老闆知道嗎?我會告訴他的,連老闆都要教育一下「做人的道理」!
2008年11月10日 星期一
虛擬作業系統 - Virtual Box
VirtualBox主網址
在Windows下虛擬作業系統軟體最好用的就是VMWARE。
而在Linux下最好用的就是VirtualBox,是免費的,但是,在Windows下可能會比較不穩定
解決方法如下:
1. 加入 usbfs群組
[user@host ~]$ sudo groupadd usbfs
2. 檢查 usbfs 群組的 gid
[user@host ~]$ cat /etc/group | grep usbfs
usbfs:x:1002:
3. 把目前的使用者加入 usbfs 群組
[user@host ~]$ sudo gedit /etc/group
把usbfs:x:1002: 修改為usbfs:x:1002:youraccount / * youraccount請改成自己帳號 * /
4. 更改USB裝置權限,編輯 /etc/fstab 檔案,並增加以下兩行,這邊要注意一下gid,可能不是1002
[user@host ~]$ sudo gedit /etc/fstab
在最下方加入
# 1002 is the USB group IDI
none /proc/bus/usb usbfs devgid=1002,devmode=664 0 0
5. 接下來重新啟動就ok啦~
使用方法:插入USB後,點 VirtualBox 右下角的USB圖示,選擇已辨識的USB裝置。
注意:在 Guest使用USB前,記得先卸載Host的USB,之後重開系統。
參考資料:
Ubuntu環境使用Virtualbox安裝Windows XP過程分享
在Ubuntu 7.10中安裝VirtualBox
[Ubuntu] VirtualBox 1.5
軟體試用達人必備工具 - VirtualBox 虛擬多個作業系統完全攻略
[Ubuntu] VirtualBox
給VirtualBox的vdi文件瘦身
裝上VirtualBox
虛擬機器VirtualBox
2008年11月8日 星期六
王永慶手稿語錄
*萬事先求知,有知才有覺,即不知就不覺。
*制度好,可以使壞人無法橫行;制度不好,可以使好人無法充分做 好事,甚至會走反面。
*經營者要有改革的心;經營者要有利人利己的胸襟。
*由儉入奢易,由奢入儉難。
*從做中學習,有壓力才有效率,有競爭才有進步。
*要控制自己表現在外面和隱藏在裡面的脾氣、要有奉獻自己的身心;工作比以往更賣力,更要超過自己,這是真正的理想。
*我們不要先求勝過別人,不妨先求超過自己,要打破自己原先紀錄,今天要勝過明天,更要能禁得起考驗。
*在比賽中打倒旁人或被人打倒有一點差別,不過打倒自己的紀錄,更有意義,不管是勝是敗,我們有了進步,這是最重要的,我們在人生競賽中要有更佳的表現。
*致富思源,富而思進,中國要告別貧窮的歷史,亦要迎向一個均富的未來,即富者造均富之道。
*從每日生活所做所為感受改革。
*學而後知,不學而不知,不知以為知,即天下大亂之主因也。
*人生在世,有始有終,貧寒富貴,悲喜哀樂,猶如苦海,波浪層層相接,情長辭短,難以陳述。
*人生活一日,便盡一日本分,一旦死去則氣散,歸天地,亦無遺憾。所謂善我生,善我死,春蠶到死絲方盡,非到燈黃油乾,不應止也。
*富助貧,強讓弱,地球村願景,終能成。
*大家都想幫助別人,但不知如何做,要有工作經驗體會,才能達成。*勤勞樸實,貢獻社會,追根究柢,止於至善,要能體會勤勞樸實,就要做有用的事,做有意義的事,就能啟發。
2008年11月6日 星期四
vista的休眠功能開啟
最近覺得xp的休眠功能超棒的~
開機之後,不用等很久,馬上可以執行動作~
耶,但是在vista怎麼一直打不開哩?
研究了一下,原來我在清硬碟的時候,把休眠的檔案刪掉了~
打了一下的指令就可以使用休眠的功能了~
不過,記得要去電源管理設定休眠喔~
1.開始->程式集->附屬應用程式->命令提示字元
2.鍵入->Powercfg/hibernate on
或
powercfg /a
喔耶~
順便介紹一下相關的知識吧~
在Windows XP中,電腦關機跟待機狀態可分為「關機」、「待命」與「休眠」三種:
關機:完整關機,完全關閉電腦電源,開(關)機速最慢。
待命:將目前狀態儲存至記憶體中,開(關)機速度最快,但主機板與記憶體需持續供電。
休眠:將目前狀態儲存至硬碟中,開(關)機速度較慢,主機板、記憶體與硬體週邊不用供電。
在Windows Vista中,有「休眠」、「睡眠」跟「交互式睡眠」三種模式:
睡眠:跟XP中的「待命」類似,將目前狀態儲存至記憶體中,開(關)機速度最快,但主機板與記憶體需持續供電。
休眠:跟XP中的「休眠」一樣,將目前狀態儲存至硬碟中,開(關)機速度較慢,主機板、記憶體與硬體週邊不用供電。
交互式睡眠:又稱「混合式睡眠」,此功能混合睡眠+休眠的功能,先將目前狀態儲存於記憶體中,再將相關資訊也儲存一份到硬碟中,避免因為睡眠期間電腦不正常斷電而使得資料遺失。
參考資料:
VAIO TZ 為何沒有休眠模式?怪了~
NB的休眠和睡眠有什麼差別????
2008年11月4日 星期二
在linux下錄影畫面
寫了一個程式,本來打算用圖片照起來,
但是,圖片不會有滑鼠,
所以,打算用錄的,
找到一個好像不錯的linux下的錄影軟體XVidCap,
但是一直出現錯誤~說什麼套件相依錯誤~
沒有辦法,只好先用vmware的錄影功能,
XVidCap以後有空再處理~
因為下載deb檔沒有辦法直接安裝,所以,必需要下載程式碼重新編譯~
下載程式碼之後,要先透過configure看系統是否滿足編譯的環境…
[user@host ~]$ ./configure
會出現以下缺少的元件:
No package 'gtk+-2.0' found
No package 'libglade-2.0' found
透過ubuntu下載套件,若不是ubuntu的話,redhat不知道能不能用yum下載套件
[user@host ~]$ sudo apt-get install libgtk2.0-dev
[user@host ~]$ sudo apt-get install build-essential
[user@host ~]$ sudo apt-get install libglib2.0-dev
[user@host ~]$ sudo apt-get install libglade2-dev
重新打configure會產生Makefile檔案
[user@host ~]$ ./configure
打make install 直接執行安裝
[user@host ~]$ sudo make install
參考資料:
推薦一款屏幕錄製軟件──xvidcap!
教學錄製 Xvidcap
Linux 下的桌面操作錄影軟體 - XvidCap
Xvidcap 1.1.7發佈
7-11 用XVidCap來桌面錄影
2008年10月25日 星期六
發展計畫書&品質計畫書
計畫書的目標(發展計畫書&品質計畫書)
1. 安排發展的活動,使得可以成功且及時的完成專案,並且預估需要的人力和預算
2. 根據前項的預估 ,來召募人員和分配資料
3. 評估風險
4. 實作SQA (Software Quality Assurance)的活動
5. 提供給管理階層所要下決策需要的資料
發展計畫書的項目
1. Project products (專案會產生出什麼東西,和要給客戶什麼東西)
a. 計設的文件
b. 完成的軟體產品(完成的時間、安裝軟體的地點)
c. 訓練的文件(時間、地點)
2. Project interface (若與其它系統溝通,要定義的介面)
a. 與其它軟體的溝通介面
b. 與同專案的其它軟硬體溝通的介面
c. 與其它硬體溝通的介面
3. Project methodology and development tools for each phase (在每一個階段要使用的發展方法與發展工具)
4. Software development standards and procedures (發展的標準與程序)
列出所有要用到的軟體發展程序的標準
5. The mapping of the development process:發展程序的時程表
a. 估計每一個活動的時間
b. 每一個活動與其它活動的相關性(甘特圖)
c. 估計每一個活動所需要的專業資源
6. Project milestones (里程碑)
每一個里程碑要完成的時間和產品
7. Project staff organization (員工組織)
a. Organizational structure (組織架構):參與的人員(包含承包商的人員)
b. Professional requirements (專業的需求):像是CMMI的資格啦~
c. 每一個活動需要的人員數
d. Names of team leaders and team members:透過name了解這一個team主要是在做什麼事情
8. Development facilities (所需要的設備,包含軟硬體)
9. Development risks (研發所會遇到的風險)
a. Technological gaps (技術差距)
b. Staff shortages (人員不足)
c. Interdependence of organizational elements (組織之間互相的依賴):像是承包商的進度會影響到主要的進度
10. Control methods (收集專案資料以便讓專案管理者了解情況)
11. Project cost estimation (估計專案需要的成本)
品值計畫書的項目
1. Quality goals (品質目標):最好用量化來說明需要達到的水準,不要說錯誤要很低,要說在100年內只能出一次錯,這樣的量化。
2. Planned review activities (計畫審查活動):包含design reviews (DRs)、design inspections、code inspections...
a. 審查活動的範圍
b. 審查活動的類型
c. 審查活動的排程
d. 審查活動的細節
e. 誰要負責審查活動
3. Planned software tests (軟體測試計畫)
a. 單元測試、整合測試、完整系統測試
b. 軟體測試的型態,包含電腦規範、用軟體來測試
c. 測試活動的時間排程
d. 特定的程序要實現
e. 誰負責測試活動
4. Planned acceptance tests for externally developed software (對額外要用到的軟體作可靠度測試)
a. 購買的軟體
b. 承包商所開發出來的軟體
c. 客戶提供的軟體
5. Configuration management (建構管理):必須說明要整個專案控制進度使用的軟體和程序是什麼
「問題」:小專案是否要development plans and quality plans?
1. 若根本不需要的專案,像是15天就可以完成的專案就不需要。
2. 依據此專案是若失敗是否會損失很大;若不會很大,則不需要計畫書;若會損失很大,則需要計畫書
3. 某一些專案計畫書是責任也是義務
小專案所需要注意的事項
The development plan:
a. Project products, indicating "deliverables"
b. Project benchmarks
c. Development risks
d. Estimates of project costs
The quality plan:
a. Quality goals
若設計給公司內部使用的系統,是否需要計畫書?
優點:
a. 避免被否絕預算
b. 避免對其它公司的專案、造成傷害
c. 避免對公司的決策出現錯誤
對內部員工的好處:
1. 比較能按照進度日完成,且比較不容易被否絕這一個提案
2. 若會延遲可以提早知道;並且可以早一點嘗試解決問題
3. 較少對內部造成傷害
對組織的好處:
1. 降低市場損失的風險
2. 降低因延遲使得公司被起訴的風險
3. 降低損壞公司的名聲
4. 降低增加預算的風險
2008年10月21日 星期二
C風格字串
C風格字串沒有什麼特別之處,只是char型態的陣列,最後一個字元是0,這個最後的字元是標記字串的結束。
建立C風格字串時,可以建立char型態的陣列,並將字串中的每一個字元指定給陣列中的元素,然後加上一個0,表示為'\0'代表字串的中止符號,標記字串結束。
建立字串有以下兩個方法
#include <iostream>
using namespace std;
int main()
{
char word[] = {'H' , 'e' , 'l' , 'l' , 'o' , '\0'};
char string1[] = "Hello";
cout << string1 << endl;
return 0;
}
其它字串function:
尋找字串:strstr
比較字串:strcmp
連結字串:strcat
拷貝字串:strcpy
將整數轉換成字串:itoa
將字串轉換成整數:atoi
將字串轉換成float:atof
傳回字串的長度:strlen
將一個數格式化為一個字串,該函數的用法是:
sprintf(string,format,list)
string是將要顯示的字串,format是表明格式化結果的轉換字串,為list中的每一個元素都指定轉換字串。可能在使用socket時會用到~
用cin的方法讀取C風格的字串
#include <iostream>
using namespace std;
int main()
{
const int total = 50;
char string1[total];
cout << "Type some words: ";
cin.getline(string1,total);
cout << "You typed: " << string1 << endl;
return 0;
}
該方法讀取的字元數為傳入的數目減1,因為,必須考慮到串尾的'\0'的空間。
將儲存字串的C風格的字串以及要讀取的最大字元傳入到cin.get (cin.get將一直讀取到最大的字元數減1,或者使用者按下Enter)。
需要注意一點:cin.get一直讀取,直到有一個終止符號'\n',但是,不讀取'\n'。要將'\n'從輸入緩衝區清除時,可以使用方法cin.clear,或者再次呼叫cin.get。
#include <iostream>
using namespace std;
int main()
{
const int total = 50;
char string1[total];
cout << "Type some words: ";
cin.get(string1,total).get();
cout << "You typed: " << string1 << endl;
return 0;
}
在C++中如果以""來包括一串文字的話,即為字串字面常數,例如"Hello! World!"就是字串字面常數,字串字面常數由字元陣列組成,每一個字串最後會以一個null字元結束。
2008年10月20日 星期一
把圖轉成xpm格式
氣在在寫qt的拖曳程式,
在拖曳的時候有時候就會出現小圖案~
而這個小圖案是以xpm的型式寫在程式裡面~
目前還沒有成功啦~先把網址記錄下來~
一成不變的GRUB開機splash看久了也會挺膩的,如果各位跟我ㄧ樣有這樣的問題時,可以準備一張640×480 16 色的圖片,便可以輕易的改裝你的splash了。製作方式如下:
(1) 準備一張640×480 16色圖片,檔案類型為JPG的格式
(2) [root@Fedora figaro]# convert -geometry 640×480 -colors 14 Image.jpe Image.xpm
(3) [root@Fedora figaro]# gzip -9 Image.xpm
(4) [root@Fedora figaro]# cp Image.xpm.gz /boot/grub
(5) 修改 /boot/grub/menu.lst,將splashimage=(hd0,0)/grub/splash.xpm.gz,把splash.xpm.gz改成我們剛才製作好的 Image.xpm.gz。完工^^
GRUB splash.xpm.gz 圖檔製作
QT - drag and drop
以上就是這一個範例程式的介面~
共會有三個這個介面,可以由其中一個拖曳到另一個DropSite~
DropSite就是要讓別人拖曳到的地方。
Secret Source可以拖曳到DropSite,會出現the secret number is X,但是拖曳到其它地方,滑鼠會出現禁止的符號~
QStoredDrag::QStoredDrag ( const char * mimeType, QWidget * dragSource = 0, const char * name = 0 )
mineType應該是說此Drop有支援mimeType這一個類型
void QWidget::setAcceptDrops ( bool on ) [virtual]
設置對於這個窗口元件按滑鼠事件是否生效為on。
void QWidget::dragEnterEvent ( QDragEnterEvent * ) [virtual protected]
當一個拖動正在進行並且鼠標進入這個窗口元件,這個事件處理器被調用
QDragObject Class
用來封裝:主要是用來當在application與application之間拖曳、或是使用在剪貼功能上
QDropEvent::Action
QDropEvent::Copy - The default action. The source simply uses the data provided in the operation.
QDropEvent::Link - The source should somehow create a link to the location specified by the data.
QDropEvent::Move - The source should somehow move the object from the location specified by the data to a new location.
QDropEvent::Private - The target has special knowledge of the MIME type, which the source should respond to in a similar way to a Copy.
預設值是Copy,也就是說,當由一個地方拖曳到另一個地方,是會在新的地方建立一個新的元件
const char * QDropEvent::format ( int n = 0 ) const [virtual]
傳回目前的drag可以支援的型式
通用資源標誌符(Uniform Resource Identifier, 簡稱"URI")是互聯網的一個協議要素,可以通過它來定位任何遠程或本地的可用資源(這些資源通常包括HTML文檔、圖像、視頻片段、程序等)。
QStoredDrag::QStoredDrag ( const char * mimeType, QWidget * dragSource = 0, const char * name = 0 )
設定要解碼的mimeType,它可以解QDragObject之類的封包
bool QDropEvent::provides ( const char * mimeType ) const [virtual]
判斷是否有支援mimeType這一類的QDragObject
這一個例子中,在dropsite.h中,有宣告一個signals function,
但是,沒有實作這一個function,
只有在main.cpp中,透過
QObject::connect( d, SIGNAL(message(const QString&)),format, SLOT(setText(const QString&)) );
實作這一個function,
我的感覺就變成,其實,message這一個function就是setText的別名啦~當執行message,就會執行setText這一個function
=======================================================
其實在良葛格學習筆記中,dragdrop有一個例子非常的清楚,只是沒有說明如何自定dragobject。
主要會用到的function有:
mousePressEvent
dragEnterEvent
dropEvent
dragLeaveEvent
2008年10月17日 星期五
實體層概觀
實體層被分成兩個附屬層(sublayer):
實體層收斂程序(Physical Layer Convergence Procedure,簡稱PLCP)附屬層
實際配媒介(Physical Medium Dependent,簡稱PMD)附屬層。
PLCP的功能在於結合來自MAC的訊框與空中所傳輸的無線電波。PLCP同時會為訊框加上自己的標頭。
每一種變調方式採用的同步訊號均不相同,因此PLCP會為準備傳送的所有訊框加上自己的標頭。
接著由PMD負責將PLCP所傳的每一個位元,利用天線傳送至空中。實體層還包含了頻道淨空(clear channel assessment,簡稱CCA)功能,用來指示MAC是否偵測到了訊號。
無線鏈路
無線頻譜可以被劃分為許多頻段,每一個頻段針對特定的使用目的。每個頻段定義了特定應用可以使用的頻率。其中,防護頻段(guard band)用來防止傳送訊號的溢散影響到其它頻段。
展頻
展頻的運作原理,是利用數學函數將訊號分散至較大的頻率範圍。祇要在接收端進行反向作業,就可以將這一些訊號重組為窄頻訊號。更重要的是,所有窄頻雜訊都會被濾掉,因此訊號可以清楚重現。
對傳統的窄頻接收器而言,傳輸訊號展開至較寬頻段之後,就和雜訊沒有兩樣。
展頻的類型
跳頻(Frequency hopping,簡稱FH或FHSS)
跳頻系統是以某種隨機樣式在頻率間不斷跳換,每一個頻道只作瞬間的傳輸。
直接序列(Direct sequence,簡稱DS或DSSS)
直接序列系統利用數學編碼函數將功率分散於較寬的頻段。
正交分頻多工(Orthogonal Frequency Division Multiplexing,簡稱OFDM)
OFDM將可用頻道劃分為一些子頻道,然後對每一個子頻道所要傳送的部分訊號進行平行編碼。
訊號接收與效能
空氣中到處都是隨機的電磁波,無線電通訊必須從背景的雜訊中分辦出訊號。一旦接收條件變差,訊號就越容易被雜訊淹沒。效能絕大部分取決於訊噪比(signal-to-noise ratio,簡稱SNR)這個決定性因素。圖10-2以訊號峰值(the peak of the signal)與雜訊基準(noise floor)之間的差異值來表示訊噪比。
路徑損耗、傳輸距離與傳輸量
在802.11中,網路的速度受到距離遠近的影響。不同的802.11定義出不同的變調標準,速度範圍由1Mbps到54Mbps。接收器必需能分辦出不同的狀態,方能將位元資料由電波訊號中取出。較高速的變調方式在特定的時間內可以封裝更多的位元,因此需要比較乾淨的訊號(以及更高的訊噪比)方能成功解碼。
電波訊號行經空間時更會衰減。在802.11的有限範圍內,雜訊基準還不至於有太大的變動。不過距離一長,訊號的衰減會影響接收端的訊噪比。當工作逐漸遠離基地台,訊號準位就會不斷的下滑;因此,訊噪比就會下滑。
以網路工程而言,當訊噪比較低以至於無法使用較高的速率,工作站就會降速,以便使用訊噪比要求較低的資料率。
路徑耗損受到距離與電波頻率的影響。距離越遠或頻率越高,則路徑損耗越大。802.11a所使用5GHz。開收式空間的路徑損耗可以表示成如下等式:
路徑損耗(dB) = 32.5 + 20 log F + log d
其中頻率 F 以GHz表示,距離d以公尺為單位。不過,路徑損耗不祇受距離的影響,牆面或窗戶等障礙物也會影響訊號,至於天線或放大器則可用來加強訊號,補償傳輸時的損耗。計算距離時通常會加計一種稱為鏈路邊際(link margin)的虛構因素,代表無法預料的損耗。
總損耗 = 傳輸功率 + 傳輸天線增益 - 路徑損耗 - 鏈路邊際 + 接收天線增益
多重路徑干擾
波與波之間具有疊加性(superposition)。當多個波集於某一點時,所產生的波即是所有波的加總。
圖 10-5(c)所顯示的兩個波幾乎完全相反,加總之後,相當於什麼也沒有。
多重路徑衰弱屬於訊符間干擾(Inter-symbol interference,簡稱ISI)的特例。
再次強調,波與波之間具有疊加性,因此造成速個波形的混淆扭曲。在實際的情況下,來自不同路徑的波前(warefront)會彼此疊加。最先到達的波前與最後到達的多重路徑回音,兩者之間時間差稱為延遲範圍(delay spread)。延遲範圍越長,就必需採用比較穩當的編碼機制。如果延遲範圍較短,效能會更好。
如果有一些延遲範圍太長,有一些網路就會降低傳輸速率以為因應。
天線
天線(antenna)是RF(Radio Frequency)系統中最關鍵的零件,因為由它們負責將線路中的訊號轉換為電波,以及將電波反轉為電路訊號。在方塊圖中,天線通常以倒三角形來表示
天線必需以導電材質方能運作。無線電波遇到天線時,電子就會流入導體而產生電流。同樣地,在天線施加電流就會在天線週圍產生電場。施加在天線上的電流不同,電場也隨之改變。變動的電場會產生磁場,因此形成電波。
天線的長短取決於頻率:頻率愈高,天線愈短。每種頻率可以使用的簡易型最短天線長度為波長的一半。
全向型(omnidirectional)天線,亦即可以收發所有方向的訊號。
指向型(directional)天線,這種類型的天線可以針對某個較窄的範圍進行收發。
給予等量的輸入功率,指向型天線可以傳得較遠,訊號也比較清楚。對於所指的方向,具備較高的無線訊號敏感度。
放大器
放大器可以增強訊號。訊號的放大或增益程度係以分貝(decibels,簡稱dB)做為量測單位。
低雜訊放大器(Low-noise amplifier,簡稱LNA)通常與天線連接,用來將所收到的訊號放大到與RF系統連結的電子零件可辦識的程度。LNA同時也可以就雜訊係數(noise factor)區分等級,雜訊係數可用來評量放大器本身所帶來的不相干資訊。雜訊係數越小,接收器就可以辦識愈細微的訊號,因此可以涵蓋較長的距離。
高功率放大器(High-power amplifier,簡稱HPA):則是用來將訊號提升至最大功率而後傳送。
更新電腦時間
那麼網路校時使用哪一個 port 呢?就是 123 這個 port ,而使用的軟體就是 ntpdate 這一支程式!
基本上,網路校時需要兩個步驟:
1. 由 time.stdtime.gov.tw 取得最新的時間,並即時更新 Linux 系統時間;
2. 更改 BIOS 的時間。
所以整個方法只要執行兩行即可搞定:
[root@host ]# ntpdate time.stdtime.gov.tw
[root@host ]# clock –w // 在redhat下
[root@host ]# hwclock -w // 在ubuntu下
如果還想要讓系統自動去更新時間的話,哈哈!對啦!那個 /etc/crontab 不要忘記了!將底下這一行寫入 /etc/crontab 當中:
10 5 * * 0,3 root /usr/sbin/ntpdate time.stdtime.gov.tw; clock -w
這樣一來,每星期三、日的五點,系統就會自動的去更新您 Linux 的時間囉!
參考資料:
鳥哥的 Linux 與 ADSL 私房菜
由文字模式自動登入,並執行指令
目的:學弟在嵌入式版子上,希望一開機可以不需要登入的動作,可以馬上執行某一個程式
目前有兩個方法
1. 設定自動由一個帳號登入,再由這一個帳號自動執行程式
2. 把要執行的程式設定成服務
目標,想要一開機執行ifconfig這一個程式
那先來試第一個方法吧~先設定成一個終端機為自動登入
[root@host ~]# vi /etc/inittab
隨便找哪個console下手都可以,在這裡以第3個虛擬控制台為例
把下面這一行
3:2345:respawn:/sbin/getty 38400 tty3
改成下面這樣
3:2345:respawn:/sbin/mingetty --autologin myname tty3
其中的「myname」是指你要自動登入的帳號,請依自己的情形輸入
接下來請到以myname的身份,到這個帳號的家目錄下
找一個叫作.bash_profile的檔案(如果沒有,請自行建立)
在.bash_profile這個檔案裡最下面加你想要輸入的指令ifconfig~
這裡另外提醒一下:
(1) .bashrc
系統啟動後就會自動執行。
(2) .profile
用戶登入後才會執行。
可以參考:shell設定
第二個方法:
把要執行的指令設定成服務~
以redhat為例:
在/etc下分別有rc1.d/;rc2.d/;rc3.d/;rc4.d/;rc5.d/;rc6.d/
分別放置登入level所要執行的服務的script,文字登入就是level 3、而視窗登入就是level 5
在/etc/rc.local檔案中(這一個script是所有服務中最後一個被執行的script,預設值是空的)
加入要執行的指令~
當登入時,就會去執行這一個指令啦~
要注意的事,此時還沒有shell,所以,沒有辦法中止正在執行的程式喔~
基本上在rc(i).d中的script有的檔名是有義意的~
S表示start、K表示kill
然後是由數字小執行到數字大的script
或是可以寫一個script然後,例如/etc/init.d/bbsd
[root@host ~]# update-rc.d bbsd defaults 90
90為開機時的執行順序,端看您如何設定.
update-rc.d會自動幫各個rcX.d目錄下建立一link至/etc/init.d/執行檔
或者是
[root@host ~]# update-rc.d iptables start 20 2 3 4 5 . stop 0 1 6 .
它會去找/etc/init.d/iptables這一個檔案,
2.3.4.5是指把該執行檔複製到/etc/rcX.d 複製到底下,當開機run level 2.3.4.5才會執行該執行檔
0.1.6是把該執行檔複製到/etc/rcX.d下,當關機時,會執行讓執行檔
在ubuntu中,rcX.d是放在/etc/event下
參考資料:
Linux自動登入技法
如何使程序開機自動運行?
linux開機啟動腳本的順序
開機自動執行script
錯誤記錄
1. slots必需宣告為public slots
error: expected primary-expression before 'void'
error: ISO C++ forbids declaration of 'type name' with no type
error: expected ';' before 'void'
2. signals必需宣告為signals就好,不需要宣告為public signals
error: expected `:' before 'protected'
3. 當header檔中,加入Q_OBJECT之後,必須重新qmake -project;qmake
它必需重新建立pro檔與Makefile
4. 在connect中,若要使用到本類別新建的function,必須要用到this指標
error: no match for call to 類別
2008年10月14日 星期二
管理作業
802.11管理架構由三個元件組成:MAC層管理單元(MAC layer management entity,簡稱MLME)、實體層管理單元(physical-layer management entity,簡稱PLME)以及系統管理單元(system management entity,簡稱SME)
掃描
在無線網路中,工作站加入任何相容網路之前,必需經過辨識的工作。於所在區域辨識現在網路的程序稱為掃描(scanning)
BSSType (independent、infrastructure 或both)
掃描時可以指定所要搜尋的網路屬於independent ad hoc、infrastructure或同時搜尋兩者。
BSSID (individual或broadcast)
工作站可以針對要加入特定的網路(individual)進行掃描或掃描允許該工作站加入所有的網路(broadcast)
SSID ("network name")
SSID係用來指定某個延伸服務組合(extended service set)的位元串。
ScanType (active或passive)
主動(active)掃描會主動傳送Probe Request訊框,以辨識該區有哪一些網路存在。被動(passive)掃描則是被動聆聽Beacon訊框,以節省電力。
ChannelList
802.11允許工作站指定所要嘗試的頻道表。
ProbeDelay
主動掃描探測某個頻道期間,為了避免工作站一直等不到Probe Response訊框,所設定的逾時計時器,用來防止某個閒置的頻道讓整個程序停擺。
MinChannelTime與MaxChannelTime
以TU(時間單位)來指定這兩個值,意指掃描每個特定的頻道,所使用的最小與最大的時間量。
被動掃描
被動掃描(passive scanning)可以節省電力,因為不需要傳送任何訊號。在被動掃描過程中,工作站會在頻道之間不斷切換,並且記錄來自所收到之Beacon訊息的資訊。Beacon在設計上是為了讓工作站得知,加入某個基本服務組合(basic service set,簡稱BSS)所需要的參數,以便進行通訊。
主動掃描
在主動掃描(active scanning)中,在每一個頻道上,工作站都會發出Probe Request訊框,請求某個特定網路予以回應。
1. 跳到某個頻道,然後等候來訊顯示(indication of an incoming frame),或者等到ProbeDelay計時器逾時。如果頻道收到訊框,就証明該頻道有人使用,因此可以加以探測。
2. 利用基本的DCF存取程序取得媒介使用權,然後送出一個Probe Request訊框
3. 至少等候一段最短的頻道時間(即MinChannelTime)
a. 如果媒介並不忙碌,表示沒有網路存在。因此,可以跳到下一個頻道。
b. 如果在MinChannelTime這段時間媒介非常忙碌,就繼續等候一段時間,直到最長的頻道時間(即MaxChannelTime),然後處理任何的Probe Response訊框
在Infrastructure網路中,是由基地台負責傳送Beacon訊框,因此它必需負責回應以Probe Request在該區搜尋網路的工作站。在IBSS中,工作站彼此輪流負責傳送Beacon訊框,因此負責傳送Probe Response的工作站會經常改變。
Probe Response屬於unicast管理訊框,因此必須符合MAC的正面回應(positive acknowldegement)規範。
在網路林立的區域,或許必須調整每個頻道的最長等候時間(maximum channel time),才有辦法處理區域內每個基地台所發出的答覆訊息。
掃描結果
掃描結束後會產生一份掃描報告。這份報告列出該次掃描所發現的BSS及其相關參數。進行掃描的工作可以利用此報告加入其所發現的任何網路。
Beacon interval (訊號間隔;整數值)
每個BSS所傳遞的訊框,均可指定自己的間隔,以TU為單位。
DTIM (DTIM期間;整數值)
DTIM訊框屬於省電(power-saving)機制的一部分
Timing parameter (計時參數)
有兩個欄位可以讓工作站的計時器與BSS所使用的計時器同步
PHY參數、CF參數以及IBSS參數
頻道資訊(channel information)包含實體層參數(physical-layer parameters)中
BSSBasicRateSet
基本速率組合(basic rate set)是打算加入某個網路時,工作站必需支援的資料傳輸速率
加入網路
加入網路(joining)是建立連線的前置作業,不過此時還不能存取網路。存取網路之前,必須經過身份認証以及形成連線。
通常用來決定加入哪一個網路的判斷標準是功率準位(power level)與訊號強度(signal strength)
使用BSSID可以確保目前是與正確的工作站進行傳輸,同時忽略其它BSS的工作站。
身份認証
目前802.11身份認証有一點像單行道。打算加入某個網路的工作站必須通過身份認証,然而網路方面並無義務對工作站証明自己的身份。
事先身份認証
事先身份認証(preauthentication)係用來加速連線關係的轉移。
在掃描階段,工作站可以跟幾部基地台進行802.11身份認証,如此一來,當有需要時,就可以立即進行連線作業,其好處是一旦進入基地台的涵蓋範圍,工作站就可以立即與基地台重新連線,而不必等候認証交換程序。
當行動式工作站移動到右邊,來至AP1的訊號會逐漸減弱。工作站會持續監測來至ESS的Beacon訊框,最後終於注意到AP2的存在。至此,工作站或許會選擇與AP1解除連線,然後與AP2進行身份認証與重新連線。
工作站送出一個EAPOL-Start訊息給新的基地台,揭開事先身份認証的序幕。
工作站每次祇能與一部基地台連線,因此事先身份認証必須透過舊過舊基地台轉達。
AP1收到以後,就會透過傳輸系統(distribution system)將訊框傳給AP2
6. 當工作站扣下扳機(pull the trigger),連線關係就會轉移到AP2。做為初始連線程序的一部分,工作站會提供金鑰快取的副本,告訴AP2它已經通過身份認証。
7. AP2收到身份認証要求,開始搜尋本身的金鑰快取。找出可用金鑰後,便立刻啟動成對金鑰的四道磋商程序。在衍生金鑰的過程中,短時間內工作站將無法正常收送封包。
連線作業
連線(association)屬於一種記錄(recordkeeping)程序,它讓傳輸系統(distribution system)得以記錄每一部行動工作站的位置,以便將傳送給行動工作站的訊框,轉送給正確的基地台。形成連線之後,基地台必須為該行動式工作站在網路上註冊,如此一來,發送給讓行動式工作站的訊框,才會轉送至其所屬基地台。其中一種註冊方式係送出一個ARP訊號,讓該工作站的MAC位址得以跟與基地台連接的交換埠形成連線。
連線程序
一旦連線要求獲准,基地台就會以代表成功的代碼0及連線識別碼(Association ID,簡稱AID)來回應。AID本身是數值形式的識別碼,在邏輯上則是用來辦識暫存訊框所要傳遞的行動式工作站。
重新連線程序
重新連線(reassociation)是指將連線關係自舊基地台轉移至新基地台的程序。不過在骨幹網路方面,基地台之間會彼此溝通,以便移轉訊框。
Infrastructure的網路的電源管理
因為基地台知道所連線的每部工作站的電源管理狀態,因此只要讓工作站處於作用(active)狀態,基地台即可判定,應該將訊框傳送至無線網路,否則就得為之暫存訊框。
開啟接收器聆聽暫存狀態,遠比週期性地送出探查訊框,所秏費的電力要少的多。
暫存單點傳播訊框,以及使用TIM來傳遞
當有訊框被暫存(buffered)時,目的節點的連線識別碼(Association ID)可以在該訊框及其目的地之間提供邏輯鏈路(logical link)。邏輯上,每個AID可將「暫存訊框」連繫至該AID所指定的行動式工作站。群播與廣播訊框被暫存時,會被連繫到0的AID。
如果工作站一直未能提取為之暫存的訊框,根本毫無意義。為了通知工作站有訊框待傳,基地台會產生有資料待傳訊息(traffic indication map,簡稱TIM)
無線基地台必須甦醒過來,並進入作用模式,聆聽Beacon訊框,以便接收TIM。祇要檢視TIM,工作站即可判定基地台是否有幫自己暫存訊框。
PS-Poll訊框用以指示某部處於省電狀態的行動式工作站暫存切換為作用模式,並且準備接收被暫存的訊框。
傳遞群播與廣播訊框:資料待傳指示訊息
每一個BSS均有一個稱為DTIM Period的參數。TIM是以Beacon訊息來傳送的。每當經過幾個固定的Beacon interval (信息間隔),就會發送一個特殊的TIM,稱為資料待傳指示訊息(Delivery Traffic Indication Map, DTIM)
IBSS的電源管理
independent網路中的工作站使用ATIM (announcement traffic indication messages;資料待傳指示通知訊息),強迫其它工作站保持清醒。在同一個IBSS當中,所有工作站必須在Beacon傳送後的特定時間聆聽ATIM訊框。
如果有部工作站為另一部工作站暫存訊框,它可以送出ATIM來通知對方。實際上,ATIM訊框是讓收發器保持開啟的訊息。
在ATIM期間,祇能傳送特定的控制與管理訊框。除了Beacon、RTS、CTS和ACK,當然包括ATIM訊框,傳送時必須依循DCF規則。ATIM訊框之所以只能在ATIM期間傳送是因為若IBSS中其它工作站皆處在休眠狀態,此時送出ATIM訊框便毫無意義。
對任何暫存管理功能而言,唯一的要求是暫存訊框至少得保存一個信標週期。
計時器的同步
除了工作站內部的計時,基本服務區域中每一部工作站都必須保存一份計時同步功能(timing synchronization function;簡稱TSF);該副本是與其本服務區域中所有其它工作站之TSF同步過的內部計時器。
Beacon訊框的另一個作用,就是定期對網路上的工作站發布TSF值。
Infrastructure的計時同步
在Infrastructure網路中,計時功能也採取類似的做法。由基地台負責維護TSF時間,任何與之連線的工作站都必須將基地台的TSF視為有效,而加以接受。
無線媒介充滿雜訊是可以預期的,經常會漏失Beacon訊框早在預料當中,工作內部的TSF計時器可以減緩偶爾漏失Beacon訊框所造成的影響。
IBSS的計時同步
IBSS中所有的工作站會準備在預定時間(target time)傳送Beacon訊框。當預定時間接近時,所有其它傳輸都會暫停。Beacon或ATM除外,所有訊框傳輸暫存器均會中止,等候媒介淨空,以便傳送更重要的管理訊框。
IBSS中所有的工作站都會為Beacon傳輸產生一個backoff(延後)計時器。TBTT結束後,所有工作站即從Beacon backoff 計時器的值倒數至0。
如果工作站在傳送時間之前就收到Beacon訊框,該預定要進行的Beacon傳輸就會被取消。
當Station的計時器逾時,即會傳送一個Beacon
這一個規則能夠確保至少有一部工作站處於清醒狀態,以便回覆正在進行掃描,準備加入網路的新工作站。
祇有當所收到的timestamp晚於內部計時器才會以timestamp更新內部計時器。
動態選頻(DFS)
當工作首度連線到網路,Association Request訊框包含一個Supported Channel資訊元素,其中列出工作站支援的頻道。
頻道禁聲
檢測無線電波頻道是在禁聲期(quiet period)或禁聲期間(quiet interval)進行。禁聲期間是指BSS所有工作站暫時停止傳輸的時間,有助於測量是否存在雷達系統的潛在干擾。
在中控型網路裡,頻道禁聲排程完全由基地台控制。基地台可以完全決定禁聲期長短,或甚至完全停用。
獨立型網路是在網路成立時選擇禁聲期的排程。輪到新工作站負責發送Beacon與Probe Response訊框也無法改變禁聲其參數,祇能延用之前的參數。
雷達掃描
獨立型網路並沒有基地台內建的功能,而是透過DFS owner來協調各個工作站進行頻率選擇服務。
網路中會有一部工作站被指定為DFS owner,負責蒐集量測報告以及監控頻道中是否有出現雷達訊號。
DFS owner負責決定使用哪一個新頻道,並且送出頻道切換宣告訊框。
萬一DFS owner離開網路,所有工作站會進入DFS owner遴選模式(recovery mode)。在這個模式當中,可以有好幾部工作站同時擔任DFS owner,並排程產生標準所要求的頻道切換宣告訊框。
第一部傳送頻道切換訊框的工作站才會成為DFS owner,其它工作站則會放棄這一個角色。