在C + +的第1部分的指針和引用

2009年4月19日,張貼在ç/的C + +

指針和引用是兩個非常重要的概念,在計算機科學。 他們出現在許多編程語言與裙子或稍有不同,但基本上是相同的待遇。 在C + +中,指針是​​必不可少的技能。

指針是一種特殊類型的數據,其變量可以宣布(或不)到內存中的其他一些數據,例如。 一個指針類型的變量擁有一個內存中的其他東西的地址。 這件事可以是一些變量,常數,啟動一個數據集,函數等等,。

聲明指針

通常是通過在變量名前添加*指針的聲明。 常用的一個符號粘貼*類型到象徵性地說,我們宣布的“指針類型”,而不是一個“指針變量”的名稱,但它們是等價的。 例如:

  / /指向一個int。
 ptr_num1 ; INT * ptr_num1;

 / /左右。
 ptr_num2 ; INT * ptr_num2;

 / /指向一個雙。
 ptr_double1 ; 雙* ptr_double1;

 / /左右。
 ptr_double2 ; 雙* ptr_double2; 

後宣布,該指針存在,自己的大小,因此在內存佔用。 一般是一個指針的大小等於數位機/系統的問題,例如4個字節32位系統。

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 pc ; int i, * pi ; double d, * pd ; // O operador sizeof diz o tamanho do tipo do seu argumento. cout << "Size of char: " << sizeof ( c ) << " bytes" << endl ; cout << "Size of int: " << sizeof ( i ) << " bytes" << endl ; cout << "Size of double: " << sizeof ( d ) << " bytes" << endl ; cout << endl ; cout << "Size of char*: " << sizeof ( pc ) << " bytes" << endl ; cout << "Size of int*: " << sizeof ( pi ) << " bytes" << endl ; cout << "Size of double*: " << sizeof ( pd ) << " bytes" << endl ; 字符C,PC,我* PI,雙D,PD * / / sizeof運算符表示其參數的類型的大小cout <<“請字符的大小:”<< sizeof(C)的<<“字節“<< endl; cout <<”請int的大小:“<< sizeof(I)的<<”字節“<< endl; cout <<”請雙的大小:“<< sizeof(D)的<<”字節“ << endl; COUT << endl; cout <<“請為char *尺寸:”<< sizeof(CP)的<<“字節”<< endl; cout <<“請為int *的大小:”<< sizeof(PI的) <<“字節”<< endl; cout <<“請雙尺寸*”<< sizeof(PD)的<<“字節”<< endl; 

使用指針

他的發言後,指針的內容是一個隨機值,浪費內存,像任何變量。 是有用的,它必須給他的東西。 作為一個指針存儲內存地址,我們需要為它分配一個有效的地址。

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
  INT X,Y;
 px, * py ; * PX,PY;

 ; X = 13;
 ; Y = 10;

 x ; &X = PX;
 y ; Y = PY;

 42 ; * PX = 42;
 py ) ++ ; (* PY)+;

 * px << endl ; COUT << endl << * PX;
 * py << endl ; COUT << endl << * PY;
 ( * px ) * ( * py ) << endl ; 法院<<(* PX)*(* PY)<< endl; 

操作(符號或符號變量名前)意味著“地址”,因為他的名字是“地址”。

還剩下什麼平等擁有能夠存儲完全相同的類型是平等的另一邊。 指針持有的地址。 因此,分配一個地址指針,在這種情況下,你需要獲得與&操作符的地址。

除有隱式類型轉換(如數字類型之間)的情況下,你的一個不同類型的東西分配一個變量,會導致一個編譯錯誤。 還好!

一旦你有一個指針指向一個有效的地址,我們可以訪問該地址的內容與操作*( 星號 ),其正式名稱是“去參考運營商。”

請注意,星號在一份聲明中表示“指針類型”,並在讀取或寫入指針的內容方面,是指“內容地址”或“內容指出”。 另外要注意不能與乘積的符號混淆。 為了避免混亂,請記住, 優先運營商的巨大的表 ,你剛剛通過了被遺忘的眼睛和下降。 在這裡,你會發現,經營者參考接管乘法運算符的優先級。 這樣做,你會記得引用的運營商,評估前的乘法運算。

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
  pa, * pb ; A,B,C,* PA,BP;
 ; A = 2
 ; B = 3;

 a ; PA =&A;
 b ; BP =&B;

 pa * * pb ; C = * PA ** BP;
 pa * * pb ; C = * PA ** BP;
 pa * * pb ; C = * PA ** BP;
 pa ** pb ; C = * PA ** BP;
 * pa ) * ( * pb ) ; C =(PA)*(BP);

 "Valor da Pegadinha: " << c << endl ; cout <<“請價值Gotcha條款:”<< C << endl; 

因此,當該測試算法,問你是什麼讓行的例子在過去五年中的任何一個,你會說,它指出PA和PB的內容相乘。 沒有更需要得到它的DP! 和打破現實生活中,如果你真的需要做到這一點,你將節省4代的過去和未來5 逐出教會 ,如果您選擇使用的最後一行。

一切可能是一個共同的變量,你可以用一個指針指向的內容,無論是讀取或寫入(除非它是明確的指針是const,但是這是另一次談話......)。

地址和指針

例如,以下面的代碼:

  18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
  INT A,B;
 pa, * pb ; * PA,PB *;

 "Antes de qualquer atribuição: \n " ) ; printf的(“前的任何任務:\”);

 "&a = %p \n " , & a ) ; // Endereço válido dado pelo SO. printf的(“&=%P \ N”,&)/ /所謂的有效地址。
 "&b = %p \n " , & b ) ; // Endereço válido dado pelo SO. printf(“請&B =%P \ N”,及b)/ /所謂的有效地址。
 "&pa = %p \n " , & pa ) ; // Endereço válido dado pelo SO. printf的(“&AP =%P \ N”,&PA)/ /所謂的有效地址。
 "&pb = %p \n " , & pb ) ; // Endereço válido dado pelo SO. 輸出(“&SC =%P \ N”,與BP)/ /所謂的有效地址。

 " \n " ) ; printf的(“\ N”);

 "a = %d \n " , a ) ; // Conteúdo não inicializado (aleatório). printf(“請=%d個\ n”,一個)/ /初始化(隨機)的內容。
 "b = %d \n " , b ) ; // Conteúdo não inicializado (aleatório). 輸出(“B =%d個\ N”,B)/ /內容初始化(隨機)。
 "pa = %p \n " , pa ) ; // Conteúdo não inicializado (aleatório). printf的(“PA =%P \ N”,PA)/ /初始化(隨機)的內容。
 "pb = %p \n " , pb ) ; // Conteúdo não inicializado (aleatório). 輸出(“SC =%P \ N”,BP); / /初始化(隨機)的內容。

 / /嘗試下面的註釋行,重新編譯和運行。
 / /輸出(“* PA =%D \ N”,* PA)/ /是什麼(隨機*)?
 / /輸出(“* BP =%D \ N”,BP)/ /是什麼(隨機*)?

 " \n Após as inicializações dos ponteiros: \n " ) ; printf的(“\ N後指針的初始化:\”);

 a ; PA =&A;
 b ; BP =&B;

 "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. 輸出(“=%P \ N”,&)/ /即使是有效的SO的地址。
 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. printf(“請&B =%P \ N”,及b)/ /即使所謂的有效地址。
 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. 輸出(“&AP =%P \ N”,&PA)/ /即使是有效的SO的地址。
 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. 輸出(“&SC =%P \ N”,與BP)/ /即使是所謂的有效地址。

 " \n " ) ; printf的(“\ N”);

 "a = %d \n " , a ) ; // Conteúdo não inicializado (aleatório). printf(“請=%d個\ n”,一個)/ /初始化(隨機)的內容。
 "b = %d \n " , b ) ; // Conteúdo não inicializado (aleatório). 輸出(“B =%d個\ N”,B)/ /內容初始化(隨機)。
 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). 輸出(“PA =%P \ N”,PA)/ /初始化內容(&A)。
 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). 輸出(“SC =%P \ N”,BP)/ /初始化內容(&B)。

 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa (*pa == a). 輸出(“* PA =%D \ N”,* PA)/ /內容由PA任命的(PA == *)。
 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (*pb == b). 輸出(“* BP =%D \ N”,BP)/ /所指出的BP內容(* BP == B)。

 " \n Após as inicializações dos inteiros: \n " ) ; printf的(“\ N後的整數初始化:\”);

 ; A = 10
 ; B = 13;

 "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. 輸出(“=%P \ N”,&)/ /即使是有效的SO的地址。
 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. printf(“請&B =%P \ N”,及b)/ /即使所謂的有效地址。
 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. 輸出(“&AP =%P \ N”,&PA)/ /即使是有效的SO的地址。
 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. 輸出(“&SC =%P \ N”,與BP)/ /即使是所謂的有效地址。

 " \n " ) ; printf的(“\ N”);

 "a = %d \n " , a ) ; // Conteúdo inicializado (10). printf(“請=%d條\ n”)/ /初始化的內容(10)。
 "b = %d \n " , b ) ; // Conteúdo inicializado (13). 輸出(“B =%d條\ n”,B)/ /初始化內容(13)。
 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). 輸出(“PA =%P \ N”,PA)/ /初始化內容(&A)。
 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). 輸出(“SC =%P \ N”,BP)/ /初始化內容(&B)。

 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa (*pa == a == 10). 輸出(“* PA =%D \ N”,* PA)/ /內容AP指出(* PA ==了== 10)。
 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (*pb == b == 13). 輸出(“* BP =%d條\ n”,* BP)/ /(* BP == B == 13)所指出的BP內容。

 " \n Alterando os valores através dos ponteiros: \n " ) ; printf的(“\ N更改通過指針的值:\”);

 7 ; * PA = 7;
 42 ; * BP = 42;

 "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. 輸出(“=%P \ N”,&)/ /即使是有效的SO的地址。
 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. printf(“請&B =%P \ N”,及b)/ /即使所謂的有效地址。
 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. 輸出(“&AP =%P \ N”,&PA)/ /即使是有效的SO的地址。
 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. 輸出(“&SC =%P \ N”,與BP)/ /即使是所謂的有效地址。

 " \n " ) ; printf的(“\ N”);

 "a = %d \n " , a ) ; // Conteúdo inicializado (a == *pa == 7). printf的(“=%d條\ n”,一)/ /初始化內容(* PA ==了== 7)。
 "b = %d \n " , b ) ; // Conteúdo inicializado (b == *pb == 42). 輸出(“B =%d條\ n”,B)/ /初始化內容(* BP == B == 42)。
 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). 輸出(“PA =%P \ N”,PA)/ /初始化內容(&A)。
 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). 輸出(“SC =%P \ N”,BP)/ /初始化內容(&B)。

 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa ( 7). 輸出(“* PA =%D \ N”,* PA)/ /內容美聯社指出(7)。
 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (42). 輸出(“* BP =%D \ N”,BP)/ /內容指出,BP(42)。 

第18行和19 respectivamnete聲明兩個整數和兩個指針為整數。

行23-26顯示我的變量的地址。 這些地址由操作系統,是固定的,而這些變量的存在。 變量不改變程序執行過程中的地址,但可以改變一個實施。 誰定義是什麼地址是在運行程序的操作系統。 編譯器只知道,需要為每個變量x字節,什麼解釋(型),該計劃將給予這個空間。

第30-33行顯示,尚未初始化這些變量的內容。 這是垃圾,有人(不知道誰)在計算機內存中的這些地方,現在屬於我的變量的最後一個值。

請注意它是安全的註釋行36和37,因為他們試圖訪問指出,PA和PB,尚未初始化的內容。 在這樣的嘗試,程序將嘗試解釋像隨機垃圾的有效地址int變量值。 根據不同的編譯器,操作系統使用,他們的命運可能是無害的,或不。 可以肯定的是,這些行的結果是不可預測和確定問題的根源。

在41和42行的指針初始化整型變量a和b的地址。 從那裡重複打印。

見不改變,這是預料中的地址指針。 什麼是其內容的變化。 PA和PB收到的變量a和b的地址。 需要注意的是手中的內容是準確的變量A和B這是由操作系統在程序的開始地址值。 檢查與以前的版畫。 tr和PB指出內容是A和B,還沒有被初始化,即垃圾的內容相同。 然而,不像前面的步驟,現在指針指向有效地址(地址和b)和a和b的內容是浪費內存,指針指向已分配的變量。

上線的61和62的整數變量的初始化值10:13,版畫又重複了​​一遍。

這時候A和Bcoteúdos不再是垃圾。 正確值。 需要注意的是在解決變量在前面的步驟,只值沒有變化。

看到後,A和B已被初始化,內容指出,PA和PB也自動改變。 出現這種情況正是因為PA和PB點PA和PB的變量使用相同的內存。 這意味著,內容指出指針可以通過改變他指出原始變量的內容進行修改。 最後行81-97表明,逆也山谷,即改變的內容,指出了一個指針,自動修正本身所指出的原始變量的內容。

這是比代碼更容易理解這個葡萄牙短語的思想。

現在...

這是用指針的基本操作。 還有有趣的事情,被視為指向函數的指針,例如,但被認為是一個更高級的話題。 在此之後的一系列計劃,這4個職位,引用,指針和引用終於函數指針的差異和相似之處。

鏈接

評論

  • 在C http://blog.blabos.org/2009/05/ponteiros-e-referencias-em-c-parte-2/指針和引用+ +第2部分:用於Blabos Blebe的博客

    [...]有了這個企圖在一系列有關指針和引用的職位,開始談論今天的三分球將討論[...]

  • http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional Caloni.com.br»博客存檔»最新研究在全國的博客

    [......]和的引用Pointeiros [...]

  • http://blog.blabos.org/2009/05/ponteiros-e-arrays/指針和數組:Blebe博客Blabos

    [...]在這個系列的第一篇文章中,我們談到關於指針一點點。 在第二,我們講的參考。 今天我們討論的指針和[......]之間的親密關係(ui!)

  • 費爾南多

    老兄,你教我如何做張貼您發布的代碼?
    在一個盒子突出,標誌線,突出語言的關鍵字?

  • 費爾南多

    老兄,你教我如何做張貼您發布的代碼?
    在一個盒子突出,標誌線,突出語言的關鍵字?

  • http://blabos.pip.verisignlabs.com/ blabos

    沒問題!

    WordPress有稱為插件WP語法 ,幕後使用稱作GeSHi

    一旦安裝,你可以把你的代碼,預標籤內添加的屬性的“語言”和“行”。 語言是不言自明,有語言列表中的文件和行是初始行。

    的格西也可以使用此功能添加到維基。

    提示:在您複製和粘貼代碼,由4位取代所有的標籤。 這將使獨立的代碼應用到標籤的風格。

    擁抱

  • http://blabos.pip.verisignlabs.com/ blabos

    沒問題!

    WordPress有稱為插件WP語法 ,幕後使用稱作GeSHi

    一旦安裝,你可以把你的代碼,預標籤內添加的屬性的“語言”和“行”。 語言是不言自明,有語言列表中的文件和行是初始行。

    的格西也可以使用此功能添加到維基。

    提示:在您複製和粘貼代碼,由4位取代所有的標籤。 這將使獨立的代碼應用到標籤的風格。

    擁抱

  • 布魯諾http://www.brunodanielmarinho.com

    精細顯示同一篇文章中,我希望,繼續proxximos職位。

  • 布魯諾http://www.brunodanielmarinho.com

    精細顯示同一篇文章中,我希望,繼續proxximos職位。

博客評論由Disqus