2012年10月30日 星期二

[cpp] running sequence

[cpp] running sequence
#include <iostream>
using namespace std;

class PointDemo {
public:
    PointDemo(int);
    ~PointDemo();
 
    void show();
private:
    // Nested Class
    class Point {
    public:
        Point();
        Point(int, int);
        int x() { return _x; }
        int y() { return _y; }
        void x(int x) { _x = x; }
        void y(int y) { _y = y; }
    private:
        int _x;
        int _y;
    };
 
    Point **_points;
    int _length;
};

// 實作內部類別
PointDemo::Point::Point() {
    _x = 0;
    _y = 0;
    cout << "enter point initial 00" << endl;
}

// 實作內部類別
PointDemo::Point::Point(int x, int y) {
    _x = x;
    _y = y;
    cout << "enter point set xy" << endl;
}

PointDemo::PointDemo(int length) : _length(length) {
    cout << "enter points demo1" << endl;
    _points = new Point*[_length];
    cout << "enter points demo2" << endl;
    for(int i = 0; i < _length; i++) { 
        cout << "enter points demo3" << endl;
        _points[i] = new Point(); 
        _points[i]->x(i*5);
        _points[i]->y(i*5);
    } 
}

void PointDemo::show() {
    for(int i = 0; i < _length; i++) { 
    cout << "enter point show" << endl;
    cout << "(x, y) = (" 
         << _points[i]->x() << ", "
         << _points[i]->y() << ")"
         << endl;
    } 
}

PointDemo::~PointDemo() {
    for(int i = 0; i < _length; i++) {
        cout << "enter ponit delete" << i << endl;
        delete _points[i];
    } 
    delete [] _points;
}

int main() {
    cout << "+++++++++++++++++++++++++" << endl;
    PointDemo demo(10);
    cout << "-------------------------" << endl;
    demo.show();
    cout << "#########################" << endl;
    return 0;
}


Output:
+++++++++++++++++++++++++
enter points demo1
enter points demo2
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
enter points demo3
enter point initial 00
-------------------------
enter point show
(x, y) = (0, 0)
enter point show
(x, y) = (5, 5)
enter point show
(x, y) = (10, 10)
enter point show
(x, y) = (15, 15)
enter point show
(x, y) = (20, 20)
enter point show
(x, y) = (25, 25)
enter point show
(x, y) = (30, 30)
enter point show
(x, y) = (35, 35)
enter point show
(x, y) = (40, 40)
enter point show
(x, y) = (45, 45)
#########################
enter ponit delete0
enter ponit delete1
enter ponit delete2
enter ponit delete3
enter ponit delete4
enter ponit delete5
enter ponit delete6
enter ponit delete7
enter ponit delete8
enter ponit delete9


Ref :
http://caterpillar.onlyfun.net/Gossip/CppGossip/NestedClasses.html

2012年10月25日 星期四

[cpp] FunctionPointer

[cpp] FunctionPointer

程式在執行時,函式本身在記憶體中也佔有一個空間,而函式名稱本身也就是指向該空間位址的參考名稱,當呼叫函式名稱時,程式就會去執行該函式名稱所指向的 記憶體空間中之指令。

您可以宣告函式指標,並讓它與某個函式指向相同的空間,函式指標的宣告方式如下所示:
傳回值型態 (*指標名稱)(傳遞參數);



#include <iostream> 
using namespace std; 

void swap(int&, int&);
bool larger(int a, int b);
bool smaller(int a, int b);
void sort(int*, int, bool (*compare)(int, int));

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, bool (*compare)(int, int)) { 
    
    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])) {
                
                cout << "{";                
                for(int k = 0; k < 5; k++) {
                    cout << arr[k] ;
                    if (k<4){
                        cout << ", "; 
                    }
                }
                cout << "} ";

                cout << "j in " << j <<" swap : "<< "(" << arr[j+1] << "," << arr[j] << ")" << endl;


                swap(arr[j+1], arr[j]); 
                flag = 1; 
            }//if 
        }//for 
    }//for 
}



int main() { 
    int number1[] = {3, 5, 1, 6, 9};
    cout << "sort {3, 5, 1, 6, 9}" << endl;
    
    sort(number1, 5, larger);
    cout << "大的在前 ";
    
    for(int i = 0; i < 5; i++) {
        cout << number1[i] << " ";
    }
    cout << endl;

    int number2[] = {3, 5, 1, 6, 9};
    cout << "sort {3, 5, 1, 6, 9}" << endl;
    
    sort(number2, 5, smaller);
    cout << "小的在前 ";
    
    for(int i = 0; i < 5; i++) {
        cout << number2[i] << " ";
    }
    cout << endl;
 
    return 0; 
}


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sort {3, 5, 1, 6, 9}
{3, 5, 1, 6, 9} j in 0 swap : (5,3)
{5, 3, 1, 6, 9} j in 2 swap : (6,1)
{5, 3, 6, 1, 9} j in 3 swap : (9,1)
{5, 3, 6, 9, 1} j in 1 swap : (6,3)
{5, 6, 3, 9, 1} j in 2 swap : (9,3)
{5, 6, 9, 3, 1} j in 0 swap : (6,5)
{6, 5, 9, 3, 1} j in 1 swap : (9,5)
{6, 9, 5, 3, 1} j in 0 swap : (9,6)
大的在前 9 6 5 3 1 
sort {3, 5, 1, 6, 9}
{3, 5, 1, 6, 9} j in 1 swap : (1,5)
{3, 1, 5, 6, 9} j in 0 swap : (1,3)
小的在前 1 3 5 6 9 

Ref :
http://caterpillar.onlyfun.net/Gossip/CppGossip/FunctionPointer.html

[cpp] return address example

[cpp] return address  example

在C++中傳遞陣列或傳回陣列一律使用傳遞記憶體位址的方法,因為陣列名稱本身就是個 指標,儲存有位址資訊。


#include <iostream> 
using namespace std; 

int* createArray(int);
void deleteArray(int*);

int main() { 

 int m = 10; 
 int *arr = createArray(m); 

 for(int i = 0; i < m; i++) {
     arr[i] = i; 
 }
 
 for(int i = 0; i < m; i++) {
     cout << "arr[" << i << "] = " << arr[i] << endl; 
 }
 
 cout << arr << endl;
 cout << arr[3] << endl;

 deleteArray(arr);

 cout << arr << endl;
 cout << arr[3] << endl;

 return 0; 

} 

// 傳回建立的陣列位址
int* createArray(int m) { 
 
 int *a = new int[m]; // 動態配置方式

 cout << "new a[" << m << "]" << endl;
 
 for(int i = 0; i < m; i++) {

     a[i] = 0;
     cout << "a[" << i << "] = " << a[i] <<  endl;
 }
 
 cout << a <<  endl;
 return a; // 傳回建立的陣列位址

}

void deleteArray(int* arr) {
 delete [] arr; 
}

Output:
new a[10]    ---> new "array a" and initial
a[0] = 0     ---> assign initial value
a[1] = 0
a[2] = 0
a[3] = 0
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0
0x8051438    ---> cout "array a" address 
arr[0] = 0   ---> assign value
arr[1] = 1
arr[2] = 2
arr[3] = 3
arr[4] = 4
arr[5] = 5
arr[6] = 6
arr[7] = 7
arr[8] = 8
arr[9] = 9
0x8051438    ---> 尚未 delete "array arr"
3            ---> 尚未 delete "array arr"
0x8051438    ---> 已經 delete "array arr"
-1785358955  ---> 已經 delete "array arr"


由於您使用動態配置的方式,所以在使用delete之前,這塊被配置的記憶體並不會自動清除,所以您可以直接傳回 給呼叫函式的主函式,注意如果您不是使用 new來配置,則在副函式中所宣告的變數記憶體,在式執行結束後都會自動消失,則您傳回指標值也就沒有意義,也會造成存取錯誤,因為該塊記憶體在副函式 執行完畢後已經自動回收了。

Ref :
http://caterpillar.onlyfun.net/Gossip/CppGossip/returnBy.html

[cpp] pass by value & pass by address & pass by reference

[cpp] pass by valuepass by address pass by reference

01 . pass by value :

         參數傳遞時的,傳值就是傳送 變數 給函式上對應的參數,值被複製一份給參數,傳遞者接受者兩個變數
         彼此各佔有一個記憶體,互不相干

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream> 
using namespace std; 

int increment(int); 

int main() { 
    int x = 10; 

    cout << increment(x) << endl; 
    cout << x << endl; 

    return 0; 
} 

int increment(int n) { 
    n = n + 1; 
    return n; 
}

Output:
1
2
11
10



02 . pass by address :
         
         在呼叫increment()函式時,您使用取址運算子&x變數的記憶體位 址取出並 傳遞給指標n,而在函式中,您使
         用取值運算子*取出這塊記憶體位址,並作遞增動作之後再指定回該記憶體位址,共用同一個記憶體位
         置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream> 
using namespace std; 

int increment(int *); 

int main() { 
    int x = 10; 
    cout << increment(&x) << endl; 
    cout << x << endl; 

    return 0; 
} 

int increment(int *n) { 
    *n = *n + 1; 
    return *n; 
}

Output:
1
2
11
11



03 . pass by reference :
         
         參考 Reference 型態代表了變數或物件的一個別名 Aliasincrement()參數列中使用參考宣告int&;當呼叫
         increment()函式時,您不用使用 &運 算子取得x變數的記憶體位址n會自動參考至x變數的位址,由於x變數與n
         變數的記憶體位址是相同的,所以在increment()中的遞增動作,同樣會 影響x變數,共用同一個記憶體位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream> 
using namespace std; 

int increment(int&); 

int main() { 
    int x = 10; 
    cout << increment(x) << "\n"; 
    cout << x << "\n"; 

    return 0; 
} 

int increment(int &n) { 
    n = n + 1; 
    return n; 
}


Output:
1
2
11
11


Ref :
http://caterpillar.onlyfun.net/Gossip/CppGossip/PassBy.html

2012年10月24日 星期三

[cpp] GCD Recursion Example


[cpp] GCD Recursion Example

#include <iostream> 
using namespace std; 

int GCD(int, int); 

int main() { 
    int m = 15;
    int n = 45; 

    cout << "GCD: "
         
         << GCD(m, n) << endl; 

    return 0; 
} 

int GCD(int m, int n) {

    cout << "01  GCD(" << m << ", " << n << ");" << endl;  
    
    if(n == 0) 
        return m; 
    else
        cout << "02  GCD(" << n << ", " << m%n << ");" << endl;
        return GCD(n, m % n);

}


Output:
1
2
3
4
5
6
01  GCD(15, 45);
02  GCD(45, 15);
01  GCD(45, 15);
02  GCD(15, 0);
01  GCD(15, 0);
GCD: 15