- N +

c語言指針經典例題,#p在c語言中是什么意思

本篇文章給大家談談c語言指針經典例題,以及*p在c語言中是什么意思對應的知識點,文章可能有點長,但是希望大家可以閱讀完,增長自己的知識,最重要的是希望對各位有所幫助,可以解決了您的問題,不要忘了收藏本站喔。

C語言中的指針該怎么理解書上太難懂了,你能畫圖舉例說下基本的指針操作嗎

謝謝邀請。

“指針是C語言的靈魂,指針可以直接操作內存,指針使C語言程序更加高效”,等等等等。相信C語言初學者學到指針時,會看到很多這樣描述指針的話,但是卻往往一頭霧水。

其實C語言的指針并沒有什么難的,將其看做是一種類似于char、int的基本數據類型就簡單了。

我在上個問答中提到C語言中的不同的基礎數據類型主要區(qū)別之一就是占用的存儲空間不同,程序是運行在計算機的內存中的,因此C語言程序的變量也是存在于內存中的。

C語言標準規(guī)定char類型占用一個字節(jié)的存儲空間,對其他整型卻沒有做規(guī)定,現在為了解釋的方便,我們假設int類型的數據占用內存4個字節(jié)。

假設我們如下定義了兩個變量:

那么,i占用了1字節(jié)的內存空間,j占用了4字節(jié)的內存空間,請看下圖。

方框表示內存空間,內部表示存儲的值。我們把內存逐字節(jié)編號,方框外部的數字表示方框的編號(這樣的內存“編號”即所謂的“內存地址”)。

修改變量i的值,實際上就是修改地址為4000的內存空間里的值。那反過來呢?如果我修改了地址為4000的內存空間里的值,i的值會相應改變嗎?答案是肯定的,請繼續(xù)往下看。

上圖中的內存地址“4000”是我為了解釋方便隨意取的。那么,在實際應用中,變量i的地址如何獲取呢?C語言提供了“&”運算符,就是獲取變量地址的。請看下面的例子:

我們取出了i的地址,把它強制轉換為long型,傳遞給p1了。編譯并執(zhí)行這段C語言代碼,得到如下輸出:

發(fā)現變量i的地址被打印出來了,這說明,C語言程序變量的地址也是一個整數。

按照上面的說法,修改i的值除了直接對i賦值以外,還可以通過修改p1地址處的內存空間里的數值。那,怎樣才能“通過修改p1地址處的內存空間里的數值”修改i的值呢?

上面的代碼實例中使用了long型變量p1存儲了i的地址。事實上,C語言有專門的數據類型存儲地址(即所謂的指針),定義方式也很簡單,就是:“類型描述符*”,例如,可以定義以下變量存儲地址:

p1和p2就是C語言中所謂的指針類型,因為i是signedchar類型的,所以定義了signedchar*類型的指針存儲i的地址。j是int類型的,所以定義了int*類型的指針存儲j的地址。

另外,C語言提供了“&”運算符取變量地址,與之對應的,還提供了“*”運算符從相應地址內存里取出數值。

了解了C語言的指針類型和“*”運算符,現在來看看如何“通過修改p1地址處的內存空間里的數值”修改i的值。請看如下C語言代碼:

編譯并執(zhí)行,得到如下輸出:

編譯運行,發(fā)現程序輸出“i=5”,這一值實際上就是通過指針修改的。可以看出,C語言中的指針并沒有什么難的。

在定義變量時,”*“放在變量符號前,可以定義指針變量。在定義完指針變量后,“*”放在變量前,就表示從地址取值的運算符了。另外,“*”還可以表示乘法運算符,讀者自己思考什么情況下,“*”表示乘法運算符。

可以看出C語言中的指針一點也不神秘。題主可以點我主頁,查看我之前的文章,了解更多指針問題:比如為什么int類型的變量j的地址要使用int*p2;定義,而不能使用signedchar*p2;定義,使用指針為何能寫出緊湊、高效的C語言程序等等。

歡迎在評論區(qū)一起討論,質疑。文章都是手打原創(chuàng),每天最淺顯的介紹C語言、linux等嵌入式開發(fā),喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦

為什么說指針是C語言的精髓

指針也是變量的一種稱為指針變量,不過它存的是地址。就類似于酒店里的門房號,每個門房號就一個指針(地址),不同類型指針指向存儲不同類型的地址就想酒店里不同的房間如標間,三人間,情侶間,總統(tǒng)套間等。

所以通過指針我們可以很容易的找到數據的存儲位置,并對其進行操作。C語言指針的使用是非常的靈活的。在實際操作中使用指針可以提高程序的運行效率,使程序更加的結構更加的緊湊,合理,并且數組等占用的內存小。雖然使用指針有很多優(yōu)點,但在使用中一定要謹慎小心,防止指針亂直,申請內存后使用完要及時的釋放。避免程序發(fā)生崩潰。

C語言指針怎樣快速掌握指針用處大嗎

C語言指針就是這門語言的靈魂,說難學,那肯定是有難度的,畢竟這是業(yè)界公認的。但是如果你熟練掌握了指針的話,它又將會成為你手中的一柄利器。下面就詳細的分享一下指針該如何深入的去理解它以及如何熟練的應用它

理解指針

首先,你需要掌握兩個運算符“*”和“&”;

“&”運算符:取對象在內存中的地址

“*”運算符:取內存中地址上的對象(值);

大家一定要深刻的理解上面兩個運算符,然后才能去進一步理解指針;

inta=100;這一行代碼我想大家都沒問題。那么“&a”返回的就是對象(變量)a在內存中的地址,它是一個16進制數。

然后用“*”號去a的地址去取對象:“*(&a)”,,就能取到對象a,也就就是100;

接下來進入重點了,指針,本身也是一個變量(對象),它本身占用內存,但是它只存地址(別人的地址),它存的誰的地址我們就稱它為指向誰的指針;

int*p=&a;int*p_2=newint(200);先不管他的類型申明,只看變量本身p和p_2。前面講到指針存放的是對象的地址,那么可以理解為指針是一個地址變量,那么賦值的話就需要也賦一個地址給它一個地址。int*和char*都可以表示地址類型,它們的區(qū)別就是地址所存的值得類型不同,一個是存整型,一個是存字符型;

對指針取值的話,就是用“*”號,后面接對象地址,也就是指針變量,所以*p和*p_2就分別是a和200;

指針的運用

指針并不是C/C++獨有的,像C#和java等其實也是有指針的,只不過都被語言本身用其他的方式替代和封裝了一般程序員接觸不到,C/C++就不一樣,它是直接將指針暴露給開發(fā)者,因為大部分牽涉到指針的都與內存有關,而計算機內存很重要,萬一出什么問題可能系統(tǒng)都會崩潰,下面就簡單來看一下程序在運行時指針與內存之間到底是個什么樣的關系:

先看一段代碼:

#include<stdio.h>

#include<string>

#include<iostream>

#include<time.h>

usingnamespacestd;

classpeople

{

public:

people();

~people();

stringName;

intage;

boolsex;

charinfo[1024];

voidrun(){}

voideat(){}

private:

};

people::people()

{

}

people::~people()

{

}

intmain()

{

people*p1=newpeople();

cout<<p1<<endl;

cout<<&p1<<endl;

cout<<sizeof(p1)<<endl;

cout<<sizeof(*p1)<<endl;

system("pause");

return0;

}

直接運行看結果:

分析

接下來來一一進行分析:

首先people*p1=newpeople();這一句是類的一個實例化,系統(tǒng)會給people實例化一個對象*p并且給它在堆上開辟空間,注意是在堆上,開辟的空間用來存儲對象的數據。數據包括哪些?就是對象的屬性和虛函數指針,但是函數并不存儲在各對象中。因此run()和eat()方法是不存在對象*p指向的內存處的。

cout<<p1<<endl;輸出的是00279360,這是一個地址,是系統(tǒng)給newpeople()對象分配的地址。

cout<<&p1<<endl;輸出的是0012FD90,這也是地址,但這是指針變量p本身的地址。

cout<<sizeof(p1)<<endl;

cout<<sizeof(*p1)<<endl;

通過這兩個輸出就能有更清晰的認識了,p1本身只占用4個字節(jié)的空間,而它所指向的對象的地址所占的空間就很大,等于類中所有數據類型所占空間之和。

接下來在main函數里寫一點邏輯:

圖解

我們來看一下程序運行時間,指針和內存是怎么工作的。這里畫一個圖給大家:

程序在運行時,數據主要是存儲在棧、堆、代碼區(qū)、全局區(qū)。代碼區(qū)主要就是存代碼中出現的一些字符常量、方法等,比如這里代碼中給對象的Name屬性賦的值“xiaoli”之類的都是存在此處,然后我們通過new出來的對象,都是由堆通過計算好類中各屬性所需空間然后開辟出來的。這里p3不是通過new開辟出來的,所以他是存在棧上的并且地址是固定的,是不能更改的,而p1和p2是能更改的。

改變地址

如此,我們三個對象互相賦值后會發(fā)生什么呢?

對比代碼和輸出結果我們發(fā)現了什么?賦值后p1和p2本身的地址并無改變,但是他所指向的內存都編程p3所在的內存了。下面用圖解給大家看一下:

注意,此處原來的p1和p2指向的內存由于是new出來的我們需要手動釋放它。所以我們在重新賦值之前要將這兩塊內存刪除掉deletep2;deletep1;

改變地址的值

如果我將代碼中的p2=&p3;換成*p2=p3呢?我們看下輸出結果:

造成這種情況的原因,其實這就牽涉到指針的兩種賦值問題:一種是改變指向的地址,一種是改變本身指向地址的值p2=&p3是改變指向地址,*p2=p3是改變指向地址的值。

C語言中關于指針有什么好的書

《C和指針》,寫得相當地不錯,英文名是《PointersonC》,特別地強調指針的重要性,算是本書的一個特點吧。

不過這本書并不十分適合初學者,如果你曾經學過C語言,有那么一些C語言的基礎但又不是很扎實,那么你可以嘗試一下這本書。我相信,只要你理解了指針,C語言便不再神秘。

都說C語言的指針很難,用不好很容易出錯,那為何還要用指針呢你能舉例說說嗎

1.分析問題

整個問題,從提問者的角度,等價于兩個子問題:

子問題1:為什么C語言要引入指針?

子問題2:指針怎么才能用好?

2.子問題1的分析

現在來分析子問題1。要回到這個問題,要回顧計算機程序的執(zhí)行原理:

現代通用計算機基本上都遵循馮·諾依曼結構。

馮·諾依曼結構的精髓在于:將計算機指令與數據一視同仁,都放入內存中處理。所以計算機程序執(zhí)行的過程,實際上就是不斷從內存中取出指令,再從內存中取出數據,指令作用于數據得到結果,結果再放回內存的過程。

從這個過程可以看出,程序的整個運行都是圍繞內存進行的。既然指令和數據都放在內存中,那么執(zhí)行哪條指令、取哪個數據、結果放到哪里,都需要精確定位內存的具體位置。

C語言作為開發(fā)Unix操作系統(tǒng)而創(chuàng)造出來的編程語言,天然需要具備操作系統(tǒng)底層的能力;而從上述程序運行的視角來看,所謂的系統(tǒng)底層能力,核心在于對內存位置的定位能力。C語言用于對內存進行定位的“武器”就是指針。

一言以蔽之:C語言之所以引入指針,是由C語言誕生的歷史背景和所要承載的歷史使命決定的——開發(fā)操作系統(tǒng),要用強大的操控系統(tǒng)底層的能力,系統(tǒng)底層的核心是對內存的定位操作。

3.子問題2的分析

很多同學被指針搞懵的原因在于:大陸的C語言入門的教材基本上都是譚浩強的《C語言程序設計》,這本教材講述指針過于繁瑣,沒有抓住指針的本質。

指針的本質就是內存地址。

記住這一點之后,你就可以游刃有余了。以下筆者對初學者最容易暈菜的幾個概念進行最凝練的解釋。

3.1多級指針

一級指針就是一次性指向目標內存地址、二級指針就是分兩段指向最終目標地址(第一級相當于先指向一個“中間驛站”,第二級再從“中間驛站”指向最終目標地址)……依次類推,這樣哪怕給你一個N級指針,你也不會懵逼。

3.2指針數組與數組指針

說白了,考的并不是計算機知識,考的是語文知識:)

兩個術語都是偏正短語:前者的被修飾詞(中心詞)是數組,后者的被修飾詞(中心詞)是指針;前者這個數組里的每個元素都是指針,后者這個指針指向的是一個數組(一片連續(xù)的內存區(qū))。

文章到此結束,如果本次分享的c語言指針經典例題和*p在c語言中是什么意思的問題解決了您的問題,那么我們由衷的感到高興!

返回列表
上一篇:
下一篇: