<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
C/C++語言擁有在程式執行時獲得變數的地址和操作地址的能力,這種用來操作地址的特殊型別變數被稱作指標。
翻譯翻譯什麼tmd叫tmd指標!
變數或常數的指標儲存的資料是 :對應的變數或常數在記憶體中的地址。
圖解:
此時 我們定義三個指標 p1, p2, p3 分別指向a, b, c ,那麼p1中儲存的資料是變數a所佔用記憶體的首地址:0x00;
b和c中儲存的資料是什麼呢? 沒錯,就是0x02和0x04。
顯然。若要知道變數a的值,首先讀取指標p1中的資料0x00,然後讀取記憶體0x00和0x01中的資料就可以了。這個時候,會出現一個問題:怎麼才能確定究竟要讀取幾個單位記憶體中的資料呢?畢竟p1中只儲存了0x00呀。這個時候 ,指標的型別就發揮了作用。舉個例子:如果定義的指標是int型別的,那麼讀取的時候自動從指標中儲存的初值向後讀取4個位元組;float型別的指標就是讀取8個位元組。這樣就可以既完整又不多餘的取出所需要的資料了。
總結一下一個指標的兩個要素:指標型別和指標所指變數的初地址。
指標在定義的時候最好直接初始化,否則可能出現意想不到的結果。
@定義一個指向變數的指標。
/*定義一個指向int型別變數a的指標p*/ int a = 3; int * p; p = &a; //把a的地址賦值給p; /*下面的語句最好不要用!!!!*/ p = &28; //這也是可以的,p指向的地址中儲存的資料是28. /*可以用下面的語句代替上面的語句*/ *p = 28;
間接參照操作符也是 *
*p 取出p指向的記憶體空間中的值。
所以區分定義或是參照指標可能有些麻煩。
只有同型別的指標和變數才能通過 * 和 & 互相建立關係。
int a = 0; int temp; int * p = &a; /*指標的間接參照*/ cout<< *p; //輸出結果是0 /*以下兩種表達等價*/ *p = 3; //把3賦值給a a = 3; /*以下兩種表達效果相同。都是把變數a賦值給temp*/ temp = a; temp = *p; //temp被賦值為0 /* 以下表達是錯誤的*/ float f = 3.1; int * p = &f; //error,指標型別與變數型別不匹配
這個部分本來應該在定義指標變數裡,但是因為需要指標的間接參照作為鋪墊,所以把它單獨拿出來了
我們先區分一組概念:常數、指向常數的指標、常指標以及指向常數的常指標。
1.常數:顧名思義不發生改變的量,想必大家是熟悉的。
2.指向常數的指標:只限制間接存取操作,不限制指標指向的值本身的操作規範。
3.常指標:指標中儲存的地址一經初始化就不能改變了,也就是說常指標只能指向一個固定的地址,但是地址中儲存的資料是可以改變的哦~
4.指向常數的常指標:根據上面三個概念大家應該可以理解了,就是指標中儲存的地址和該地址中的資料皆不可更改。
例如:
int b = 4; const int a = 5; //定義一個常數a。 /*注意觀察以下三個定義中const的位置*/ const int *p = &a; //定義一個指向常數的指標p,指向常數a。 p = &b; //這個也是沒問題的哦 *p = 6; //error,這個間接存取操作是不可以。 int * const p2 = &b;//定義一個常指標p2 *p2 = 6; //這個是可以的,注意區分和上面的區別 const int * const p3 = &a; //指向常數的常指標p3 /* emm我也不知道該註釋點什麼,自行體會吧~*/ *p = 11; //error,因為p指向的是常數,常數的值不可更改 *p2 = 2; //true,p2是常指標,指向的地址不變,但地址中的值可以更改 *p3 = 4; //error p3 = &b; //error
指標本質上也是一個變數或常數,那麼指標也是有地址的,而指向這些地址的指標被稱為指向指標的指標。
int a = 25; int * p = &a; int pp = &p; //true,pp指向的地址中儲存的是指標p的地址。
一個陣列的陣列名就是一個常指標。
int arr[] = {5,4,6,9,8,3};
arr就是一個指標,而且指向陣列的第一個元素arr[0]。
指標陣列:
char * arr[] ={"this is", "a", "C++ !"};
在此提及一下字串常數:
char * a /* 雙引號的作用: 在字串結尾加一個 ,並分配記憶體空間,返回首地址。 */ a = "dshfw";
指標只能支援 + 和 - 的運算,但這已經足夠滿足大多數指標操作的需求了。
/*接下來以陣列為例,只介紹加法 ,減法同理*/ int arr[] = {5,4,6,9,8,3}; cout<< *p; //輸出結果為5 cout<< *(p+1); //輸出結果為4 /*列印整個陣列*/ for(int *p = arr; p < arr+5; ++p) { cout<< *p<<' '; } cout<<endl;
/*函數原型*/ void * malloc(size_t size); /*使用:開闢5個int型別變數的儲存空間,返回首地址*/ /**/ int *arr; if(arr = (int *) malloc(5 *sizeof(int)) == NULL) { exit(1); } /*釋放堆記憶體*/ free(arr);
注意釋放陣列記憶體空間時,delete後有[] !!!
/*申請一個5個元素的陣列空間*/ int * arr = new int[5]; delete[] arr; /*申請一個變數的空間*/ int * arr = new int; delete arr;
函數名和陣列名一樣都是一個指標,有時我們需要把函數名作為引數傳入其他函數中。
arr[] = {4,6,9,8,5,3,2,7,5}; /*兩種不同的寫法均可以*/ void Sort_Shell(int arr[], int n) { /*code*/ } void Sort_Shell(int * arr, int n) { /*code*/ } /*下面這種是不可以的!!!*/ void Sort_Shell(int * arr[], int n) { /*code*/ }
舉個小小的例子
/*來個小小的希爾排序演演算法*/ void Sort_Shell(int arr[], int n) { int gap = n / 2; for(; gap > 0; gap /= 2) { for(int i = gap; i <n; ++i) { int temp = a[i]; int j = i; while(j >= gap&& temp < arr[j - gap]) { a[j] = a[j - gap]; j -=gap; } a[j] = temp; } } }
開了個小差,接下來回歸正題,我們的指標。
static bool cmp(int a, int b) { return a < b; } void show(bool * b) { if( &b) { cout<< true; } else { cout<<false; } }
首先來看個例子:
void swip(int a, int b) { int c = a; a = b; b = c; } int main() { int a = 5, b = 6; swip(a, b); cout<<a<<' '<<b; }
輸出結果:5 6
並未達到交換的效果,因為函數內部對形參的修改並不能反映到上層的main函數中。
此時我們可以通過指標作為函數的入口引數來實現預期的功能。
void swip(int * a, int* b) { int c = *a; *a = *b; *b = c; } int main() { int a = 5, b = 6; swip(&a, &b); cout<<a<<' '<<b; }
輸出結果:6 5
傳遞函數的指標雖然能達到預期效果,但是確實以破壞函數的黑盒為代價,可讀性差,偵錯困難。
有沒有什麼更好的辦法呢?接下來 參照登場了。
void swip(int &a, int &b) { int c = a; a = b; b = c; } int main() { int a = 5, b = 6; swip(a, b); cout<<a<<' '<<b; }
輸出結果:6 5
克服了指標作為引數的弊端。話又有點多了,哈哈,這和指標有什麼關係呢······
//函數原型 int strcmp(const char * arr1, const char * arr2); //使用舉例: char arr1[] = "dfetf"; char arr2[] = "cfefef"; int b = strcmp(arr1, arr2);
輸出b的值是大於0 的。
指標強大而又危險,卻也是C和C++的靈魂,由於其可以直接操作記憶體地址的特殊性,使得理解指標是如何工作的在C和C++中必不可少,若想成為一名優秀的C++工作者,必須要掌握指標。
到此這篇關於C/C++指標介紹與使用詳解的文章就介紹到這了,更多相關C++指標內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45