程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 指針 && 雙指針,c語言指針

指針 && 雙指針,c語言指針

編輯:C++入門知識

指針 && 雙指針,c語言指針


指針是C語言中的難點,C++中自然也免不了其身影。

以下是我學習中的積累,不足之處望不吝賜教。

指針類型:

指針

 

Const int* pstr     不能修改被指向的對象,可以使指針指向其他對象

  如:const int* pvalue {&value};

  *pvalue=6;     //will not compile

  pvalue=nullptr;  //ok

 

Int* const pstr     不能修改指針中存儲的地址,可修改指向的對象

  如:Int* const pvalue {&value};

  *pvalue=6;     //ok

  pvalue=nullptr;  //will not compile

 

Const int* const Pstr  指針和指向的對象都不能修改

  如:Const int* const pvalue {&value};

  *pvalue=6;     //will not compile

  pvalue=nullptr;  //will not compile

 

指針數組  char* pstr[]

數組指針 char (*pstr)[4]

  double beans[3][4];

  double* pbeans;

  pbeans=&beans[0][0]; //指向數組第一個元素的位置

  pbeans=&beads[0];    //指向數組第一行元素的位置

  double(*pbeans)[4] = beans; //非=&beans,列數要相等

函數指針

double (*pfun) (char*,int)

指針參數:

先看一段雙指針(二級指針)在mian函數裡的地址輸出

 

 1 int main()
 2 {
 3     int v = 9;
 4     int *p1 = &v;
 5     int **p2 = &p1;
 6 
 7     cout << "v=   " << dec << v << endl;
 8     cout << "&v=  " << hex << &v << endl;
 9     cout << "p1=  " << hex << p1 << endl;
10     cout << "&p1= " << hex << &p1 << endl;
11     cout << "&*p1=" << hex << &(*p1) << endl;
12 
13     cout << "p2=  " << hex << p2 << endl;
14     cout << "&p2= " << hex << &p2 << endl;
15     cout << "&(*p2)=" << hex << &(*p2) << endl;
16     
17     cin.get();
18     return 0;
19 }

 

注:從中不難看出指針間的關系,二級指針p2指向p1,物理內存p2所在位置存儲了指針p1的地址,而p1所在物理內存所在位置存儲了變量V的地址。

  當指針同C語言中那樣作為參數傳遞時,可以通過地址來觀察函數調用情況。

 

 

 1 void  SetPoint(int *pu)
 2 {
 3     cout << "pu=  " << hex << pu << endl;
 4     cout << "&pu= " << hex << &pu << endl;
 5     *pu=*pu + 1;
 6 }
 7 int main()
 8 {
 9     int a = 5;
10     int *pt = &a;
11     SetPoint(&a);
12 
13     cout << "&a=  " << hex << &a << endl;
14     cout << "pt=  " << hex << pt << endl;
15     cout << "&pt= " << hex << &pt<<endl;
16     cout << "&*pt=" << hex << &(*pt)<<endl;
17     cout << "a=   " << dec << a<< endl;
18     
19     cin.get();
20     return 0;
21 }

 

注:由上代碼可以看出參數’pu‘的地址不等於變量’a‘的地址,所以‘pu'只是作為中間臨時變量指向了變量’a'。

  而'a'的值卻被改變,則說明編譯器創建了臨時變量對‘a'進行了操作。

 

 

 1 void  SetPoint(int &pu)
 2 {
 3     cout << "pu=  " << hex << pu << endl;
 4     cout << "&pu= " << hex << &pu << endl;
 5     pu=pu + 1;
 6 }
 7 int main()
 8 {
 9     int a = 5;
10     int *pt = &a;
11     SetPoint(a);
12 
13     cout << "&a=  " << hex << &a << endl;
14     cout << "&pt= " << hex << &pt<<endl;
15     cout << "&*pt=" << hex << &(*pt)<<endl;
16     cout << "a=   " << dec << a<< endl;
17     
18     cin.get();
19     return 0;
20 }

 

注:而c++中的引用則是直接對變量’a'進行操作,由上面輸出可以看出,‘pu’的地址等於‘a'的地址。

雙指針:

網上常出現的一道面試題如下

 

void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(char) * num); } int main() { char *str = nullptr; GetMemory(str, 100); strcpy(str, "Hello"); cout << str << endl; return 0; }

 

我試著輸出了str和p的地址,結果於上。可以看出兩個變量的地址並不一樣,因此 p 是作為函數運行中的臨時變量。可知此處與直接傳參數一樣,只會被當做臨時變量處理。

可以將函數中的臨時變量作為返回值傳給 str ,以達到想要的效果。

char * GetMemory(char *p, int num)
{
    p = (char *)malloc(sizeof(char) * num);
    return p;
}
int main()
{
    char *str = nullptr;
    str=GetMemory(str, 100);
    strcpy(str, "Hello");
    cout << str << endl;
    return 0;
}

效率高的還是直接用雙指針(二級指針)

void GetMemory(char **p, int num)
{
    *p = (char *)malloc(sizeof(char) * num);    
}
int main()
{
    char *str = nullptr;
    GetMemory(&str, 100);
    strcpy_s(str,6, "Hello");
    cout << str << endl;

    cin.get();
    return 0;
}

思考輸出的地址, 指針 p [00AFFDDC] 指向了 str [00AFFEB4]的地址。從而以二級指針作為橋梁曲線操作來達到直接為 str 分配空間的目的。

由此,進一步,以後申請動態分配內存,可以考慮使用雙指針。在大的數據面前,復制移動顯然浪費時間,也可以考慮使用。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved