指標
基本概念
- 符號意義
副程式
- 為何副程式必須導入指標
- 副程式引入處指標與陣列不同
- 如何從副程式得到指標長度
- 間接定址與直接定址
- 為何需要指標的指標
指標類型
- 指標的指標
- 結構指標
- 虛無指標
下周分享內容:如何有效率的編程
基本概念
符號意義
記住兩句話&找地址
*找數值
int i=1
程式初始化配置記憶體給變數
i
使用並在裡面儲存數值1
可以透過
&i
查找記憶體地址 int* p=&i
創建一個指標,並告知編譯器這個用來儲存儲存整數,再來存入
i
的地址可以透過
*i
查找記憶體地址內的數值
關於指標的創建,請記住這句話
告知編譯器這個用來儲存儲存整數
後續會繼續討論,這裡先討論兩個區別
int* i
與 int *i
有什麼區別呢
在編譯器內他們是等價的,但建議使用前者
的方式宣告,更容易閱讀,可以想像
把他們當成另一個型態
這樣更容易閱讀對吧XDD
的方式宣告,更容易閱讀,可以想像
把他們當成另一個型態
int*
這樣更容易閱讀對吧XDD
那什麼時候才需要用到把星號放到後面呢?
直覺得˙會把它看成
等價於
這時候我會建議你都把他們放後面吧
這樣就更容易閱讀了
int* i, j;
你覺得後面的j是什麼型態呢直覺得˙會把它看成
int*
型態但其實他們是等價於
int* i; int j
這時候我會建議你都把他們放後面吧
int *i, *j;
or int *i ,j;
這樣就更容易閱讀了
副程式
為何副程式必須導入指標
有了前者得概念,現在來出一到小題
如何使用副程式修改變數
簡單的來形容主程式內有一個變數
我要呼叫一個副程式修改i的數值
我要呼叫一個副程式修改i的數值
int i=0;
modify();
modify();
如何實做呢 https://goo.gl/2EMGo3
副程式引入處指標與陣列不同
fun(int* arr);
與
fun(int arr[4]);
用途上來看最主要大概差異在
前者沒有把數字定死,想傳幾個都可以傳
即便是後者,你傳入一個長度是5的陣列能然能取到
第5個的數值,這純粹只是運氣好,第5個的數值
只是因為宣告時記憶體是連續的,運氣好可以讀到
程式如果複雜了,並不能保證他不會修改
如何從副程式得到指標長度
通常來說都會在下標的第[0]個儲存長度
這可以節省運算時間,也讓你更好操作
這可以節省運算時間,也讓你更好操作
C++可以透過樣板取得取得長度
template<size_t N>
void arr_len(int (&arr)[N]) {
std::cout << "sizeof = " << sizeof(arr) << " / ";
std::cout << sizeof(arr[0]) << std::endl;
std::cout << "len = arr[" << N << "]" << std::endl;
}
樣板會干擾到拆分程式,還是建議採用前者
間接定址與直接定址
假設有一個二微陣列是
那麼在記憶體上第三個是
輸入
先找到[0]的地址再去查找地址的數值
速度上會略低,如果宣告成一微陣列
自己手動算出
效率上會來的好一些,在操作上也較容易
[2][2]
那麼在記憶體上第三個是
[1][0]
輸入
[1][0]
在操作上必須找兩次,先找到[0]的地址再去查找地址的數值
速度上會略低,如果宣告成一微陣列
自己手動算出
[2][2]
是第3個效率上會來的好一些,在操作上也較容易
為何需要指標的指標
- 存取動態二維陣列
- 副程式拆解上的需求
這可能有點難形容,兩者其實
也差不都在形容同一件事情
直接看代碼或許會比較好理解
也差不都在形容同一件事情
直接看代碼或許會比較好理解
核心代碼
imch imgraw::cubicInterpolate (imch* p, double x) {
double temp = (double)(p[1] + 0.5 *
x*(p[2] - p[0] +x*(2.0*p[0] - 5.0*p[1] + 4.0*p[2] -
p[3] + x*(3.0*(p[1] - p[2]) + p[3] - p[0]))));
return (imch)temp;
}
用來控制核心代碼的驅動
imch imgraw::bicubicInterpolate (imch** p, double y, double x) {
imch* arr = new imch[4];
for (int i = 0; i < 4; ++i)
arr[i] = cubicInterpolate(p[i], x);
return cubicInterpolate(arr, y);
}
如果沒有將核心代碼拆分出來,核心代碼必須重複5次
指標的指標
動態二維陣列的應用
// 創建
int** ptr = new int* [2];
for (int i = 0; i < 2; ++i)
ptr[i] = new int [2];
// 釋放
for (int i = 0; i < 2; ++i)
delete [] ptr[i];
delete [] ptr;
結構指標
結構
struct node{
int i;
};
結構指標要用
->
去指向 node a, *b;
b = &a;
a.i = 1;
cout << b->i << endl;
return 0;
虛無指標
這應該很少會用到,但如果你要把程式寫好
寫得足夠嚴謹,就必須得用他,
很多底層的代碼,都是這樣定義的
寫得足夠嚴謹,就必須得用他,
很多底層的代碼,都是這樣定義的
//接收不同型態的資料
void pri_int(void* data){
int temp=(int)*data;
cout << "temp=" << temp << endl;
}
這個副程式將可接受各種型態的指標
最終cast成整數的樣貌,印出
最終cast成整數的樣貌,印出
沒有留言:
張貼留言