C++——指針學習

之前因爲種種原因一直不願意學指針(當然這是藉口,其實是懶外加笨,無論是看書還是聽課都沒學會,直到上次C++實驗課老師要求必須用指針寫,我(╯‵□′)╯︵┻━┻)。


先從最基本的問題開始,我們每學一個知識,都要知道學這個知識是幹什麼的(無非是提升能力素養或者陶冶情操什麼的),那麼指針有什麼用呢?

按照百度百科的說法:

在計算機科學中,指針(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向(points to)存在電腦存儲器中另一個地方的值。由於通過地址能找到所需的變量單元,可以說,地址指向該變量單元。

我特別能理解第一次接觸這段話,並且還沒有學過或者瞭解數據結構的小白的感受(因爲我就是啊),看到這段話,其實是很懵的,完全不知所云。

好吧,那我們先來初步瞭解一下數據結構是什麼?
首先是來自百度百科的標準定(fei)義(hua):數據結構是計算機存儲、組織數據的方式。

下面是摘自數據在計算機中的存儲的解釋。
數據有數值型非數值兩類,這些數據在計算機中都必須以二進制形式表示一串二進制數既可表示數量值,也可表示一個字符、漢字或其他。一串二進制數代表的數據不同,含義也不同。這些數據在計算機的存儲設備中是如何進行組織存儲的?

  數據單位

  位(bit)

  位(bit),音譯爲"比特",是計算機存儲設備的最小單位,由數字0或1組成。

  字節(Byte)

  字節(Byte),簡寫爲"B",音譯爲"拜特",簡寫爲"B"。8個二進制位編爲一組稱爲一個字節,即:1B=8bit。字節是計算機處理數據的基本單位,即以字節爲單位解釋信息。通常,一個ASCII碼佔1個字節;一個漢字國標碼佔2個字節;整數佔2個字節;實數,即帶有小數點的數,用4個字節組成浮點形式等

  字(word)

  計算機一次存取、處理和傳輸的數據長度稱爲字,即:一組二進制數碼作爲一個整體來參加運算或處理的單位。一個字通常由一個或多個字節構成,用來存放一條指令或一個數據。

  字長

  一個字中所包含的二進制數的位數稱爲字長。不同的計算機,字長是不同的,常用的字長有8位、16位、32位和64位等,也就是經常說的8位機、16位機、32位機或64位機。例如,一臺計算機如果用8個二進制位表示一個字,就說該機是八位機,或者說它的字長是8位的;又如,一個字由兩個字節組成,即16個二進制位,則字長爲16位。字長是衡量計算機性能的一個重要標誌。字長越長,一次處理的數字位數越大,速度也就越快。


  編址與地址

  編址

  對計算機存儲單元編號的過程稱爲"編址",是以字節爲單位進行的。

  地址

  存儲單元的編號稱爲地址。

===》

1.內存中的每個位置都由一個獨一無二的地址表示.
2.內存中的每個位置都包含一個值.
===》
我們可以通過一個地址,來找到內存中的某個具體位置,然後訪問到(得到)該位置的值(允許的話).這就是內存和地址簡單的思想.



其實……

用指針的原因就是因爲……

方便……

當然,在知乎上也有很多解答,感興趣的話可以去看看爲什麼要有指針


書歸正傳,先看一段代碼:

/*指針學習。
之前一直固執的不學指針(其實是被oj嚇的,以前剛剛學數組的時候就見到有報錯,說我是數組越界或者是指針無意義,感到了無限的恐懼--->因此就沒再學指針了)*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int *a;
    int input;
    cin>>input;
    a=&input;
    cout<<a<<endl;
    cout<<*a<<endl;
    cout<<input<<endl;
    return 0;
}

第一行27是輸入,第二行的0x69fef8就是地址,剩下兩行都是數值。


那麼問題來了,a和*a有什麼區別?*a和input又有什麼聯繫呢?


我們先看一下指針是如何聲明的。


注:上面是截圖,大家理解一下懶得打字的我。。。

附原文鏈接C++指針|菜鳥教程

總之,這個意思就是如果直接輸出帶*的那個變量的名字(而不帶*號)得到的是地址,而加上*號得到的就是需要的那個值了,如果直接輸出與&連接的變量名也會直接輸出所需的值。


--------------------------到此就是我每次學習斷開的地方------------------------------------

完全不知道這指針還有什麼用,覺得還不如直接折騰a b來的簡單(似乎,其實,好像……也確實,指針在除了C和C++裏也沒有哪裏用了)。

直到上次C++實驗課圍觀某大神用指針做題,我看的雲裏霧裏,才堅定了我學習的心o(╥﹏╥)o



首先大家體諒一下好奇心旺盛到崩潰的我,忍不住試了一下如果寫int a;不加*會怎麼樣。

結果是報錯:

然後,嘗試一下各種花式類型:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    char *word;
    int *number;
    double *fla;
    string *str;
    char a;
    int b;
    double c;
    string d;
    cin>>a>>b>>c>>d;
    word=&a;
    number=&b;
    fla=&c;
    str=&d;
    cout<<a<<'\t'<<b<<'\t'<<c<<'\t'<<d<<'\n';
    cout<<word<<'\t'<<number<<'\t'<<fla<<'\t'<<str<<'\n';
    cout<<*word<<'\t'<<*number<<'\t'<<*fla<<'\t'<<*str<<'\n';
    return 0;
}


輸入:

輸出:

A 23 2.345 %zuzhang
A 0x7fff355ee59c 0x7fff355ee5a8 0x7fff355ee5a0
A 23 2.345 %zuzhang

接下來是一個作死的嘗試,就是看這個*可以管多遠(什麼叫多遠(╯‵□′)╯︵┻━┻)
然後是試圖上面聲明指針,下面不用……



作死完畢,進入正題(當然大家用的時候不要像上面一樣)

指針和數組

指針和數組是密切相關的。事實上,指針和數組在很多情況下是可以互換的。例如,一個指向數組開頭的指針,可以通過使用指針的算術運算或數組索引來訪問數組。
#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
   int  *ptr;
 
   // 指針中的數組地址
   ptr = var;
   for (int i = 0; i < MAX; i++)
   {
      cout << "var[" << i << "]的內存地址爲 ";
      cout << ptr << endl;
 
      cout << "var[" << i << "] 的值爲 ";
      cout << *ptr << endl;
 
      // 移動到下一個位置
      ptr++;
   }
   return 0;
}

當上面的代碼被編譯和執行時,它會產生下列結果:

var[0]的內存地址爲 0x7fff59707adc
var[0] 的值爲 10
var[1]的內存地址爲 0x7fff59707ae0
var[1] 的值爲 100
var[2]的內存地址爲 0x7fff59707ae4
var[2] 的值爲 200
然而,指針和數組並不是完全互換的。
#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
 
   for (int i = 0; i < MAX; i++)
   {
      *var = i;    // 這是正確的語法
      var++;       // 這是不正確的
   }
   return 0;
}

把指針運算符 * 應用到 var 上是完全可以的,但修改 var 的值是非法的。這是因爲 var 是一個指向數組開頭的常量,不能作爲左值。

由於一個數組名對應一個指針常量,只要不改變數組的值,仍然可以用指針形式的表達式。例如,下面是一個有效的語句,把 var[2] 賦值爲 500:

*(var + 2) = 500;

上面的語句是有效的,且能成功編譯,因爲 var 未改變。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章