C語言中怎麼理解野指針?

數字視聽科普


C語言是一種比較流行的語言,在眾多的編程語言中C語言長期穩居前列的位置,足見C語言在編程界使用的是一種非常廣泛的一種編程語言。學過C語言的朋友都知道在學習C語言時學習指針內容是一個繞不過去的坎,要想學會C語言必須要掌握指針這個知識點,從一個方面講指針既是C語言的重點也是C語言的難點,我們只有攻下這個“堡壘”才可以說真正學會了C語言。

對C語言指針中變量地址的理解

下面我結合自己學習C語言的過程通過自己用C語言編寫單片機程序的經驗來談談我對C語言的指針理解和簡單的應用。我們利用C語言編寫程序時當遇到數組、字符串以及內存的動態分配等問題時,我們這時要用指針的話往往能達到簡化程序快速處理各種數據。從這方面我們可以看到指針能為程序中的各種數據的傳遞提供了很快捷的方法。

其實指針就像彙編語言中的寄存器間接尋址一樣,我們訪問的地址不是寄存器中的數據,而是訪問的是寄存器的地址。我們打個比方,我們把整個內存比作一棟大樓,內存中的寄存器就好像大樓中的每個房間,為了方便尋找房間我們都把房間按一定規律編號,同樣我們也把內存中的寄存器編好號,當我們要到大樓裡找人的時候,我們不是直接找人而是找這個人所居住的房間號,只要把房間號找到了,那麼人就自然而然地找到了。那麼同理計算機要尋找去處理某個數據不是直接去尋找這個具體的數據而是去尋找存儲這個數據的地址。找到了存儲這個數據的地址那麼這個數據也就找到了。

因此我們就把這個存儲數據的地址稱之為變量的地址,因為這個存儲器裡存儲的是一個變量,就像大樓房間裡的人一樣,房間裡的人也是經常會變的,今天這個房間住的是張三明天李四又住進去了,所以我們把存儲變量的地址就叫變量的地址。比如有個變量我們用X表示,假如它存儲在0X01這個地址單元中,我們要取出這個變量的地址用語言表達式為&X。

對C語言中指針變量的理解

我們知道了如何取變量的地址了,那麼下面就是如何把這個變量的地址給予誰的問題了,這時候我們又要引出一個“概念”。這個“概念”名詞叫指針變量。這時我們可以定義一個指針變量P,我們如果把X這個變量的地址要賦給指針變量的話,可以這樣表達:P=&X。為了明確這個變量不是一般的變量,我們要給這個指針變量加個“標籤”用*P表示。這個標籤就像“身份證”一樣,一但加上就說明這個變量不是一個一般的變量了,我們用語言表達為:*P=&X。當然既然都是變量那麼我們在使用這些變量時先要給它們定義屬性。也就是它們屬於哪一類“人員”。

C語言指針的簡單應用舉例

以上就是我對C語言中的指針這個知識點的理解,下面我們舉個“栗子”來說明指針是如何應用的,下面我們用C語言指針來編寫一個單片機流水燈的小程序。如下圖說表示的。

程序中傳 遞的是 buf 的地址,把這個地址值直接傳遞給函數 ShiftLeft 的形參指針變量 p,也就是 p 指 向了 buf。從小程序中可以看出我們傳遞的是指 針,不僅僅我們的子函數可以使用 buf 裡邊的值,而且還可以對 buf 裡邊的值進行改變。 此外再在說一句,只要是*p 前邊帶了變量類型如 unsignedchar,就是表示定義了一個指 針變量 p,程序中的*p,是指 p 所指向的內容。

以上就是我對這個問題的理解,歡迎朋友們對這個問題 進行討論。敬請關注電子及工控技術。感覺對你有參考作用請隨手點個贊哦!


電子及工控技術


C語言指針該怎麼理解這個問題,真的是有1000個人能給出1000個答案。我覺得,在這裡我可以給出我理解並整理的一個答案。

對於C語言指針,我認為可以從“兩己三他”的維度來理解。所謂的“兩己三他”,展開來說,就是“己址,己值,他址,他值,他型”。詳細論述,建議題主知乎上搜索我寫的一個文:從5個維度來看C語言指針(指針就是個紙老虎)。

大概來說:

  1. 己址:就是自己的地址的意思。就是指針變量也有自己的地址;
  2. 己值:就是自己的數據值的意思。就是指針變量也有自己的數據值;
  3. 他址:就是他人的地址的意思。指針變量的己值,其實就是他人的地址;
  4. 他值;就是他人的數據值的意思。指針變量的己值是他人的地址,那麼就可以通過指針變量獲取到他人的數據值;
  5. 他型:就是他人的類型。你以為聲明指針變量時的類型,是指指針嗎?你錯啦!

我這裡寫一段C語言代碼,大概解釋下“兩己三他”的意思。



C程序也很簡單,裡面有一些關於指針常見的C語言代碼寫法。

pInt = ¶;這條語句的本質,其實就將變量para的地址給了指針pInt的己值。

printf("%x \\n\

數字視聽科普


C語言中的野指針通常指的是,一個指針指向的內存已經被系統回收了,但這個指針又沒有被置空(賦值NULL),而是繼續保存著那塊內存的地址,這樣的指針通常被稱為“野指針”。

因為“野指針”的內容沒有被置空,通過它仍然可以操作那塊已經被回收的內存,但此時那塊內存可能已經被系統分配它用,這樣就會產生內存操作衝突,導致程序的崩潰。

而產生“野指針”通常有以下兩種情況:

1. 使用malloc/calloc動態分配的內存,調用free函數釋放之後,沒有把相應的指針賦值為NULL;

2. 函數內部定義了一個臨時變量,並返回這個變量的地址賦值給函數外部的一個指針。由於函數內部的臨時變量,在函數退出後即被釋放,使用函數內部臨時變量地址賦值的指針,在函數結束後就指向了一塊已經被釋放了的內存。


zcphoenix2018


底下的回答其實概念不是完全對的,甚至是錯的。

而且一個簡單問題寫一堆,長篇累牘,浪費讀者時間。

野指針用一句話就可以解釋: 指向已被釋放的內存或者已被回收的對象的指針。

比方說,在C語言裡,你有一個指針指向某內存塊,當用free函數釋放了該內存塊時,該指針就相當於指向無效內存塊了,如果繼續使用,就會造成程序錯誤,俗話說就是"程序跑飛了"。

下面有網友說的一個例子,指針先指向一個分配好的內存塊,然後將指針指向另一個新分配的內存塊,導致前一個內存塊無法再被引用到而釋放。這不是野指針問題,是內存洩露問題!基本概念要搞清楚,不能誤人子弟。


周林ZhouLin


C語言的指針是本分之九十初學者最難過的一關,因為它比較抽象。想要去理解和熟練運用指針就少不了從原理層去認識它。這裡小編就自己學習指針過程中的一些理解,總結出來分享給您;

理解指針

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

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

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

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

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

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

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

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

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

指針的運用

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

先看一段代碼:

#include <stdio.h>
#include <string>
#include <iostream>
#include <time.h>
using namespace std;
class people
{
public:
people();
~people();
string Name ;
int age ;
bool sex ;
char info[1024] ;
void run(){}
void eat(){}
private:
};
people::people()
{
}
people::~people()
{
}
int main()
{
people* p1 = new people();
cout<cout<cout<<sizeof>cout<<sizeof>system("pause");
return 0 ;
}/<time.h>/<iostream>/<string>/<stdio.h>

直接運行看結果:

分析

接下來來一一進行分析:

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

cout<

cout<

cout<<sizeof>

cout<<sizeof>

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

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

圖解

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

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

改變地址

如此,我們三個對象互相賦值後會發生什麼呢?

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

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

改變地址的值

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

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


編程老大叔


C語言指針是C語言中最基礎同時也是難點之一,很多學習過C語言的都知道指針,最基本的用法也都知道,但是深入學習C語言就知道指針是C語言的靈魂,難點就是了解指針全面用法,以及指針和指針變量的關係。

C語言指針本身難度並不大,最讓人頭痛的是它的繁瑣。C 語言最顯著的特點,就是因為它裡面有指針。

要了解指針以及指針的運行,首先我們先了解數據保存過程的與我們如何讀取保存過數據的內容。

我們都知道內存單元是字節,在程序中定義某個變量之後,當系統對其進行編譯時就會分配到內存單元字節,每個單元自己都有自己的編號,當然就會有給它一定長度的空間,也就是地址。

由於我們可以通過地址能找到變量單元,也可以說該地址“指向”該變量單元,所以在C語言中,地址就稱為“指針”,明白一點就是通過“地址”能找到對應的內存單元,每個變量地址都對應一個變量指針。

至於如何運行,上面也說了指針的作用就是存儲地址值,即操作內存。



SOWORD科技言


指針是一種的變量的類型,這種變量存儲的值是一個內存地址。

在C語言中,每定義一個變量,編譯器都會為其分配變量類型對應大小的內存,內存的起始地址就是變量的地址,內存存儲的內容就是變量的值。

int i; //編譯器為變量名為i的變量分配了內存。

通過變量名,我們可以讀寫變量的值。

i=10;//寫入數值10到名為i的變量。

printf("%d\

計算機軟件知識


恰好我之前寫了一系列介紹 C 語言的文章,介紹了什麼是指針,以及為什麼要使用指針,下面摘錄一部分,感興趣的話,可以點我瞭解更多。


什麼是 C語言指針?


不同的數據類型的主要區別在於佔用的存儲空間不同。我們知道,C 程序是運行在計算機的內存中的,因此 C 程序的變量也是存在於內存中的。C 標準規定 char 類型佔用一個字節的存儲空間,對其他整型卻沒有做規定,現在為了解釋的方便,我們假設 int 類型的數據佔用內存 4 個字節。

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

signed char i = 3;int j = 8;

那麼,i 佔用了 1 字節的內存空間,j 佔用了 4 字節的內存空間,請看下圖。

方框表示內存空間,內部表示存儲的值。我們把內存逐字節編號,方框外部的數字表示方框的編號(這樣的內存“編號”即所謂的“內存地址”)。修改變量 i 的值,實際上就是修改地址為 4000 的內存空間裡的值。那反過來呢?如果我修改了地址為 4000 的內存空間裡的值,i 的值會相應改變嗎?答案是肯定的,請繼續往下看。

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

#include <stdio.h>
int main()
{
signed char i = 3;
int j = 8;
long p1 = (long)&i;
printf("p1: %ld \

IT劉小虎


1 內存是個大樓,樓中有許多房間,每個房間只住八個0或者1;

2 每個房間都有門牌號,這個號從零號開始,最大就看內存條大小了,這個門牌號就是地址;

3 內存中存儲數字的房間可以分為兩種,一種是存儲普通的數字,一種存儲其他房間的門牌號(地址),存儲其他房間門牌號的房子,就是指針,這些房間在C語言上都稱為變量;

4 任何一個變量都有地址,如同所有房間都有門牌號,可以通過:

&變量

來獲得這個變量的存儲地址,保留的話只能存進指針變量中去。

5 可以通過*運算,按一個指針變量中存儲的地址、取出那個地址中存儲的數。

簡單描述,更多內容好好看教材。


素食的貓


看看我新發布的視頻,也許指針不再難了。

/<stdio.h>/<sizeof>

/<sizeof>


分享到:


相關文章: