發表文章

目前顯示的是 12月, 2012的文章

【轉載】Data structure的對齊(alignment)

來源 變數的宣告,會配置其所需的記憶體。每種變數所需的大小不一樣,比如說char是1 bytes,int 是4 bytes,double則是8 bytes。如果是這樣,那這些大小在記憶體中是如何擺放呢?是直覺的一個接一個放嗎?其實不然。這牽扯到performance / efficiency的問題! 在32 bits的架構上,一次的資料存取也就是32 bits (4 bytes)。而這4 bytes 不是隨便從哪個點抓都可以,而是以4 bytes為單位,不管需要的是其中那個byte,就抓那4個bytes。比如說,抓第0,4,8 ,12....等,而不會是從3,7,9開始抓4個bytes。 這代表什麼呢?這表示了對齊 (alignment)的重要,因為會影響到幾次才抓的完。如果要抓一個4 bytes 的int,而這個int是從6擺到10,那就表示要抓兩次,自然效能較差了。因此,在struct的宣告是存在對齊這件事的。見下例: #include <stdio.h> int main(int argc, char* argv[]) {         struct align_test         {                 char x; //1 byte                 int y;  //4 bytes                 short int z;  //2bytes         };   ...

【轉載】動態空間分配

來源 動態空間分配 所謂動態空間分配指的是,在執行期間由程式向作業系統或程式庫要求後才分配的空間,這塊記憶體區域稱為Heap(堆積)。C語言的動態空間分配主要透過malloc和free兩函數來處理。這兩個函數的宣告如下: void *malloc(size_t size); void free(void *ptr); 透過malloc()所分配出來的空間必須由使用者呼叫free()才能歸還給系統。初學者常犯的錯誤之一,就是忘了用free()歸還空間,這會造成程 式佔用太多記憶體,此現象稱為memory leakage。相反的,如果空間已用free()歸還了,卻還試著去使用那塊記憶體,則會發生Segmentation Fault (core dumped)的錯誤。 Linked Stack typedef struct items { int data; struct items *link; } ITEM; typedef struct stack { ITEM *top; } STACK; void initStack(STACK *s) { s->top = NULL; } void pushStack(STACK *s, int y) { ITEM *x; // x will point to the new ITEM x = (ITEM *) malloc(sizeof(ITEM)); // allocate memory for the new ITEM x->data = y; // store data x->link = s->top; // x->link points to where s->top points s->top = x; // stack's top points to x } int popStack(STACK *s) { ITEM * x = s->top; int d = x->data; s->top = s->top->link; free(x); return d; } int stackIsEmpty(ST...

【轉載】用於struct的運算符號

來源 在如下的結構定義裡,next前面的*不可省略,否則就遞迴定義了,Compiler將無法決定struct list的大小。 struct list { int data; struct list *next; // a pointer to struct list }; struct list listOne, listTwo, listThree; listOne.next = &listTwo; listTwo.next = &listThree; // 以下想要由listOne設定到listThree的data listOne.next.next.data = 0; // 這不合法, 因為.的左邊必須是struct,不可以是pointer (*(*listOne.next).next).data = 0; // 這樣寫才對     你會發現上面的例子中, 如果struct裡面有pointer to struct, 而我們想要用該pointer來存取結構成員時, 就必須很小心的用*和()來表達。由於結構成員包括指向結構的指標(define a pointer to struct in a struct), 是很常見的事情, 這樣的(*(*listOne.next).next).data語法既難寫又難懂, 因此C語言定義了->運算符號。此符號的左邊是一個pointer to struct, 右邊則是該pointer指到的結構成員。->為第一優先權左結合, 因此 (*(*listOne.next).next).data = 0; //這樣寫才對 listOne.next->next->data = 0; // 這樣寫更漂亮

【轉載】static修飾詞

(來源)http://www.csie.nctu.edu.tw/~skyang/static.zhtw.htm 在全域變數或函式的宣告之前加上 static,就讓它們不能跨 .cpp 檔使用,如下例中的 compare_grade( )它的目的僅在於提供給下面的 qsort( ) 使用,所以在它函式宣告之前加了 static,這麼一來它就只能在這個 .cpp 檔案中有效,在其他的 .cpp 檔案中就算以 extern 來援用它也不可以,另一方面,在其他的 .cpp 檔案中就算有同名的 compare_grade( ) 函式也沒關係。 #include <math.h> #include <stdlib.h> #include "GradeList.h" static int compare_grade(const void *ptr1, const void *ptr2) { float f1 = *((float *)ptr1); // 把 ptr 轉型成 (float *)再取值 float f2 = *((float *)ptr2); if (f1 > f2) { return 1; } / / 如果 f1 比較大就傳回正數 else if (f1 < f2) { return -1; } return 0; } // 用 compare_grade( ) 比較 grade 中每個 float,由小到大排序: void GradeList::sort_grade_list(void) { qsort(grade, students, sizeof(float), compare_grade); } 另一個與這樣的 static 相對的修飾詞是 extern,這個修飾詞用來讓你使用其他檔案的全域變數與函式,在變數宣告或函式原型宣告前加上 extern,則編譯器不會產生新變數或函式,而是在連結(linking)階段才使用其他檔案中的變數或函式,例如: A.cpp int curUsers = 5; B.cpp extern int curUsers; / / 不可以再給初始值 修飾函式中的區域變數 以下...

【轉載】C/C++中的volatile使用時機?

(原作者)http://freestyler.pixnet.net/blog/post/23872864-c-c%2B%2B%E4%B8%AD%E7%9A%84volatile%E4%BD%BF%E7%94%A8%E6%99%82%E6%A9%9F%3F C/C++ 的volatile C/C++中的volatile使用時機? .不知各位對volatile(揮發性的)這個字陌不陌生? 我相信大家在一些程式或多或少都看  過這個字眼, 但是究竟要在何種場合用它呢? .當然一定是有需要, C/C++才會有這個保留字, 否則只是增加programmer的困擾而已 .有2兩個場合(I/O & multithread program), 供各位參考! .請大家check自己的程式中(尤其是第2個場合), 若有的話請記得加上volatile 1. I/O, 假設有一程式片斷如下        U8   *pPort;        U8   i, j, k;              pPort = (U8 *)0x800000;           i = *pPort;            j = *pPort;            k = *pPort;         以上的i, j, k很有可能被compiler最佳化而導致產生        i = j = k = *pPort;     的code, 也就是說只從pPo...

指標

int x, y, *ip, *iq; x = 2; /* 敘述 1 */ y = x + 3; /* 敘述 2 */ ip = &x; /* 敘述 3 */ iq = ip; /* 敘述 4 */ *iq = *ip + y; /* 敘述 5 */ 敘述四之指標 iq 與指標 ip 同時指向 x ,因此 *iq 與 *ip 和 x 是相等的。

指標

    int *ip;       /* ip 為一指標變數 */     int x = 2, y;     ip = &x;     y  = *ip + 1;  /* 與 y = x + 1; 相同 */     /* 其輸出結果為: 2 65524 2 65524 3 65522 */  y=*ip+1的*ip為間接取值, 不是取ip的值,而是取ip所指向的記憶體位址的值,因此該敘述與y=x+1相同

指標

int *a; int b = 123; a = &b; cout << "b: "  << b  << endl; cout << "&b: " << &b << endl; cout << "*a: " << *a << endl; cout << "a: "  << a  << endl; 我們可宣告一變數a為指標,其值為記憶體之位址 變數b的&符號表示變數b的記憶體位址之值

Convert RPM to DEB

Convert RPM to DEB Install alien command on Debian / Ubuntu Install alien command on Ubuntu as shown below. # sudo apt-get install alien Use alien command to convert rpm to deb file The following example converts the linuxconf-devel rpm file to linuxconf-devel deb file. Once you generate the deb file, you can install it on Ubuntu or Debian. # alien linuxconf-devel-1.16r10-2.i386.rpm linuxconf-devel_1.16r10-3_i386.deb generated

以Blender建立杯子

圖片
1. 利用CUBE以擠出法(熱鍵E)來建立。 2. 向下E,然後SCALE DOWN(熱鍵S)。 3. 再向下E,做出腳的部份,向下E,SCALE UP,向下E,做出底座的部份。 4. 在右欄於EDIT MODE選擇OBJECT MODIFIERS,選擇ADD MODIFIER,增加VIEW和RENDER的數量至適合的量。 5. 在左欄選擇SMOOTH。 6. 在右欄為CUBE上色。

以Blender建立一個房子

圖片
1. 建立兩個方塊。 2. 右欄的工具列可用熱鍵 "N" 開啟並調整方塊的位置與大小。 3. 上面的方塊按TAB以EDIT MODE修改,用 "面模式" 將頂部縮小。 4. 增加打光。