1、i++跟++i
(1)單獨執行後,i的值都增加了1
(2)i++不可以做左值,++i可以
<1>左值:C/C++語言中可以放在賦值符號左邊的變量,即具有對應的可以由用戶訪問的存儲單元,並且能夠由用戶去改變其值的量。
<2>具體函數實現:
// 前綴形式:
int& int::operator++() //這裏返回的是一個引用形式,就是說函數返回值也可以作爲一個左值使用{//函數本身無參,意味着是在自身空間內增加1的
*this += 1; // 增加
return *this; // 取回值
}
//後綴形式:
const int int::operator++(int) //函數返回值是一個非左值型的,與前綴形式的差別所在。
{//函數帶參,說明有另外的空間開闢
int oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}
2、C++ 的一個常見面試題是讓你實現一個 String 類,限於時間,不可能要求具備 std::string 的功能,但至少要求能正確管理資源。
此題轉載至:http://coolshell.cn/articles/10478.html
首先選擇數據成員,最簡單的 String 只有一個 char* 成員變量。
好處是容易實現,壞處是某些操作的複雜度較高(例如 size() 會是線性時間)。
爲了面試時寫代碼不出錯,本文設計的 String 只有一個 char* data_成員。
而且規定 invariant 如下:一個 valid 的 string 對象的 data_ 保證不爲 NULL,data_ 以 '\0' 結尾,以方便配合 C 語言的 str*() 系列函數。
其次決定支持哪些操作,構造、析構、拷貝構造、賦值這幾樣是肯定要有的(以前合稱 big three,現在叫 copy control)。
如果鑽得深一點,C++11的移動構造和移動賦值也可以有。
爲了突出重點,本文就不考慮 operator[] 之類的重載了。
這樣代碼基本上就定型了:
- #include <utility>
- #include <string.h>
- class String
- {
- public:
- String()
- : data_(new char[1])
- {
- *data_ = '\0';
- }
- String(const char* str)
- : data_(new char[strlen(str) + 1])
- {
- strcpy(data_, str);
- }
- String(const String& rhs)
- : data_(new char[rhs.size() + 1])
- {
- strcpy(data_, rhs.c_str());
- }
- /* Delegate constructor in C++11
- String(const String& rhs)
- : String(rhs.data_)
- {
- }
- */
- ~String()
- {
- delete[] data_;
- }
- /* Traditional:
- String& operator=(const String& rhs)
- {
- String tmp(rhs);
- swap(tmp);
- return *this;
- }
- */
- String& operator=(String rhs) // yes, pass-by-value
- {
- swap(rhs);
- return *this;
- }
- // C++ 11
- String(String&& rhs)
- : data_(rhs.data_)
- {
- rhs.data_ = nullptr;
- }
- String& operator=(String&& rhs)
- {
- swap(rhs);
- return *this;
- }
- // Accessors
- size_t size() const
- {
- return strlen(data_);
- }
- const char* c_str() const
- {
- return data_;
- }
- void swap(String& rhs)
- {
- std::swap(data_, rhs.data_);
- }
- private:
- char* data_;
- };
注意代碼的幾個要點:
- 只在構造函數裏調用 new char[],只在析構函數裏調用 delete[]。
- 賦值操作符采用了《C++編程規範》推薦的現代寫法。
- 每個函數都只有一兩行代碼,沒有條件判斷。
- 析構函數不必檢查 data_ 是否爲 NULL。
- 構造函數
String(const char* str)
沒有檢查 str 的合法性,這是一個永無止境的爭論話題。這裏在初始化列表裏就用到了 str,因此在函數體內用 assert() 是無意義的。
這恐怕是最簡潔的 String 實現了。
練習1:增加 operator==、operator<、operator[] 等操作符重載。
練習2:實現一個帶 int size_; 成員的版本,以空間換時間。
練習3:受益於右值引用及移動語意,在 C++11 中對 String 實施直接插入排序的性能比C++98/03要高,試編程驗證之。(g++的標準庫也用到了此技術。)
3.描述在瀏覽器中敲入一個網址並按下回車後所發生的事情//比如 www.baidu.com
(1)DNS域名解析
首先要查找域名的IP地址,經過DNS查找後,將輸入網址域名轉換成IP地址。如果url裏不包含端口號,則會使用該協議的默認端口號。DNS域名解析的過程是這樣的:首先我們知道我們本地的機器上在配置網絡時都會填寫DNS,這樣本機就會把這個url發給這個配置的DNS服務器,如果能夠找到相應的url則返回其ip,否則該DNS將繼續將該解析請求發送給上級DNS,整個DNS可以看做是一個樹狀結構,該請求將一直髮送到根直到得到結果。
(2)在發送請求前,先要建立一個TCP連接(socket連接)。socket通過ip和端口建立的,現在有了目標ip和端口號。
(3)建立連接後發送請求。瀏覽器給web服務器發送一個HTTP請求。請求中也包含瀏覽器存儲的該域名的cookies。cookies是與跟蹤一個網站狀態相匹配的鍵值。cookies會存儲登錄用戶名,服務器分配的密碼和一些用戶設置等。Cookies會以文本文檔形式存儲在客戶機裏,每次請求時發送給服務器。
(3)服務的永久重定向響應
(4)瀏覽器跟蹤重定向地址
(5)服務器“處理”請求:應答 web服務器收到請求,進行處理。 從它的文檔空間中搜索子目錄index.html。如果找到該文件,Web服務器把該文件內容傳送給相應的Web瀏覽器;未找到,返回錯誤信息。爲了告知瀏覽器,Web服務器首先傳送一些HTTP頭信息,然後傳送具體內容(即HTTP體信息),HTTP頭信息和HTTP體信息之間用一個空行分開
(6)服務器發回一個HTML響應
(7)釋放 TCP 連接:若connection 模式爲close,則服務器主動關閉TCP 連接,客戶端被動關閉連接,釋放TCP 連接;若connection 模式爲keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求
(8)瀏覽器開始顯示HTML
(9)瀏覽器發送獲取嵌入在HTML中的對象
參考網址:http://www.mamicode.com/info-detail-1357508.html
4.strcpy和memcpy的區別 ()
strcpy和memcpy都是標準C庫函數,它們有下面的特點。
strcpy提供了字符串的複製。即strcpy只用於字符串複製,並且它不僅複製字符串內容之外,還會複製字符串的結束符。
已知strcpy函數的原型是:char* strcpy(char* dest, const char* src);
memcpy提供了一般內存的複製。即memcpy對於需要複製的內容沒有限制,因此用途更廣。
void *memcpy( void *dest, const void *src, size_t count );
char * strcpy(char * dest, const char * src) // 實現src到dest的複製
{
if ((src == NULL) || (dest == NULL)) //判斷參數src和dest的有效性
{
return NULL;
}
char *strdest = dest; //保存目標字符串的首地址
while ((*strDest++ = *strSrc++)!='\0'); //把src字符串的內容複製到dest下
return strdest;
}
void *memcpy(void *memTo, const void *memFrom, size_t size)
{
if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必須有效
return NULL;
char *tempFrom = (char *)memFrom; //保存memFrom首地址
char *tempTo = (char *)memTo; //保存memTo首地址
while((size-- )> 0) //循環size次,複製memFrom的值到memTo中
*tempTo++ = *tempFrom++ ;
return memTo;
}
strcpy和memcpy主要有以下3方面的區別。
1、複製的內容不同。strcpy只能複製字符串,而memcpy可以複製任意內容,例如字符數組、整型、結構體、類等。
2、複製的方法不同。strcpy不需要指定長度,它遇到被複制字符的串結束符"\0"才結束,所以容易溢出。memcpy則是根據其第3個參數決定複製的長度。
3、用途不同。通常在複製字符串時用strcpy,而需要複製其他類型數據時則一般用memcpy