相信很多人都還對指標這定義很不熟悉,甚至在寫程式時也很容易搞混,沒關係小弟也是從這懵懵懂懂的道路走過來的,這邊先直接給一道程式大家先試著想想看答案是什麼?!
int main()
{
int a = 5;
int b = a;
std::cout << a << std::endl;
std::cout << b << std::endl;
a = 10;
std::cout << a << std::endl;
std::cout << b << std::endl;
return 0;
}
// output
// a = 5
// b = 5
// a = 10
// b = 5
小弟本身是先從 python 學起(雖然大學修課是C/C++),如果上面程式來看自己會覺得最後 a = 10
、b = 5
,沒錯答案的確是這樣起初剛學指標時也很容易會被這種題目混淆,會思考著 b 到底是獲得 a 的數值還是位址。
接著就是位址、指標的重點了,以下面程式來看當宣告變數時會給予一個記憶體空間去做存放,而這空間就是人家常提到的位址,那 a 這個變數便代表了 0x0011FF00
這個位址,而這位址存放的元素為 int 變數(4 個byte)。
int a = 10;
int b = 20;
int c = 30;
那麼 pointer 要做什麼用呢,當想要去更動位址裡面的數值時 pointer 就派上用場啦,可以應用到的範圍很廣這邊就先講一下他的基本要數,從下面範例來看這次 b 直接取了 a 的位址,那當 b 給予其他數值時(也就表示該位址做更動) a 的數值也會跟著做改變。
int main()
{
int a = 5;
int *b = &a;
std::cout << a << std::endl;
std::cout << *b << std::endl;
*b = 15;
std::cout << a << std::endl;
std::cout << *b << std::endl;
return 0;
}
// output
// a = 10
// b = 10
// a = 15
// b = 15
那麼先看了上面的 pointer 起手式後,來簡單講解 *
與 &
做什麼用的,當你宣告變數時該變數名稱只是代表該型態值,也就如下面程式當宣告 a 為 10,那這個 a 變數只是一個 int 型態值有它自己的記憶體空間,所以當你宣告 b 為 a 時就只是將 a(10) 這個值也給 b,那 a 與 b 各為不同記憶體空間。
int a = 10;
int b = a;
當想要牽一髮而動全身的效果時就得用到 *
與 &
,如下程式所示,int *b
為要放入 int 位址的變數,&a
為將 a 的位址取出來,所以 int *b = &a
為將 a 的位址給予 b,所以 b 拿到的是 a 的位址。
*
:為位址變數&
:取變數位址
int a = 10;
int *b = &a;
// a 位址 0x61fe14
// b 位址 0x61fe14
但要將 b 位址裡面的數值顯示出來該怎麼做呢? **
就是將位址裡面的值顯示出來,有點像負負得正的概念
std::cout << a << std::endl;
std::cout << *b << std::endl;
// a => 10
// b => 10
剛有提到 pointer 應用場景很廣,這裡就介紹常用到的陣列(Array),陣列與一般變數不同的是陣列可以存很多個變數,也就是說一般變數只給一個記憶體空間,而陣列則是給很幾個記憶體空間,聽起來很繞口直接看程式!
int main()
{
int a = 10;
int b[2] = {10, 20};
int c = 30;
// testFunction(&a, &b);
std::cout << &a << std::endl;
std::cout << b << std::endl;
std::cout << &c << std::endl;
return 0;
}
// output
// a 位址==> 0x61fe1c
// b 位址==> 0x61fe14
// c 位址==> 0x61fe10
這次你有發現 b 不需要 &
就能直接顯示位址了耶,宣告陣列本身就是記憶體位址,那麼不就可以直接將陣列位址給其他人了囉!? 請看程式~
int a[3] = {3, 4, 5};
int *b = a;
// a 位址==> 0x61fe14
// b 位址==> 0x61fe14
下面程式有讓你覺得好像有看過類似這樣的陣列操作嗎?
由於 b 本身就是陣列位址,所以可以藉由 b+i
的操作來換下一個記憶體位址,再配合上面有提到的負負得正的概念, *(b+i)
就能將值取出來囉~
int b[3] = {10, 20, 30};
for(int i = 0; i < 3; i++)
{
std::cout << *(b+i) << std::endl;
}
當宣告一個變數就是挪出一個記憶體空間去存放這個變數,那就有了位址與數值的關係。
int a = 2
,a 為 int 型態數值,數值為 2int *b = &a
,b 為 int 指標位址,位址為 a 的位址int c[3] = {10, 20, 30}
,b 為 3 個 int 指標位址,各存放 10、20、30 數值int *d = c
,d 為 int 指標位址,指向 c 的位址