當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式微處理器
[導(dǎo)讀]1為什么使用指針 假如我們定義了 char a=’A’ ,當(dāng)需要使用 ‘A’ 時(shí),除了直接調(diào)用變量 a ,還可以定義 char *p=&a ,調(diào)用 a 的地址,即指向 a 的指針 p ,變量 a( char 類(lèi)型)只占了一個(gè)字節(jié),指針本身的大小由可尋址的字長(zhǎng)來(lái)決定,指針 p 占用 4 個(gè)字節(jié)。


1為什么使用指針

假如我們定義了 char a=’A’ ,當(dāng)需要使用 ‘A’ 時(shí),除了直接調(diào)用變量 a ,還可以定義 char *p=&a ,調(diào)用 a 的地址,即指向 a 的指針 p ,變量 achar 類(lèi)型)只占了一個(gè)字節(jié),指針本身的大小由可尋址的字長(zhǎng)來(lái)決定,指針 p 占用 4 個(gè)字節(jié)。

但如果要引用的是占用內(nèi)存空間比較大東西,用指針也還是 4 個(gè)字節(jié)即可。

  • 使用指針型變量在很多時(shí)候占用更小的內(nèi)存空間。

變量為了表示數(shù)據(jù),指針可以更好的傳遞數(shù)據(jù),舉個(gè)例子:

第一節(jié)課是 1 班語(yǔ)文, 2 班數(shù)學(xué),第二節(jié)課顛倒過(guò)來(lái), 1 班要上數(shù)學(xué), 2 班要上語(yǔ)文,那么第一節(jié)課下課后需要怎樣作調(diào)整呢?方案一:課間 1 班學(xué)生全都去 2 班, 2 班學(xué)生全都來(lái) 1 班,當(dāng)然,走的時(shí)候要攜帶上書(shū)本、筆紙、零食……場(chǎng)面一片狼藉;方案二:兩位老師課間互換教室。

顯然,方案二更好一些,方案二類(lèi)似使用指針傳遞地址,方案一將內(nèi)存中的內(nèi)容重新“復(fù)制”了一份,效率比較低。

  • 在數(shù)據(jù)傳遞時(shí),如果數(shù)據(jù)塊較大,可以使用指針傳遞地址而不是實(shí)際數(shù)據(jù),即提高傳輸速度,又節(jié)省大量?jī)?nèi)存。

一個(gè)數(shù)據(jù)緩沖區(qū) char buf[100] ,如果其中 buf[0,1] 為命令號(hào), buf[2,3] 為數(shù)據(jù)類(lèi)型, buf[4~7] 為該類(lèi)型的數(shù)值,類(lèi)型為 int ,使用如下語(yǔ)句進(jìn)行賦值:

*(short*)&buf[0]=DataId;
*(short*)&buf[2]=DataType;
*(int*)&buf[4]=DataValue;
  • 數(shù)據(jù)轉(zhuǎn)換,利用指針的靈活的類(lèi)型轉(zhuǎn)換,可以用來(lái)做數(shù)據(jù)類(lèi)型轉(zhuǎn)換,比較常用于通訊緩沖區(qū)的填充。

  • 指針的機(jī)制比較簡(jiǎn)單,其功能可以被集中重新實(shí)現(xiàn)成更抽象化的引用數(shù)據(jù)形式

  • 函數(shù)指針,形如: #define PMYFUN (void*)(int,int) ,可以用在大量分支處理的實(shí)例當(dāng)中,如某通訊根據(jù)不同的命令號(hào)執(zhí)行不同類(lèi)型的命令,則可以建立一個(gè)函數(shù)指針數(shù)組,進(jìn)行散轉(zhuǎn)。

  • 在數(shù)據(jù)結(jié)構(gòu)中,鏈表、樹(shù)、圖等大量的應(yīng)用都離不開(kāi)指針。

2 指針是什么?

操作系統(tǒng)將硬件和軟件結(jié)合起來(lái),給程序員提供的一種對(duì)內(nèi)存使用的抽象,這種抽象機(jī)制使得程序使用的是虛擬存儲(chǔ)器,而不是直接操作和使用真實(shí)存在的物理存儲(chǔ)器。所有的虛擬地址形成的集合就是虛擬地址空間。

內(nèi)存是一個(gè)很大的線性的字節(jié)數(shù)組,每個(gè)字節(jié)固定由 8 個(gè)二進(jìn)制位組成,每個(gè)字節(jié)都有唯一的編號(hào),如下圖,這是一個(gè) 4G 的內(nèi)存,他一共有 4x1024x1024x1024 = 4294967296 個(gè)字節(jié),那么它的地址范圍就是 0 ~ 4294967296 ,十六進(jìn)制表示就是 0x00000000~0xffffffff ,當(dāng)程序使用的數(shù)據(jù)載入內(nèi)存時(shí),都有自己唯一的一個(gè)編號(hào),這個(gè)編號(hào)就是這個(gè)數(shù)據(jù)的地址。指針就是這樣形成的。

1
#include <stdio.h>

int main(void)
{
    char ch = 'a';
    int  num = 97;
    printf("ch 的地址:%p\n",&ch);   
    //ch 的地址:00BEFDF7
    printf("num的地址:%p\n",&num);  
    //num的地址:00BEFDF8
    return 0;
}

指針不僅可以表示變量的地址,還可以存儲(chǔ)各種類(lèi)型數(shù)據(jù)的地址,指針變量是用來(lái)保存這些地址的變量,與數(shù)組類(lèi)似,依據(jù)地址存放的數(shù)據(jù)類(lèi)型,指針也分為 int 指針類(lèi)型,  double 指針類(lèi)型, char 指針類(lèi)型等等。

綜上,指針的實(shí)質(zhì)就是數(shù)據(jù)在內(nèi)存中的地址,而指針變量是用來(lái)保存這些地址的變量

指針變量 和 指向關(guān)系

用來(lái)保存 指針 的變量,就是指針變量。如果指針變量p保存了變量 num的地址,則就說(shuō):p指向了變量num,也可以說(shuō)p指向了num所在的內(nèi)存塊,指針變量pp指向了p所在的內(nèi)存塊,以下面為例:

#include <stdio.h>

int main(void)
{
  int num = 97;
  char ch = 'a';

  int *p = & num;
  int **pp = &p;
  char *p1 = & ch;

  printf("num 的地址:%p\n",&num);   
  printf("指針p的值:%p\n",p);   
  printf("指針p的地址:%p\n",&p);  
  printf("指針pp的值:%p\n",pp); 
  printf("ch 的地址:%p\n",&ch);  

  return 0;
}
運(yùn)行結(jié)果
  • int型的num值為97占4個(gè)字節(jié),內(nèi)存地址為: 0113F924char 型的 ch('a')值為97占1個(gè)字節(jié),內(nèi)存地址為: 0113F91B。
int型占4個(gè)字節(jié)

char型占1個(gè)字節(jié)

  • num的地址為: 0113F924, num的值為 97 ,指針 p 指向 num 的內(nèi)存塊,指針 p 地址為: 0113F90C, p的內(nèi)存保存的值就是 num的地址 0113F924
0x0113F90C存儲(chǔ)的內(nèi)容為地址0113F924
  • 指針變量 pp 指向 指針 p,指針 pp 內(nèi)存值為 指針 p 的地址: 0113F90C,形成了只想指針的指針。
指針pp為指向指針p的指針

定義指針變量

C語(yǔ)言中,定義變量時(shí),在變量名 前 寫(xiě)一個(gè) * 星號(hào),這個(gè)變量就變成了對(duì)應(yīng)變量類(lèi)型的指針變量。必要時(shí)要加( ) 來(lái)避免優(yōu)先級(jí)的問(wèn)題。

引申:C語(yǔ)言中,定義變量時(shí),在定義的最前面寫(xiě)上typedef ,那么這個(gè)變量名就成了一種類(lèi)型,即這個(gè)類(lèi)型的同義詞。

int a ; //int類(lèi)型變量 a
int *a ; //int* 變量a
int arr[3]; //arr是包含3個(gè)int元素的數(shù)組
int (* arr )[3]; //arr是一個(gè)指向包含3個(gè)int元素的數(shù)組的指針變量

int* p_int; //指向int類(lèi)型變量的指針 
double* p_double; //指向idouble類(lèi)型變量的指針 
struct Student *p_struct; //結(jié)構(gòu)體類(lèi)型的指針
int(*p_func)(int,int); //指向返回類(lèi)型為int,有2個(gè)int形參的函數(shù)的指針 
int(*p_arr)[3]; //指向含有3個(gè)int元素的數(shù)組的指針 
int** p_pointer; //指向 一個(gè)整形變量指針的指針

取地址

既然有了指針變量,那就得讓他保存其它變量的地址,使用& 運(yùn)算符取得一個(gè)變量的地址。

int add(int a , int b)
{
    return a + b;
}

int main(void)
{
    int num = 97;
    float score = 10.00F;
    int arr[3] = {1,2,3};

    int* p_num = &num;
    float* p_score = &score;
    int (*p_arr)[3] = &arr;           
    int (*fp_add)(int ,int )  = add;  //p_add是指向函數(shù)add的函數(shù)指針
    return 0;
}

特殊的情況,他們并不一定需要使用&取地址

  • 數(shù)組名的值就是這個(gè)數(shù)組的第一個(gè)元素的地址。
  • 函數(shù)名的值就是這個(gè)函數(shù)的地址。
  • 字符串字面值常量作為右值時(shí),就是這個(gè)字符串對(duì)應(yīng)的字符數(shù)組的名稱(chēng),也就是這個(gè)字符串在內(nèi)存中的地址。
int add(int a , int b){
    return a + b;
}
int main(void)
{
    int arr[3] = {1,2,3};
    int* p_first = arr;
    int (*fp_add)(int ,int )  =  add;
    const char* msg = "Hello world";
    return 0;
}

解地址

對(duì)一個(gè)指針解地址,就可以取到這個(gè)內(nèi)存數(shù)據(jù),解地址 的寫(xiě)法,就是在指針的前面加一個(gè) * 號(hào)。

解指針的實(shí)質(zhì)是:從指針指向的內(nèi)存塊中取出這個(gè)內(nèi)存數(shù)據(jù)。

int main(void)
{
    int age = 19;
    int*p_age = &age;
    *p_age  = 20;  //通過(guò)指針修改指向的內(nèi)存數(shù)據(jù)

    printf("age = %d",*p_age);   //通過(guò)指針讀取指向的內(nèi)存數(shù)據(jù)
    printf("age = %d",age);

    return 0;
}

空指針

空指針在概念上不同于未初始化的指針。空指針可以確保不指向任何對(duì)象或函數(shù);而未初始化的指針則可能指向任何地方??罩羔槻皇且爸羔?。

在C語(yǔ)言中,我們讓指針變量賦值為NULL表示一個(gè)空指針,而C語(yǔ)言中,NULL實(shí)質(zhì)是 ((void*)0) ,  在C++中,NULL實(shí)質(zhì)是0。

#ifdef __cplusplus
     #define NULL    0
#else    
     #define NULL    ((void *)0)
#endif

void*類(lèi)型指針

void是一種特殊的指針類(lèi)型,可以用來(lái)存放任意對(duì)象的地址。一個(gè)void指針存放著一個(gè)地址,這一點(diǎn)和其他指針類(lèi)似。不同的是,我們對(duì)它到底儲(chǔ)存的是什么對(duì)象的地址并不了解。

double a=2.3;
int b=5;
void *p=&a;
cout<<p<<endl;   //輸出了a的地址

p=&b;
cout<<p<<endl;   //輸出了b的地址

//cout<<*p<<endl;這一行不可以執(zhí)行,void*指針只可以?xún)?chǔ)存變量地址,不可以直接操作它指向的對(duì)象

由于void是空類(lèi)型,只保存了指針的值,而丟失了類(lèi)型信息,我們不知道他指向的數(shù)據(jù)是什么類(lèi)型的,只指定這個(gè)數(shù)據(jù)在內(nèi)存中的起始地址,如果想要完整的提取指向的數(shù)據(jù),程序員就必須對(duì)這個(gè)指針做出正確的類(lèi)型轉(zhuǎn)換,然后再解指針。

數(shù)組和指針

  • 同類(lèi)型指針變量可以相互賦值,數(shù)組不行,只能一個(gè)一個(gè)元素的賦值或拷貝
  • 數(shù)組在內(nèi)存中是連續(xù)存放的,開(kāi)辟一塊連續(xù)的內(nèi)存空間。數(shù)組是根據(jù)數(shù)組的下進(jìn)行訪問(wèn)的。指針很靈活,它可以指向任意類(lèi)型的數(shù)據(jù)。指針的類(lèi)型說(shuō)明了它所指向地址空間的內(nèi)存。
  • 數(shù)組所占存儲(chǔ)空間的內(nèi)存: sizeof(數(shù)組名) 數(shù)組的大?。? sizeof(數(shù)組名)/sizeof(數(shù)據(jù)類(lèi)型),在32位平臺(tái)下,無(wú)論指針的類(lèi)型是什么, sizeof(指針名)都是 4 ,在 64 位平臺(tái)下,無(wú)論指針的類(lèi)型是什么, sizeof(指針名)都是 8 。
  • 數(shù)組名作為右值的時(shí)候,就是第一個(gè)元素的地址
int main(void)
{
    int arr[5] = {1,2,3,4,5};

    int *p_first = arr;
    printf("%d",*p_first);  //1
    return 0;
}
  • 指向數(shù)組元素的指針 支持 遞增 遞減 運(yùn)算。 p= p+1意思是,讓 p指向原來(lái)指向的內(nèi)存塊的下一個(gè)相鄰的相同類(lèi)型的內(nèi)存塊。在數(shù)組中相鄰內(nèi)存就是相鄰下標(biāo)元素。

函數(shù)與指針

函數(shù)的參數(shù)和指針

C語(yǔ)言中,實(shí)參傳遞給形參,是按值傳遞的,也就是說(shuō),函數(shù)中的形參是實(shí)參的拷貝份,形參和實(shí)參只是在值上面一樣,而不是同一個(gè)內(nèi)存數(shù)據(jù)對(duì)象。這就意味著:這種數(shù)據(jù)傳遞是單向的,即從調(diào)用者傳遞給被調(diào)函數(shù),而被調(diào)函數(shù)無(wú)法修改傳遞的參數(shù)達(dá)到回傳的效果。

void change(int a)
{
    a++;      //在函數(shù)中改變的只是這個(gè)函數(shù)的局部變量a,而隨著函數(shù)執(zhí)行結(jié)束,a被銷(xiāo)毀。age還是原來(lái)的age,紋絲不動(dòng)。
}
int main(void)
{
    int age = 60;
    change(age);
    printf("age = %d",age);   // age = 60
    return 0;
}

有時(shí)候我們可以使用函數(shù)的返回值來(lái)回傳數(shù)據(jù),在簡(jiǎn)單的情況下是可以的,但是如果返回值有其它用途(例如返回函數(shù)的執(zhí)行狀態(tài)量),或者要回傳的數(shù)據(jù)不止一個(gè),返回值就解決不了了。

傳遞變量的指針可以輕松解決上述問(wèn)題。

void change(int* pa)
{
    (*pa)++;   //因?yàn)閭鬟f的是age的地址,因此pa指向內(nèi)存數(shù)據(jù)age。當(dāng)在函數(shù)中對(duì)指針pa解地址時(shí),
               //會(huì)直接去內(nèi)存中找到age這個(gè)數(shù)據(jù),然后把它增1。
}
int main(void)
{
    int age = 160;
    change(&age);
    printf("age = %d",age);   // age = 61
    return 0;
}

比如指針的一個(gè)常見(jiàn)的使用例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void swap(int *,int *);
int main()
{
    int a=5,b=10;
    printf("a=%d,b=%d\n",a,b);
    swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);
    return 0;
}
void swap(int *pa,int *pb)
{
    int t=*pa;*pa=*pb;*pb=t;
}

在以上的例子中,swap函數(shù)的兩個(gè)形參pa和pb可以接收兩個(gè)整型變量的地址,并通過(guò)間接訪問(wèn)的方式修改了它指向變量的值。在main函數(shù)中調(diào)用swap時(shí),提供的實(shí)參分別為&a,&b,這樣就實(shí)現(xiàn)了pa=&a,pb=&b的賦值過(guò)程,這樣在swap函數(shù)中就通過(guò)*pa修改了 a 的值,通過(guò)*pb修改了 b 的值。因此,如果需要在被調(diào)函數(shù)中修改主調(diào)函數(shù)中變量的值,就需要經(jīng)過(guò)以下幾個(gè)步驟:

  • 定義函數(shù)的形參必須為指針類(lèi)型,以接收主調(diào)函數(shù)中傳來(lái)的變量的地址;
  • 調(diào)用函數(shù)時(shí)實(shí)參為變量的地址;
  • 在被調(diào)函數(shù)中使用*間接訪問(wèn)形參指向的內(nèi)存空間,實(shí)現(xiàn)修改主調(diào)函數(shù)中變量值的功能。

指針作為函數(shù)的形參的另一個(gè)典型應(yīng)用是當(dāng)函數(shù)有多個(gè)返回值的情形。比如,需要在一個(gè)函數(shù)中統(tǒng)計(jì)一個(gè)數(shù)組的最大值、最小值和平均值。當(dāng)然你可以編寫(xiě)三個(gè)函數(shù)分別完成統(tǒng)計(jì)三個(gè)值的功能。但比較啰嗦,如:

int GetMax(int a[],int n)
{
    int max=a[0],i;
    for(i=1;i<n;i++)
    {
        if(max<a[i]) max=a[i];
    }
    return max;
}
int GetMin(int a[],int n)
{
    int min=a[0],i;
    for(i=1;i<n;i++)
    {
        if(min>a[i]) min=a[i];
    }
    return min;
}
double GetAvg(int a[],int n)
{
    double avg=0;
    int i;
    for(i=0;i<n;i++)
    {
        avg+=a[i];
    }
    return avg/n;
}

其實(shí)我們完全可以在一個(gè)函數(shù)中完成這個(gè)功能,由于函數(shù)只能有一個(gè)返回值,可以返回平均值,最大值和最小值可以通過(guò)指針類(lèi)型的形參來(lái)進(jìn)行實(shí)現(xiàn):

double Stat(int a[],int n,int *pmax,int *pmin)
{
    double avg=a[0];
    int i;
    *pmax=*pmin=a[0];
    for(i=1;i<n;i++)
    {
        avg+=a[i];
        if(*pmax<a[i]) *pmax=a[i];
        if(*pmin>a[i]) *pmin=a[i];
    }
    return avg/n;
}

函數(shù)的指針

一個(gè)函數(shù)總是占用一段連續(xù)的內(nèi)存區(qū)域,函數(shù)名在表達(dá)式中有時(shí)也會(huì)被轉(zhuǎn)換為該函數(shù)所在內(nèi)存區(qū)域的首地址。我們可以把函數(shù)的這個(gè)首地址賦予一個(gè)指針變量,使指針變量指向函數(shù)所在的內(nèi)存區(qū)域,然后通過(guò)指針變量就可以找到并調(diào)用該函數(shù)。這種指針就是函數(shù)指針。

函數(shù)指針的定義形式為:

returnType (*pointerName)(param list);

returnType 為函數(shù)返回值類(lèi)型,pointerNmae 為指針名稱(chēng),param list 為函數(shù)參數(shù)列表。參數(shù)列表中可以同時(shí)給出參數(shù)的類(lèi)型和名稱(chēng),也可以只給出參數(shù)的類(lèi)型,省略參數(shù)的名稱(chēng),這一點(diǎn)和函數(shù)原型非常類(lèi)似。

用指針來(lái)實(shí)現(xiàn)對(duì)函數(shù)的調(diào)用:

#include <stdio.h>
//返回兩個(gè)數(shù)中較大的一個(gè)
int max(int a, int b)
{
    return a>b ? a : b;
}
int main()
{
    int x, y, maxval;
    //定義函數(shù)指針
    int (*pmax)(int, int) = max;  //也可以寫(xiě)作int (*pmax)(int a, int b)
    printf("Input two numbers:");
    scanf("%d %d", &x, &y);
    maxval = (*pmax)(x, y);
    printf("Max value: %d\n", maxval);
    return 0;
}

結(jié)構(gòu)體和指針

結(jié)構(gòu)體指針有特殊的語(yǔ)法: -> 符號(hào)

如果p是一個(gè)結(jié)構(gòu)體指針,則可以使用 p ->【成員】 的方法訪問(wèn)結(jié)構(gòu)體的成員

typedef struct
{
    char name[31];
    int age;
    float score;
}Student;

int main(void)
{
    Student stu = {"Bob" , 19, 98.0};
    Student*ps = &stu;

    ps->age = 20;
    ps->score = 99.0;
    printf("name:%s age:%d
"
,ps->name,ps->age);
    return 0;
}

const 和 指針

  • 指向常量的指針,值不能改變,指向可改變
  • 常指針值能改變,指向不可改變
  • 指向常量的常指針,都不能改變
#include <stdio.h>
 
int main()
{
  // 1 可改變指針
  const int a = 10;
  int *p = &a;
  *p = 1000;
  printf("*p = %d\n", *p);
 
  // 2 可改變指針
  const b = 10;
  int *pb = &b;
  pb = p;
  printf("*pb = %d\n", *pb);
 
  // 3
  const c = 10;
  int * const pc = &c;
  *pc = 1000;
  //pc = pb;不能改變
 
  //4
  const d = 10;
  const * int const pd = &d;
  //*pd = 1000; 不能改變
 
 
  printf("\n");
  return 0;
}

深拷貝和淺拷貝

如果2個(gè)程序單元(例如2個(gè)函數(shù))是通過(guò)拷貝 他們所共享的數(shù)據(jù)的 指針來(lái)工作的,這就是淺拷貝,因?yàn)檎嬲L問(wèn)的數(shù)據(jù)并沒(méi)有被拷貝。如果被訪問(wèn)的數(shù)據(jù)被拷貝了,在每個(gè)單元中都有自己的一份,對(duì)目標(biāo)數(shù)據(jù)的操作相互 不受影響,則叫做深拷貝。


#include <iostream>
using namespace std;

class CopyDemo
{
public:
  CopyDemo(int pa,char *cstr)  //構(gòu)造函數(shù),兩個(gè)參數(shù)
  {
     this->a = pa;
     this->str = new char[1024]; //指針數(shù)組,動(dòng)態(tài)的用new在堆上分配存儲(chǔ)空間
     strcpy(this->str,cstr);    //拷貝過(guò)來(lái)
  }

//沒(méi)寫(xiě),C++會(huì)自動(dòng)幫忙寫(xiě)一個(gè)復(fù)制構(gòu)造函數(shù),淺拷貝只復(fù)制指針,如下注釋部分
  //CopyDemo(CopyDemo& obj)  
  //{
  //   this->a = obj.a;
  //  this->str = obj.str; //這里是淺復(fù)制會(huì)出問(wèn)題,要深復(fù)制
  //}

  CopyDemo(CopyDemo& obj)  //一般數(shù)據(jù)成員有指針要自己寫(xiě)復(fù)制構(gòu)造函數(shù),如下
  {
     this->a = obj.a;
    // this->str = obj.str; //這里是淺復(fù)制會(huì)出問(wèn)題,要深復(fù)制
     this->str = new char[1024];//應(yīng)該這樣寫(xiě)
     if(str != 0)
        strcpy(this->str,obj.str); //如果成功,把內(nèi)容復(fù)制過(guò)來(lái)
  }

  ~CopyDemo()  //析構(gòu)函數(shù)
  {
     delete str;
  }

public:
     int a;  //定義一個(gè)整型的數(shù)據(jù)成員
     char *str; //字符串指針
};

int main()
{
  CopyDemo A(100,"hello!!!");

  CopyDemo B = A;  //復(fù)制構(gòu)造函數(shù),把A的10和hello!!!復(fù)制給B
  cout <<"A:"<< A.a << "," <<A.str << endl;
  //輸出A:100,hello!!!
  cout <<"B:"<< B.a << "," <<B.str << endl;
  //輸出B:100,hello!!!

  //修改后,發(fā)現(xiàn)A,B都被改變,原因就是淺復(fù)制,A,B指針指向同一地方,修改后都改變
  B.a = 80;
  B.str[0] = 'k';

  cout <<"A:"<< A.a << "," <<A.str << endl;
  //輸出A:100,kello!!!
  cout <<"B:"<< B.a << "," <<B.str << endl;
  //輸出B:80,kello!!!

  return 0;
}

根據(jù)上面實(shí)例可以看到,淺復(fù)制僅復(fù)制對(duì)象本身(其中包括是指針的成員),這樣不同被復(fù)制對(duì)象的成員中的對(duì)應(yīng)非空指針會(huì)指向同一對(duì)象,被成員指針引用的對(duì)象成為共享的,無(wú)法直接通過(guò)指針成員安全地刪除(因?yàn)槿糁苯觿h除,另外對(duì)象中的指針就會(huì)無(wú)效,形成所謂的野指針,而訪問(wèn)無(wú)效指針是危險(xiǎn)的;

除非這些指針有引用計(jì)數(shù)或者其它手段確保被指對(duì)象的所有權(quán));而深復(fù)制在淺復(fù)制的基礎(chǔ)上,連同指針指向的對(duì)象也一起復(fù)制,代價(jià)比較高,但是相對(duì)容易管理。

參考資料

  1.    C Primer Plus(第五版)中文版
  2. https://www.cnblogs.com/lulipro/p/7460206.html

本文授權(quán)轉(zhuǎn)載自公眾號(hào)“C語(yǔ)言與CPP編程” ,作者自成一派123

-END-



推薦閱讀



【01】為什么要使用二級(jí)指針?
【02】指針和引用有什么區(qū)別?分別什么時(shí)候引用?
【03】“懸空指針”和“野指針”究竟是什么意思?標(biāo)準(zhǔn)答案來(lái)了
【04】用指針實(shí)現(xiàn)高低位倒序,瘋了吧?
【05】再談指針:大佬給你撥開(kāi) C指針 的云霧


免責(zé)聲明:整理文章為傳播相關(guān)技術(shù),版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉