#include格式
1. include <fileName> : 叫前置處理器到系統的include資料夾去找此檔案。主要用於標準函式庫中的檔案。
2. include "fileName" :先去目前工作目錄下找,找不到再到系統的include資料夾去找。此使用方式常用於我們自己寫的檔案。
const V.S #define
1.const: constant variable, 一開始宣告時, 便一定要定義它的值, 一旦定義完後, 便無法改變此變數的值。就像java中的final關鍵字。
2.#define:replacing text macros, 巨集命令, 通常定義在程式的一開頭, 且都是使用大寫。
ex: #define PI 3.14
Preprocessor執行程式前會先將使用define變數的變數名稱替換成常數值後, 才開始編譯。
Preprocessor並不懂c++語法,所以在做macros時, 不會做型別與語法的檢查。而const會。
inline
inline適合用在內容很少的函式,
ex:
inline giveme(){
a+a;
}
你在使用的時候,呼叫到inline的函式,
編譯器會自動幫你替代成函式中的內容,
不過編譯器會看狀況要不要替代。
result = giveme();
==>result = a+a;
優點:
因為是將function替代掉, 直接執行
比一般呼叫函式速度快,執行流程不會跳來跳去, 一般呼叫函式會切換,所以執行慢。
但是缺點也是你的程式檔案內容會長大
typedef
1. 用typedef可以為已經存在的型別另外建立新的名稱。
typedef 型別 新的名稱;
ex: typedef unsigned char abc;
Postfix increment Operator V.S Prefix increment Operator
1. Postfix increment Operator: 後置遞增運算子, i++
2. Prefix increment Operator, 前置遞增運算子, ++i
ex:
int i =5;
int j = (i++)+5
==> i = 6, j = 10
ex:
int i =5;
int j = (i++)+i+(i++);
==> i=7, j = 17
ex:
int i=5;
int j = (--i)+i+(--i)
==> i = 3, j = 11
<<,>>
1. 用乘除法(*或/)是很耗CPU時間, 所以我們可以利用<< , >>來做乘除運算,藉此加快速度。
<< n 等於 數字乘上2^n
>> n 等於 數字除上2^n
參數中的預設值
這大概是我寫c++時最喜歡它的地方,
void getme(int a,b=3);
當caller call getme()只有給a的值, 沒給b的值時,
==> getme(15);
getme()會自動幫你把b值填上, 這個b =3。
但是預設值只能從最右邊的值開始設喔!
也就是你不能寫 getme(int a=3, b)
一定要b有預設值, a才可以設定預設值
local variable V.S static variable
1. local variable (在函數中的變數)會被放在stack中, 當函式消失, stack也會不見
2. static variable 不會放在函數stack中, 會在程式一執行時便存在於記憶體中
當local variable和Global variable有重複名稱時,
會以local variable為主, 如果在函數中想要存取同名稱的global variable,
就使用 :: 。
ex: ::x
就會存取到global 的x
指標與陣列
指標是用來存放位址的(通常4 bytes),來看下面的例子
Ex:
int j =9;
int *i = &j; // 把j的位置給i
==> i = j的位置, *i = 9; // * 是提取值的意思
可以看成 (int*) i=&j;
用這個方式來記會比較好。
因為在宣告型態之後的寫法,
是這樣寫的:
i = &j;
*i = j;
如果你是用第一種方法 int *i = &j; 來記一定會混淆。
另外指標的*與陣列的[]可以互用:
int a[] = {7,8,9};
int *i = a;
==> *i = 7, *(i+1) = 8, i = a陣列的位置
==> i[0] =7
==>*a = 7, *(a+1) =8
另外來談談直接new一塊記憶體
一開始宣告就配置記憶體
int *a=new int(10);
釋放記憶體
delete a;
需要的時候再配置記憶體
int *a;
...
...
a = new int(10);
或 a= new int;
配置陣列的空間
int *parray = new int[9];
..
delete [] parray;
⦿ 陣列變數不能指定給另一個陣列變數, 通常會使用指標來指定,
不用指標的方式就是要用迴圈一個一個複製。
ex:
int a[]={1,2} 或 int a[5] = {1,2}
int b[] = a[]; // 錯誤!
Reference Type
Reference Type是建立variable的別名, 把它想做是你的綽號,
你的名字叫做王大明, 朋友叫你小明, 你媽叫你阿明。
王大明,小明跟阿明都是叫你的意思,對吧!
Reference Type就是取綽號的意思。
這裏有個很重要的事情, 就是宣告的時候,
必須一定要初始化。
Ex:
int i=1;
int &j=i; // j就是你的綽號, 在這邊一定要給值,讓它初始化
==> i =1, j=1
改變i的值,會連j 也一起改, 因為他們兩個是指向同一塊記憶體
i = 99;
==> i =99, j=99
Reference Type 常用在function的參數傳遞跟回傳值上。
呼叫函式的方法
呼叫函式的方式有三種:
1. call by value : 把參數數值複製過去, 所以被呼叫的函式中的參數與呼叫時的參數是不同的。
2. call by address : 函數的參數型別是指標, 呼叫時是把address丟給函式
3. call by reference : 函數的參數型別是reference type, 函式中用的是綽號。
call by address 和call by reference其實是一樣的,
都是指向同一個記憶體。
至於要選擇哪個用呢?
call by reference前面有說,宣告時一定要初始化。
至於call by address並沒有這樣規定。
因此, call by reference時, 丟過來的參數一定要是已存在變數或物件,
而call by address你甚至可以丟個null pointer過來。
ex:
Call by Address
void giveme(int *i);
....
int x;
giveme(&x);
把它想像成 int* i= &x;
陣列也是一種指標
void giveme(int array[]);
....
int originalArray[10];
giveme(originalArray);
c++陣列沒有可以得知陣列size的function,
所以在傳的時候會順便把size傳過去
ex: void giveme(int array[], int size);
Call by reference
void giveme(&x);
....
int i =9;
giveme(i);
把它想成 &x = i;
Return value
1. return pointer
2. return reference
ex:
int *funtion(int *p){
return p; // return pointer
}
int &function(int *p){
int i=100;
return *p;
或return i;
}
public, protected, private
// struct 成員預設都是public, from C
struct Sky{
int a=0;
private: //以下才是private
int b;
}
// class 成員預設都是private
class Sky{
int a =0;
public: //以下才是public
int b;
}
“. ” v.s "->"
呼叫function的時候, 有兩種方式, “. ” v.s "->"
很常有人搞不清楚, 這是很基本的喔~
得要好好釐清才行:
物件.function / 物件.variable
pointer -> function
前者是物件呼叫函式的方式,
使用物件來呼叫函式就要用 ". "
如果你是指標的話那就使用 -> 來呼叫函式/variable。
Class
定義在類別中的funtion有個特性:預設是inline funtion(for all?)。
宣告方式除了在class中直接宣告並定義,
另一種:
class Sky{
void int method();
}
void Sky::method(){
....
}
static
class Sky{
static int b=99;
static int a;
}
int Sky::a=19;
static function
class Sky{
static getRain()...
}
使用的時候:
Sky::getRain();
new class方式:
Sky mySky;
Sky *sky = new Sky;
sky = &mySky; // ok
*sky = mySky; // not ok
沒有留言:
張貼留言