天天看點

C++指針的深度了解

前言

筆者會從各種的例子和面試題入手,将逐漸去分析指針的知識點和指針的一些進階的用法。

1.介紹指針的基本知識點

C++指針的深度了解

第一個例子,也許一些人會疑惑為什麼t是512了,先看下面的圖 

C++指針的深度了解

從筆者自己畫的圖分析,引用(&)這個符号傳回的是這個類型最低位的位址而不是最高位數的位址,還有就是int型指針和char型的指針的差別到底在哪裡?不同類型的指針唯一差別就是偏移量的不同,它們存的都是位址,但是char型指針偏移量是1個位元組,而int型指針的偏移量是4個位元組(void *的指針是隻有位址 沒有偏移量),是以pChar+1就可以指向int型資料内部的第二個位元組位置的位址,這個通路看出上去非法的,但是确實可行,是以t就是2的9次方得到512也不奇怪。這樣的指針可以說破壞了int型的結構,可以看出指針的靈活,如果沒有通路權限的問題,指針可以随意修改任何程式的數值,指針也可以直接賦給它一個位址,如下面的圖

C++指針的深度了解

可以看出指針非常強大,但是因為系統有通路權限的設定,就算知道另外一個程式的數值的位址也難以修改,當然可以通過Dll注入去修改其他程式的數值(這種方法筆者有時間會去詳細的介紹的),接下讓我們去看一下關于指針的一些簡單的面試題。

C++指針的深度了解

第一個ptr指針指向是a往後偏移1個位元組的位址,然後将其強制轉換成int *,讓這個指針的偏移量是4個位元組。

第二個ptr指針指向是a往後偏移4個位元組的位址,因為先将(&a)轉換成int型指針了,是以之後的加1就是4個位元組的偏移量(sizeof(int))。

第三個ptr指針直接指向一個(int)a+1的位址,筆者也不知道到底指向那裡了,這個和上述直接指派一個位址一樣的效果。

2.介紹指針和數組的關系

一維數組名其實和指針常量基本沒有差别,唯一的差別就是指針常量自身占據棧上的記憶體空間指向數組的首位址,而一位數組名本身的位址就是這個數組的首位址(變量的别名和指針也有這個差別),并且它們的指向位址都不能改變,如下圖所示。

C++指針的深度了解

n級指針可以表示n維數組,筆者接下來會用二級指針去表示二維數組,表達一下二級指針的基礎知識點,希望一些不太了解指針的人可以舉一反三,去深入了解各種的n級指針,如圖所示。

C++指針的深度了解

從圖中可以知道二級指針向堆申請的空間不是連續的,二級指針p的偏移量是sizeof(int)*n(也就是一行為偏移量),一級指針*p的偏移量是sizeof(int),二級指針第一次解引用就會成為一級指針,一級指針解引用就是這個位址存的值,既然談到了二級指針,接下來談一下int *p[n]和int (*p)[n]的差別,int *p[n]是數組指針,也就是說p[0],p[1]..都是一個指針,而int (*p)[n]是一級行指針,偏移量是sizeof(int)*n,這種指針隻能通路二維數組的行的首位址,裡面的具體機關無法通路,以此類推我們可以知道三級指針的偏移量是整個二維數組。

3.函數指針

接下來筆者用指針去寫一個轉移表,讓讀者們知道指針不僅可以指向任何資料類型也可以指向函數的首位址,下面就是轉移表代碼。

#include<iostream>
using namespace std;
double add(double ,double );
double sub(double ,double );
double mul(double ,double );
double div(double ,double );
int main(void)
{
    double f=0;
    double (*work[4])(double ,double)={add,sub,mul,div};
    f=work[0](2.3,3.1);
    cout<<f<<endl;
    return 0;
}
double add(double a,double b)
{
    return a+b;
}
double sub(double a,double b)
{
    return a-b;
}
double mul(double a,double b)
{
    return a*b;
}
double div(double a,double b)
{
    return a/b;
}
           

紅色代碼的部分就是數組函數指針,回調函數就是将一個函數指針作為參數傳遞給另外一個函數去調用,了解C#語言的,應該知道C#的委托和函數指針本質基本是一樣的,指針大緻的用法就這麼多了,希望大家看了這篇文章對指針的了解有所提升,溫馨提示對指針還不太掌握的,盡量使用指針常量(雖然這麼做失去了靈活性),用指針加某一個機關移動指向的位置(p+n),而不是指針自增去移動(p+=n),因為自增去移動的時候最後到底指向那裡了,有可能都是未知的。如果那裡有錯,歡迎大牛改正。

繼續閱讀