|
剛剛休息了一個暑假。不要盲目羨慕我啊,只有短短一個星期。上研以來,還真的沒有什么假期可言,寒暑兩假一年加起來也就兩個多星期,相比同學悠哉的兩三個月來說真的是少啊。
眼看明年也快要畢業了,于是邀請父母還有淘氣的小侄來北京逛逛看看。父親的北京記憶還停留在80年代初,還話說他開著大卡車從除了天門前的其他街道呼嘯而過。北京已經變化得令他陌生。小侄則郁悶為什么去哪都要不停的倒車,嚷著再不做地鐵的他,做了一回公交后,再也沒有這種想法。
上星期還算天公作美,剛開始的幾天還算溫度適宜,領著逛了逛石景山游樂園,鳥巢,天文館,北京市海洋館,西單,前門,天安門。剩下幾天的高溫天氣,奈何我有興致,他們卻個個都不逛了。原因有二,一是money消耗了不少,父母也替我心疼錢了;二是高溫加交通不順,老的累了,小的也累了。情愿開著空調,家里看電視。
幾天下來,小侄竟然發出了這樣的感慨,北京沒有家好。父母也覺得沒有家好。在這個城市生活了兩年多的我,為什么沒有這種感覺呢。習慣了,習慣了擁堵,習慣了走路,習慣了忙碌,習慣了這個城市帶給我的感覺,也漸漸覺得自己融入了進來。畢竟這里會讓自己跑得更快些,跳得更高些,是這里的機遇與挑戰吸引了我,我想這也是吸引很多人的理由。要不,這么多人,擁擠在這個城市總該有個往前奔的理由。
還沒畢業,所以高得不能再高的房價還暫時對我帶不來什么沖擊,只是眼下的經濟形式,讓我面臨著就業壓力。父母的到來,讓我為自己找到了一個很好放松的理由。假期的結束,又讓自己回到了畢業的思考。
似乎這是一個熱門話題,身邊的同學、同事以及朋友都會問及此事。程序員是我的首選職業,因為我喜歡,喜歡那種挑戰和不斷學習的感覺,享受那種解決問題的快樂。我會選擇這個一直下去,有著成為小小專家的夢想。只是現在需要一個跳板,跳得更高,飛得更遠。
夢能飛得多遠,在于我能跑得多塊。假期給我帶來了一些疲憊,看看《蠟筆小新》,居然能緩解疲勞。其實小新有時比我小侄聽話好多。今天終于恢復了早起的習慣,工作也要認真起來。舊項目終于完結了,新項目又要開始了,項目總結也要趕著寫,學習進步也要加緊些。事情很多,都得一件一件來。在豆瓣網上看到的晨型人,5點多起來對于我來說真的太困難了,還是老時間起來吧,七點多,才能保證一天之精神飽滿。加油起來,堅持就會勝利。
今天在進行memcpy出現了一些問題。
原因是這樣的:
我定義了這樣一個接口,里面涉及memcpy操作。
舉個例子吧,如接口addItem,
void addItem(int iType, LPVOID *pItem);
里面有一個對象是TCHAR szStr[512];
我直接進行了這樣的拷貝,memcpy(szStr, pItem, sizeof(szStr));
今天就出問題了。提示某塊內存無法訪問。于是重新看這個問題。為什么會這么寫這樣的接口呢?
我原先寫的是 void addItem(int iType, TCHAR *pItem);
后來由于需求的變化,變成了LPVOID。改成這個以后,原先的字符串wcscpy就變成了memcpy。這個一直沒有引起警覺。其實這一步的改變,就應該對接口做相應的調整,接口應該變為
void addItem(int iType, LPVOID *pItem, DWORD cbItem);
增加一個參數來說明pItem的大小。然而這一步沒有做。
所以今天的教訓就是要注意修改接口的時候,注意相應的變化。
還有是字符串的操作問題,寬字符和ASCII字符串的操作要注意。
第一方法的時間復雜度為o(n),第二種的時間復雜度為o(m),m為1的個數。
后記:
最近一周多,一直在做這本書上的編程題。一天3道,自己先嘗試編寫,運行成功后再與書上的解答進行對比。稍有幾次略感比書上稍好些。但大多數情況還是效率差一些。想想原因,還是練得比較少。所以繼續努力。多多積累,養成良好的思維習慣。
去同學那玩,看到這么一本書《C++沉思錄》。這本書很早聽過,但是沒有讀過。于是捧起書讀了幾章,感覺很是不錯。其中第四章就是講“類設計者的核查表”。雖然用c++有幾年,但是有一些東西還是需要銘記于心的。
類設計者的核查表
一、
您的類需要一個構造函數么?
有些類太簡單,無需構造函數,但有些類太復雜,他們需要構造函數來隱藏它們的內部工作方式。
二、 您的數據成員是私有的么?
通常使用公有的數據成員不是什么好事,因為類設計者無法控制何時訪問這些成員。
三、 您的類需要一個無參的構造函數么?
如果一個類已經有了構造函數,想聲明該類的對象可以不必顯示地初始化它們,則必須顯示地寫一個無參的構造函數。
四、 是不是每一個構造函數初始化所有的數據成員?
構造函數的用途就是用一種明確定義的狀態來設置對象。對象的狀態由對象的數據成員進行反映。每個構造函數都要負責為所有的數據成員設置經過明確定義的值。
有時這種說法也未必總是正確的。有時,類會有一些數據成員,它們只在它們的對象存在了一定時間之后才有意義。提這個問題,只是激勵你進行思考。
五、 類需要構造函數么?
不是所有有構造函數的類都需要構造函數。如果深入考慮一個類要做些什么,那么該類是否需要析構函數的問題就十分明顯了。應該問一問該類是否分配了資源,而這些資源又不會有成員函數自動釋放,這就足夠了。特別是那些構造函數里包含了new表達式的類,通常要在析構函數中加上相應的delete表達式,所以需要一個虛析構函數。
六、
類需要一個虛析構函數么?
有些類需要虛析構函數只是為了聲明他們的析構函數是虛的。當然,決不會用做基類的類是不需要虛析構函數的:任何虛函數只在繼承的情況下才有用。
虛析構函數通常是空的。
七、 你的類需要復制構造函數么?
很多時候答案都是“不”,但是有時候答案是“是”。關鍵在于復制該類對象是否就相當于復制其數據成員和基類對象。如果并不相當,就需要復制構造函數。
如果你的類在構造函數內分配資源,則可能需要一個顯示的復制構造函數來管理資源。有析構函數的類通常是析構函數來釋放構造函數分配的資源,這通常說明需要一個復制構造函數。(空的虛析構函數除外)
如果不想用戶能夠復制該類的對象,就聲明復制構造函數為私有的。如果其他的成員不會使用這些成員函數,聲明就足夠了,沒有必要定義它們。
八、 你的類需要一個賦值操作么?
如果需要復制構造函數,同理多半也會需要一個賦值操作。
九、 你的賦值操作符能正確地將對象賦給對象本身么?
賦值總是用新值取代目標對象的舊值。如果原對象和目標對象是同一個,而我們又奉行“先釋放舊值,再復制”的行事規程,那么就可能在還沒有實施復制之前就把原對象銷毀了。
十、 你的類需要定義關系操作符么?
如果你的類邏輯上支持相等操作,那么提供operate== 和operate!=可能會有好處。類似的,如果你的類的值有某種排序關系,那就可能會想提供余下的關系操作符。只要它們想創建你的類型的有序集合,你就必須提供關系操作符。
十一 刪除數組時你記住了用delete[]么?
這個形式的存在,是C++希望在保持與C的兼容性的同時關注效率。C++要求用戶告知要被刪除的是不是數組。如果是,該實現就可能會提供另一個地方來存儲長度,因為與數組所需的內存量相比,這個常數的開銷會小很多。
十二 記得在復制構造函數和賦值操作符的參數類型中加上了const么?
復制構造函數應該是像X::X(const X&)這樣,畢竟復制對象不會改變原對象。實際上,由于綁定一個非const引用到一個臨時對象是非法的,使用X::X(X&)作為復制構造函數不會允許復制任何特殊表達式的結果。同樣道理適用于賦值。
十三 如果函數有引用參數,它們應該是const引用么?
只有當函數想改變參數時,它才應該有不用const聲明的引用參數。
今天抱著書在做這么一道題:
整數/字符串轉換
編寫兩個轉換例程。第一個例程將一個字符串轉換成帶符號的整數。您可以假定這個字符串只包含數字和符號字符('-'),是一個格式正確的整數,而且這個數字在int類型的范圍之內。第二個例程將Int類型中存儲的有符號整數轉換回字符串。
其中碰到了int與char的轉換問題。這個還真的把我難住了。我先用最笨的方法switch進行了轉換。你也知道這肯定不是最優的方法。直接轉換,值也肯定不對。
后來發現竟然是這么使用的,趕快記錄下來。
1、int 轉換成char
例如:
int n = 1;
char ch = char(n + '0');
不過需要注意,此處的n只能是0-9之間的字符
2、char轉換成Int
char ch = '9';
int n = int(ch) - int('0');
此處ch也是‘0’至‘9’的數字字符
多多學習,抓住機遇。
快捷方式的讀取和創建
SHGetShortcutTarget
功能:
獲取快捷方式的目標路徑
原型:
BOOL SHGetShortcutTarget(
LPTSTR szShortcut,
LPTSTR szTarget,
int cbMax
);
參數:
szShortcut :包含快捷方式名字的字符串
szTarget :包含快捷方式目標路徑的字符串, 字符串的大小至少是cbMax。
cbMax :將被拷貝到緩存szTarget的最大字符串
返回值:
成功返回TRUE,否則返回FALSE。
示例代碼:
TCHAR StartMenuFilePath[MAX_PATH];
::SHGetSpecialFolderPath(NULL, StartMenuFilePath, CSIDL_PROGRAMS, FALSE);
TCHAR szShortPath[MAX_PATH];
wsprintf(szShortPath, _T("%s\\%s"), StartMenuFilePath, _T("搜索.lnk"));
TCHAR szFilePath[MAX_PATH];
:SHGetShortcutTarget(szShortPath, szFilePath, sizeof(szFilePath));
執行完畢后,
szFilePath 的值為shfind.exe
SHCreateShortcut
功能:
創建快捷方式。
原型:
DWORD WINAPI SHCreateShortcut(
LPTSTR szShortcut,
LPTSTR szTarget
);
參數:
szShortcut :包含快捷方式名字和路徑的字符串。在路徑指定的位置創建快捷方式。
szTarget: 包含快捷方式目標路徑和參數的字符串。大小限定在256個字符以內。
返回值:
成功返回TRUE,否則返回FALSE。如果指定的快捷方式已經存在的話將返回FALSE。
示例代碼:
SHCreateShortcut(_T("\\搜索.lnk"), _T("shfind.exe"));
執行結果為在根目錄下創建了“搜索.lnk”這個快捷方式文件。
這里主要針對獲取快捷方式的內容進行幾點說明:
我們獲取快捷方式的時候,內容不一定只包含路徑,有可能存在一下的情況,如:
1、路徑后跟隨名稱
\Windows\“開始”菜單\程序\任務.lnk
2、縮寫名
poutlook.exe tasks
\Windows\“開始”菜單\程序\ActiveSync.lnk
:MSSYNCAPP
3、路徑后跟隨數字
\Windows\“開始”菜單\程序\游戲\icon.lnk
shellres.dll,-8229
考慮以上這幾種情況,我們在獲取快捷方式路徑時,需要對路徑做一些特殊處理。這里重點說一下第二種情況,這個縮寫代表什么意思?在網上搜索了一下,原來我們可以在[HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\]鍵值下找到名為:MSSYNCAPP的子鍵,鍵值為1的子鍵數值指明了名為:MSSYNCAPP的程序名稱。但我們從這里獲得的值,有時也不是路徑,還會再次出現上述三種情況。所以,如果我們想從快捷方式中獲取路徑的話,就需要留意一些了。
至于為什么會這樣,我還不是很明白。