欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++中指針的深入理解

 更新時間:2021年07月22日 09:36:53   作者:鬼才fjz  
指針在 C\C++ 語言中是很重要的內(nèi)容,并且和指針有關(guān)的內(nèi)容一向令初學(xué)者頭大,這篇文章主要給大家介紹了關(guān)于C/C++中指針的相關(guān)資料,需要的朋友可以參考下

計(jì)算機(jī)的內(nèi)存模型

CPU是計(jì)算機(jī)的核心部件,要想讓一個CPU工作,就必須向它提供指令和數(shù)據(jù),指令和數(shù)據(jù)在存儲器中存放,也就是我們平時說的內(nèi)存。

內(nèi)存分為:物理內(nèi)存和虛擬內(nèi)存,物理內(nèi)存對應(yīng)著計(jì)算機(jī)中的內(nèi)存條,虛擬內(nèi)存是操作系統(tǒng)內(nèi)存管理系統(tǒng)假想出來的,由于這些不是我們本文的重點(diǎn),我們就不做區(qū)分。

在不考慮cpu緩存的情況下,計(jì)算機(jī)運(yùn)行程序本質(zhì)上是對內(nèi)存中的數(shù)據(jù)的操作,存儲器被劃分為多個存儲單元,存儲單元從零開始順序編號,CPU要從內(nèi)存中讀取數(shù)據(jù),首先要指定存儲單元的地址。

CPU從內(nèi)存中讀取數(shù)據(jù)的過程如圖所示:

計(jì)算機(jī)為了方便管理內(nèi)存,將內(nèi)存的每個單元用一個數(shù)字編號

指針與指針常量

指針的本意就是內(nèi)存地址,我們可以通俗的理解成內(nèi)存編號,既然計(jì)算機(jī)通過編號來操作內(nèi)存單元,這就造成了指針的高效率

指針變量:

  • 通俗理解為存儲指針的變量,也就是存儲內(nèi)存地址(內(nèi)存編號)的變量
  • 指針變量和int,float,char等類型一樣同屬變量類型,指針變量類型占四個字節(jié)(32位機(jī)器下),存儲的是32位的內(nèi)存地址
    星號:
  • 在C\C++中(*)被定義為取內(nèi)容符號
  • 雖然所有指針變量占的內(nèi)存大小和存儲的內(nèi)存地址大小都是一樣的,但是由于存儲的只是數(shù)據(jù)的內(nèi)存首地址,所以指針變量存儲的內(nèi)存地址所指向的數(shù)據(jù)類型決定著如何解析這個首地址
  • 比如int型指針變量,我們需要從該指針變量存儲的首地址開始向后一直搜索4個字節(jié)的內(nèi)存空間
  • 所以當(dāng)我們使用*p,必須知道p是一個什么類型的指針

指針變量和指針常量

指針變量首先是一個變量,由于指針變量存儲了某個變量的內(nèi)存首地址,我們通常認(rèn)為"指針變量指向了該變量",同時指針變量時一個變量,它的值是可以變動的。

相反,指針常量可通俗地理解為存儲固定的內(nèi)存單元地址編號的量,它一旦存儲了某個內(nèi)存地址以后,不可再改存儲其他的內(nèi)存地址了

舉個例子:

void f(const int *x,int *y)
{
	*x=2;//錯誤,由于x前面有個const修飾,所以不可以修改x所指向的內(nèi)存單元的內(nèi)容
	//正確寫法
	*y=3;
}

指針變量和數(shù)組

先看一個例子:

	int a[5]={1,2,3,4,5};
	int *ptr=(int*)(&a+1);
	cout<<*(a+1)<<endl;
	cout<<*(ptr-1)<<endl;

輸出結(jié)果為2和5,首先我們看一下&a+1的含義:

  • 我們知道C\C++中規(guī)定數(shù)組名表示這個數(shù)組的首地址,而這里出現(xiàn)了&a這樣的符號,本來a就是指針常量,再次取地址難道不是非法操作?
  • 這時我們可以將這個&a看成是指向數(shù)組的指針,也稱為行指針,&a的類型是int (*p)[5],一個步長即5個元素的長度,&a + 1代表往后移動一個步長

分析:

  • a表示的是第一個元素的首地址,那么a+1指向的就是下一個元素的內(nèi)存首地址,所以*(a+1)=2
  • 而&a則表示整個數(shù)據(jù)的首地址,那么&a+1移動的內(nèi)存數(shù)目就是整個數(shù)組所占字節(jié)數(shù),假如原先數(shù)組中第一個元素的首地址是0,那么&a+1表示的就是20,而這個地址已經(jīng)不屬于數(shù)組了,接著通過(int*)(&a+1)將數(shù)組指針轉(zhuǎn)換成整型指針,這樣原先&a+1表示的數(shù)據(jù)范圍20-39就縮小為20-23,正好是一個int型的大小,而ptr-1就是16了,表示的數(shù)據(jù)內(nèi)存范圍是16-19,這樣*(ptr-1)正好是最后一個元素5了

上面的例子,只是通過簡單的數(shù)據(jù)類型來說明內(nèi)存分布,但是實(shí)際上一些復(fù)雜的數(shù)據(jù)類型,尤其是一些自定義的類或者結(jié)構(gòu)體類型,內(nèi)存分布還要充分考慮到字節(jié)對齊。

函數(shù)指針

函數(shù)指針是指向函數(shù)的指針變量,C\C++程序在編譯時,每個函數(shù)都有一個入口地址,該入口地址就是函數(shù)指針?biāo)赶虻牡刂?,有了指向函?shù)的指針變量后,可用該指針變量調(diào)用函數(shù),同時也可以做函數(shù)的參數(shù)

我們先看函數(shù)指針調(diào)用函數(shù),如下:

int f(int x, int y) {
	return x + y;
}
//申明一個函數(shù)指針
typedef int (*pf)(int, int);
int main()
{
	int a = 1;
	int b = 2;
	//將函數(shù)f地址賦給函數(shù)指針pf
	pf = f;
	//利用函數(shù)指針調(diào)用函數(shù)
	int c = (*pf)(a, b);
	cout << c << endl;
}

需要注意的是,定義的函數(shù)指針類型時的函數(shù)簽名(包括函數(shù)返回值和函數(shù)參數(shù)列表的類型,個數(shù),順序)要將賦值給該類型變量的函數(shù)簽名保持一致,不然可能會發(fā)生很多無法預(yù)料的情況,還有C\C++規(guī)定函數(shù)名就表示函數(shù)入口地址,所以,函數(shù)名賦值時函數(shù)名前面加不加取地址符&都一樣,但是在C++中取類的方法函數(shù)的地址時,這個&符號不能省略。

函數(shù)指針還有另外一個用處,就是作為一個函數(shù)的參數(shù),在Windows編程中作為回調(diào)函數(shù)很常見:

typedef int (*PF)(int, int);
int f1(int x, int y)
{
	return x + y;
}
int f2(PF pf, int t)
{
	return (*pf)(3, t);
}
int main()
{
	//將函數(shù)f1作為參數(shù)傳遞給函數(shù)f2
	int c = f2(f1, 4);
	cout << c << endl;
	return 0;
}

C++中的引用

所謂引用,使用另外一個變量名來代表某一塊內(nèi)存,這就相當(dāng)于同一個人有不同的名字,但是不管哪個名字,指的都是同一個人。

int a=1;
//通過&符號,將b定義為a的引用
int &b=a;
//b和a完全一樣,等價(jià)于int c=a
int c=b;

注意,C++規(guī)定,定義一個引用的時候,必須馬上初始化

傳值還是傳引用

如果變量類型是基元數(shù)據(jù)類型,比如int,float,bool,char等小數(shù)據(jù)類型被稱為基元數(shù)據(jù)類型,那么賦值時傳的是值,這時候b的值是a的拷貝,那么更改b不會影響到a,但是,如果變量數(shù)據(jù)類型是復(fù)雜數(shù)據(jù)類型,比如數(shù)組,類對象,那么賦值時傳的就是引用,這個時候,a和b指向的都是同一個內(nèi)存區(qū)域,那么無論更改a或者b都會相互影響。

最后,在利用C++中拷貝構(gòu)造函數(shù)復(fù)制對象時需要注意,基元數(shù)據(jù)類型可以直接復(fù)制,但是對于引用類型數(shù)據(jù),我們需要實(shí)現(xiàn)引用類型的真正復(fù)制

C++中的new關(guān)鍵詞

在c++中通過new關(guān)鍵詞定義一個對象,不能直接得到對象的實(shí)例,我們需要用一個指針去接收這個new出來的對象,我們引用這個對象必須使用指針引用運(yùn)算符->

#include <iostream>
using namespace std;
class Person
{
public:
	Person()
	{

	}
	Person(int a, int b)
	{
		this->m_a = a;
		this->m_b = b;
	}
	int m_a;
	int m_b;
};
int main()
{
	//在C++中可以用以下形式來實(shí)例化一個對象,per1和per2為實(shí)例化的person類對象
	Person per1;
	int i = 1;
	int j = 2;
	Person per2(i, j);
}

在C++中,this關(guān)鍵詞是一個指針,而不像在java中是一個類實(shí)例,在C++中*this才等價(jià)于java

class Person
{
public:
	Person(int number)
	{
		//C++中需要使用指針引用符號
		this->m_number = number;
	}
	//返回對象本身,,需要使用引用,因?yàn)榉祷刂禃r會創(chuàng)建一個新的對象,使用引用的方式不會創(chuàng)建新的對象
	Person& getSelf()
	{
		return *this;
	}
	int m_number;
};

總結(jié)

到此這篇關(guān)于C/C++中指針的文章就介紹到這了,更多相關(guān)C/C++指針理解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mac OS上搭建Apache+PHP+MySQL開發(fā)環(huán)境的詳細(xì)教程

    Mac OS上搭建Apache+PHP+MySQL開發(fā)環(huán)境的詳細(xì)教程

    這篇文章主要介紹了Mac OS上搭建Apache+PHP+MySQL開發(fā)環(huán)境的詳細(xì)教程,包括常見的PHP連接MySQL失敗問題的解決辦法,需要的朋友可以參考下
    2016-01-01
  • C語言編寫多功能日歷

    C語言編寫多功能日歷

    之前看到本站給大家分享了一則C語言實(shí)現(xiàn)的簡單日歷,就手癢了,也想自己寫一個,既然有簡單了,那咱寫個稍微復(fù)雜點(diǎn)的,多功能的吧。呵呵,玩笑玩笑
    2015-03-03
  • 如何利用C語言輸出3D立體感心形圖詳解

    如何利用C語言輸出3D立體感心形圖詳解

    其實(shí)我們在程序中也有很多樂趣的,只是很多人不善于發(fā)現(xiàn),這篇文章主要給大家介紹了關(guān)于C語言輸出3D立體感心形圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-12-12
  • C++ Boost Heap使用實(shí)例詳解

    C++ Boost Heap使用實(shí)例詳解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • C++選擇排序算法實(shí)例

    C++選擇排序算法實(shí)例

    這篇文章主要介紹了C++選擇排序算法實(shí)例,本文先是介紹了什么是選擇排序,然后給出了實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2014-10-10
  • C++選擇排序算法實(shí)例詳解

    C++選擇排序算法實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了C++選擇排序算法實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • C++?繼承的范例講解

    C++?繼承的范例講解

    繼承是C++面向?qū)ο缶幊讨械囊婚T。繼承是子類繼承父類的特征和行為,或者是繼承父類得方法,使的子類具有父類得的特性和行為。重寫是子類對父類的允許訪問的方法實(shí)行的過程進(jìn)行重新編寫,返回值和形參都不能改變。就是對原本的父類進(jìn)行重新編寫,但是外部接口不能被重寫
    2022-06-06
  • 詳解c++20協(xié)程如何使用

    詳解c++20協(xié)程如何使用

    這篇文章主要介紹了詳解c++20協(xié)程如何使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C/C++中的static關(guān)鍵字詳解

    C/C++中的static關(guān)鍵字詳解

    這篇文章主要為大家詳細(xì)介紹了 C/C++中的static關(guān)鍵字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++使用redis的實(shí)例詳解

    C++使用redis的實(shí)例詳解

    這篇文章主要介紹了C++使用redis的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10

最新評論