EasyC++,C++指針初探
大家好,我是梁唐。
這是EasyC++系列的第15篇,咱們來聊聊C++中的指針。
想要追求更好閱讀體驗的同學(xué),可以點擊文末的「閱讀原文」,訪問github倉庫。
指針初探
前言
C++可以說是成也指針、敗也指針。依靠著指針,我們可以靈活地操控變量內(nèi)存地址,實現(xiàn)很多獨有的功能。但也正因為指針,尤其是使用不當(dāng)?shù)臅r候會產(chǎn)生許多的問題。導(dǎo)致許多工程師對于C++以及指針深惡痛絕,以至于C++之后的許多語言都摒棄了指針的設(shè)計,比如Java和Python。
我們先把頭疼的內(nèi)容放一放,先從一些簡單的概念開始。
首先要明確的是指針是一個變量,它特殊的點在于雖然同樣是變量,它存儲的并不是值,而是一個內(nèi)存地址。內(nèi)存地址顧名思義就是存放在內(nèi)存當(dāng)中的位置,對于非指針的變量, 我們也可以使用&操作符去獲取它的地址。這就是為什么我們使用scanf在讀取變量的時候,需要在變量名之前加上一個&符號。
- int a;
- scanf("%d", &a);
目的就是為了將a變量的地址傳給scanf函數(shù),從而將屏幕當(dāng)中讀取到的內(nèi)容填寫到a變量對應(yīng)的地址當(dāng)中。
我們也可以直接輸出一個變量的地址,但輸出結(jié)果是一個十六進制的數(shù),代表一個內(nèi)存位置。如果大家學(xué)過匯編或者是了解過底層的話,應(yīng)該不陌生。這個輸出的結(jié)果是給機器看的,人類無法讀懂。
- int a;
- cout << &a << endl;
聲明和初始化
指針和普通變量不同,它存儲的值是地址。所以在聲明指針的時候,也會有一點細(xì)小的區(qū)別。我們通過*符號創(chuàng)建指針,*運算符稱為間接值(indirect value)或解除引用(dereferencing),現(xiàn)在理解這兩個概念可能有些費勁,沒關(guān)系我們可以先放一放。只許看記住使用*創(chuàng)建指針即可,*寫在類型和變量名中間,如:
- int * p;
這樣我們就創(chuàng)建了一個int型的指針,它的名字叫做p。關(guān)于*的位置,有些人喜歡緊跟著變量類型,有些人喜歡緊跟著變量名。其實都可以,看個人喜好。傳統(tǒng)上來說C程序員喜歡后者,突出ptr是一個指針。
- int *ptr;
C++程序員更喜歡前者,突出是一個int型的指針:
- int* ptr;
這兩種都可以,對于編譯器來說沒有任何區(qū)別。但是要注意的是,每一個指針變量都需要一個*:
- int a, *ptr;
前面說了,由于指針的值是一個地址,所以我們在對指針進行初始化或者賦值的時候,就需要用到取地址符。
- int a = 3;
- int *p = &a; // 獲取了a的地址
當(dāng)我們有了指針變量之后,我們可以使用*來訪問它指向的內(nèi)存地址的值。
- int a = 3;
- int *p = &a;
- cout << *p << endl; //output: 3
要注意的是,由于指針p指向a的地址,所以當(dāng)我們通過*符號修改了p指向的值之后,a的值一樣會發(fā)生變化。
- *p = 5;
- cout << a << endl; //output: 5
正因為指針有這樣的特性,所以使用的時候千萬小心……
本文轉(zhuǎn)載自微信公眾號「Coder梁」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Coder梁公眾號。