發表文章

(C++) 別再用dynamic array與pointer了! 趕快學STL的vector與iterator!

圖片
(一) 廢話 別再用array與pointer?那我不是在自打上一篇的嘴巴嗎? 其實並不衝突。因為在C之下,pointer還是非常重要的,本篇所著重的是C++。 不知道大家在學C++時,老師或書中有沒有教或學到STL(Standard Template Library)呢? STL是C++下非常非常好用的函式庫,他提供了非常多Template形式的"容器",讓開發上省去不少麻煩,且使得C++與C之間相去越遠,兩者已經儼然是不同的語言了!(Jserv 大師也曾說過 - 自 1999 年制訂的 C99 規格開始,C 語言和 C++ 程式語言就分道揚鑣,換言之「C++ 是 C 語言的超集 (super-set)」不再成立。) (二)前言 C++之父-Bjarne Stroustrup曾說過, "you should use vector over Array unless you have a really good reason to use an array"。因為記憶體的管理永遠是開發者的痛,在現今的程式開發中最好能避免使用new,因為這會使我們必須持續的追蹤其大小且須手動刪除釋放。尤其是在re-size array時,vector會更加好用。 當然不諱言的是,dynamic array的速度還是優於vector的,只是那是只在極端講求速度的class 的內部實作中才使用。 (三) Vector與Iterator是何物? Vector 是 C++中STL容器(container)中其中一個 template class,他在宣告後就可以使用。只需要一直進行新增資料,而不用在乎其大小,亦可視為會 自動擴展容量(capacity) 的陣列,所以只要一直塞一直塞一直塞就可以了XD。是C++標準程式庫中的眾多容器(container)之一。 Iterator有時又稱cursor,是一種在很多程式語言中都有的interface,主要功能就是讓工程師可以無需關心memory分配而在各種container中進行尋訪。C++雖然本身不具此功能,但在STL中對於此進行了實作。會 綁定所指向的容器 。因此Iterator可以 視為容器(在這就是用於vector)的指標的概念,因此亦可以直接做

(C) 簡單搞懂指標(pointer)、指標陣列(pointers of array, int *foo[]) 與指向陣列的指標 (pointer to array, int (*bar)[])

圖片
(一) 廢話 指標一直以來都是初學者的一個夢魘,有時後就算是老手也不一定會搞清楚,而且不常用的話也容易忘記,但指標在C理面是一個非常重要的核心技術,在很多公司的面試題都是必出的主題,因此能搞清楚指標對一個工程師而言是百利無一害的。 (二) 前言 在開始之前,我必須先強調以下看似廢話但其實是很重要的觀念,之後會提到他們是多麼重要,反正就先記起來吧,就算知道了也還是多想他一下。 什麼"資料型態(data type)"就存什麼樣的"型態資料"。因此指標變數就是存記憶體位址 真的很廢話,但在指標裡面會是很重要的觀念。 (三) 什麼是指標 指標(pointer)就是一個變數的 記憶體的地址,在宣告的時候使用" * "放在變數型態之後。他可以被視為一種資料型別的修飾,因此若宣告了一個指標變數時,就代表 其資料型態是指標類型,因此這個變數存的內容就是記憶體 ,不管他本身原本是什麼型態,只要在程式理面使用該變數(不額外加符號),就是使用他的記憶體。就是上面強調的「 什麼型態存什麼資料 」。 (四) 基本符號 在指標裡,「 * 」是一個非常重要的符號,他同時可以是兩種意思,分別是: 1. 指標(pointer) - 這個符號 只有在宣告的時候 才會出現,表示該變數是 指標型態 ,其存的內容就是記憶體位址;可以想像成是一個「 鎖 」。 2. 取 值 運算子(Dereference operator) - 在 宣告以外時所有 出現在變數前的都是這種(當然不包含乘法),表示依照這個變數所存的地址,去取得該記憶體位址理面存的值;可以想像成是把該變數的鎖打開的「 鑰匙 」。 另外還有一個符號: 「 & 」 : 取 址 運算子(Address-of operator) - 取得某一變數本身存放的記憶體位址。 (五) 宣告與使用 在使用指標之前,如果沒有進行記憶體配置的話,原則上初始值為NULL,要讓程式能動態配置一個記憶體,就必須使用 malloc 。 在Linux man pages中,malloc 的原型為以下所示:     void *malloc(size_t size ); 傳入參數僅有一個,就是要配置的記憶體大小(單位為Bytes

(c/c++) Function Pointer函式指標兩三事 (Function Pointer 的 typedef 與 Array of Function Pointer)

圖片
 Function Pointer 定義: Function Pointer (中文直譯「函式指標」),即為 儲存某一個函式起始memory address的 變數 ,此變數可以提供我們在之後進行呼叫。 乍聽之下,function pointer就只是多一個別名再呼叫,似乎沒什麼實質的用處,但其實我們可以藉由function pointer省去繁複的 if/switch,後面會一一介紹。 使用方法:  現在假設我們有以下這個函式: int Square(int n) {     return n*n; } 然後宣告一個function pointer變數,以便於指向函式Square: int (*fptr)(int); fptr = Square; 這邊有幾個小細節必須注意: 1.最前面的int是變數data type(資料型態),和要指向的函式回傳值型態相同。第一個小括號代表指標變數名稱,第二個小括號代表傳入的parameter資料型態們,且理所當然的type必須與我們要指向的函式傳入值相同。 2. function pointer 的 pointer operator(*) 必須與變數名稱一起被小括號括起來 並接參數的小括號。若沒有這個小括號,會變成以下: int *fptr(int); 在意義上,表示fptr為一個"函式"而不是變數,回傳的資料型態為 int* ,會有3種情況;     a. 回傳一個pointer of int(整數指標變數的指標) -> int *a; return a;     b. 回傳一個address of int(整數一般變數的位址) -> int a; return &a;     c. 回傳一個int array(整數型態的陣列) -> int a[100]; return a; 延伸: 在知道function pointer的妙用前,還必須介紹以下兩種功能: 1.typedef typedef是c/c++中的關鍵字,其允許programmer為data type(資料型態)創造一個全新的名字。同時也可以為函式創造一個別名,其好處在於若要把function當做一參數傳入另外一fumcti

基礎 Linux(UNIX-Like) 指令(Command line)整理介紹

圖片
什麼是Command line? 就是常常我們看電影中,駭客對著一個沒有圖且畫面全黑的電腦打著滿滿文字,看起來很帥的那個。   (翻攝於youtube) 阿不對放錯圖了XD,應該是這張才對   (電影 ALGORITHM: The Hacker Movie中照片) 那個輸入的視窗,在 windows 中稱為 命令提示字元(cmd) ;在 Linux 中則稱為 終端機(terminal) 。至於輸入的那些指令則稱為 command line (cl)。 這些指令其實是呼叫一些現成寫好的程式,因此若能善用這些指令,有時候可以省去很多不必要的碼農時間。 這邊提供了一些基本但重要且常用的Linux指令(windows的與linux大不相同),介紹其常用的功能,若想知道該指令更多細節與參數,可以善用man 或者 --help指令進行查詢,例如: $ man cat $ cat --help 就能得到更多的細節拉~ 在開始介紹指令以前,先講解一下指令的 參數(option) 。 一般而言參數可以分為 長參數(long option) 與 短參數(short option) 。 長參數:在使用時常用' -- '作為參數開始,並且是一串具有意義的單字,較具有可讀性,缺點則是過長。例如--help --all或者--recursive。 短參數:在使用時都用' - '作為參數開始,接著使用一個英文字母來表示,通常是某個單字的其中一個字母。例如-a -l或者-r之類的。 另外 短參數可以合併在一起使用 ,例如: $ ls -la 和 $ ls -l -a 就是一樣的東西。更加詳細的原理可以參考getopt_long()。 以下開始介紹各個常用指令,有黃底的代表筆者認為非常重要一定要熟悉的指令。 cat (con cat enate) 🐱 <用處> 印出檔案內容或將多個 檔案合併 。 <語法> cat [OPTION]... [FILE]... <說明> 此語法多用於將文字檔案內容印在terminal上。實際上該指令是將檔案內容連結(複製)至另一端,在沒有指定目標的情況下,會將檔案連結至standard output,即印在terminal上。

在linux下用C實作netstat (Implement netstat)

圖片
在Linux 下, netstat 指令常被用來查詢網路各種資訊,像是 在TCP、UDP、IP  ethernet 和 socket 中的各種資訊。 至於 netstat 則是去/proc中抓取各個所需要的資料。  /proc是系統模擬出來、假的(虛擬)檔案系統(pseudo-filesystem),它是外界讀取核心資訊的對外窗口 。 說是假的檔案系統是因為/proc中每個檔案在當user-process讀取/proc下的檔案時,才會即時(real-time)產生檔案中的「內容」。   以下 是Linux Programmer's Manual 中對於proc的描述 : The proc filesystem is a pseudo-filesystem which provides an interface to kernel data structures. from man proc 在/proc 這個目錄下,可以分為兩種類型的檔案:一種是只有數字編號的目錄,其代表每個執行中的Process 的ID (i.e. pid); 另一種非數字編號的則是與系統資訊相關的檔案。 在這個實作中我們需要使用到的是 /proc/net,該目錄下儲存著各種網路層的資訊。其中的/tpc與/udp分別儲存著tpc socket table與udp socket。 當我們對其中一個(udp) 貓一下( cat 指令)後,會出現如下的表格: 在這些欄位中,我們所需要的分別是 local_address 、 rem_address 與 inode 。 其中inode在這裡所代表 的意義很重要, 因為 使用該 addr :port的process 會 link到該inode 。講到這邊 大概就 已經講完所有原理了,最後只要找到 link到所有inode 的process就能完成了。 至於這個link要去哪裡找呢? 這就要 去 /proc 目錄下所有的數字目錄中的/ fd( f ile d escriptors)目錄 去慢慢找,即 /proc/[pid]/fd/ ,找到 所有symbolic link 到 inode 的 pid 。 例如我現找到一pid=878的process符合此條件(絕對剛好是87的),於是在/proc/878