C語言疑難雜症-指針

2022-06-07     大方老師單片機

原標題:C語言疑難雜症-指針

C語言疑難雜-指針

\\\插播一條:文章末尾有驚喜~///

進修階段:高中信競、大學編程。

前置知識:二進位與十六進位C語言根底,數組。

指針初學可能比較難了解,我這篇文章儘量用通俗易懂的方式來講解。

1.指針概述

為什麼有指針這個東西?由於指針很貼近計算機內部的實際工作原理,與內存實際的尋址方式類似C語言能夠說是高級語言中最貼近機器的語言,而PythonJavaScript這種更親和於人類的語言與機器的關係則比較遠了,甚至它們自身可能還是C語言寫出來的呢。

指針能夠形象地比喻為在內存中定位的導航員。內存那麼大,怎麼知道我須要的東西存在哪裡呢?能夠讓指針來記錄與導航。我們先來了解一下內存。

2.預備知識

2.1內存

鑽研過組裝機、電腦配件的話,一定知道內存條這個東西。此時這個時代,一台家用電腦的內存一般2GB4GB8GB16GB32GB64GB等等。

CPU比作幹活的人,則內存就相當於工作檯CPU在跑的程序以及很多相關數據都存在內存內,這就相當於人在幹活時要把相關資料放在工作檯上使用。

內存能夠看成是一個宏大的數組,我這裡記為

memory[0..n]

memory的每一個單元1B=8bitmemory[0]就是內存的第一個單元。這個中括號裡面的數,即數組下標,被稱為內存地址,簡稱為地址。我確定了一個地址,也就相當於確定了內存中的一個單元。

通常,我們說32位機器,意思就是地址32bit的,最大支持的內存是

memory[0x00000000..0xFFFFFFFF]

最小地址0,最大地址0xFFFFFFFF=2^32-1,最大支持

也就是32位機器理論上最大支4GB的內存,這就是它漸漸被淘汰的理由。

64位機器理論上最大支持的內存是

這個量級遠大於目前的需求,因128位機器在相當長的時長內不會出現。

2.2變量與數據類型

C語言有很多數據類型,不同的數據類型在內存中的占用空間和存儲格式也不一樣。不同數據類型的存儲格式比較複雜,這裡不詳述。我只談談不同的占用空間。

一個變量在內存中占用都是不間斷空間,T類型的變量在內存中占sizeof(T)位元組的空間。當我聲明一T類型的變a時,內存會尋找不間斷且可用sizeof(T)個單元,把它們分配給變a,假如說memory[100..103]4B的空間。此後我對變a進行讀寫,也就相當於memory[100..103]4B的空間進行讀寫。

某些數據類型的占用空間short短整形占2Bint整形占4Bfloat浮點形占4Bdouble雙浮點型占8Bchar字符型占1B.

3.指針

指針是一種特殊的數據類型,指針類型的變量應存儲的是內存地址。32位機器上,任何一個內存地址都32bit=4B,故任何一個指針型變量都占4B.

此時問題來了,指針指向內存中的一個單元,我怎麼知道這個單元裡面存的是什麼東西,是什麼類型的數據?因此,在聲明指針變量的時候,也要聲明這個指針指向數據的類型,假int型指針char型指針等。

3.1指針的聲明

在語法上,聲明指針類型使*符號,例如

int *a, b, *c; //ac是指針b不是指char *ch;

這兩句代碼聲明int*型的變acint型變bchar*型變ch.依據語法,我們習慣上T型指針T*型,含義就T*型變量是指針,其所指的相關內存單元存的T型數據(注意,這裡b變量不是指針,僅僅為普通int整形。)

3.2指針的使用

指針有很多種使用方式,包括動態申請內存、函數地址傳參等等。我這裡僅介紹最簡略的使用方式。我提供一份例程,可直接從例程中進修指針的聲明與使用。

例程:

int x=1, y=2; //xy並賦初int *p=&x; //ppx*p=11; //pxp=&y; //py*p=12; //pyprintf("x=%d, y=%d", x, y); //xy

第一行,在內存中申請不間斷4B區域存int型數1,記為變x;再在內存中申請不間斷4B區域存int型數2,記為變y.x對應內存區memory[100..103]y對應內存區memory[200..203].第一行執行完畢,內存如1所示:

1第一行執行完畢

第二行在內存中申請不間斷4B區域存int*型地址數100,記為變p.&符號是取地址運算符,表示取變x的首地址,在本例中就100.這一行代碼是聲明指針同時賦初值,相當於以下兩行代碼:

int *p;p=&x;

第二行執行完畢,內存如2所示100的十六進位0x64):

2第二行執行完畢

第三行,p所指的地址4B空間內存int型數11.*是解地址運算符表示取得指針所指的內存空間第三行執行完畢,內存如3所示:

3第三行執行完畢

假如第三行改為執p=(int*)11;,則是先int型數11強制轉換int*型數11,然後賦值p,如3.2所示:

3.2第三行改為執p=(int*)11;

p所指的內存空間不一定是可用的。因此像這樣直接給指針賦值一個常數的情況非常罕見。

第四行py的首地址。第四行執行完畢,內存如4所示:

4第四行執行完畢

第五行,把變y的值改12.第五行執行完畢,內存如5所示:

寫文章

Keil系列教09_調試仿真

strongerHuang

?關注他

44人贊同了該文章

說明:

本文原創作者strongerHuang

首發於微信公眾號『嵌入式專欄』,同時也更新在我的個人網站EmbeddedDevelop

標籤Keil MDK-ARMμVision

該教程基MDK-ARM,大局部內容也適用Keil3C51 C251 C166)產品。

一、寫在前面

調試對於程式設計師來說是一個比較重要的環節,因此就很有必要掌Keil的這些調試功能。

Debug調試按鈕,進入調試狀態,就會出現如下Debug Toolbar調試工具欄。

我們調試須要用到的按鈕包含上圖框出來的這些按鈕,但常用的按鈕就是調試工具欄前八個:復位、全速運行、停下運行、單步運行、逐步運行、跳出運行、運行到光標行、跳轉到暫停行。

二、相關描述

這些工具欄按鈕的主要含義能夠參看Keil系列教03_主窗口和工具欄詳細說明》。

調試工具欄按鈕位於菜Debug中,同時調試視圖窗口位於菜View。能夠參看文章Keil系列教04_菜單概述》。

同樣,這些調試工具欄按鈕可通過快速鍵實現,有些默認沒有快速鍵,能夠通Configuration添加快速鍵。請參看文章Keil系列教08_Configuration(二)Shortcut Keys快速鍵章節內容。

下面率領大家掌握那八個調試按鈕、四個斷點按鈕,以及局部調試視圖窗口的內容。

三、八個調試按鈕

保證代碼編譯沒誤,點擊/停下調試按鈕(如下圖),或快速Ctrl + F5,進入調試模式。此時就會出現如文中開頭的調試工具欄。

3.1 Reset復位

Reset復位,讓程序復位到起點,恢復到初始狀態。

3.2 Run全速運行

Run全速運行F5),讓程序處於運行狀態。此按鈕在程序停下運行時有效。

3.3 Stop停下運行

Stop停下運行,讓正在運行的程序停下下來。此按鈕在程序運行時有效。

3.4 Step單步運行

Step單步運行F11),每點一次按鈕,程序運行一步(單步),遇到函數會跳進函數執行(箭頭進入括號)。此按鈕在程序停下運行時有效。

3.5 Step Over逐步運行

Step Over逐步運行F10),每點一次按鈕,程序運行一行(單行),遇到函數跳過函數執行(箭頭跳過括號)。此按鈕在程序停下運行時有效。

3.6 Step Out跳出運行

Step Out跳出運行Ctrl + F11),每點一次按鈕,程序跳出當前函數執行(箭頭跳出括號),直到跳出最外面的函數main函數)。此按鈕在程序停下運行時有效。

3.7 Run to Cursor Line運行到光標行

Run to Cursor Line運行到光標行Ctrl + F10),將光標放在某一行,點擊該按鈕,程序全速運行,直到運行到光標的位置停下下來。(前提是程序能運行到光標所在行)。

3.8 Show Next Statement跳轉到暫停行

Show Next Statement跳轉到暫停行,點擊該按鈕,跳轉到程序暫停(停下)所在行。主要用我們翻開多個文件,不知道程序暫停在哪裡。此按鈕在程序停下運行時有效。

四、四個斷點按鈕

調試時,這四個按鈕也常用,從左到右依次是:插/移除斷點使/失能斷點失能所有斷點取消所有斷點。

4.1/移除斷點

Insert/Remove Breakpoint/移除斷點F9),點擊一下按鈕,在光標所在行插入一個斷點,再點擊一次,則移除斷點。

該按鈕操作即是用滑鼠在代碼所在行前面點擊一次,注意獨有在灰色所在行才有效(也就是程序能執行的地方),如下圖:

4.2使/失能斷點

Enable/Disable Breakpoint使/失能斷點Ctrl + F9),在有斷點根底上,點擊一下按鈕,失能該斷點,再點擊一次,則使能該斷點。

失能斷點就是保留該斷點,但該斷點沒效(程序執行到該處不停下)。

4.3失能所有斷點

Disable All Breakpoints失能所有斷點,保留所有斷點,但都沒效(和上面一個道理),但這裡不能再次使能所有斷點。

4.4取消所有斷點

Kill All Breakpoints取消所有斷點Ctrl + Shift + F9),和上面失能不一樣,這裡是不保留斷點,即取消工程所有斷點,也叫殺掉所有斷點。

五、調試視圖窗口

調試視圖窗口獨有進入調試模式時才會出現,其窗口名稱詳情可參看文章Keil系列教04_菜單概述》View菜單章節。

這裡講述幾個在調試時常用的視圖窗口。

5.1 Watch窗口

Watch查看變量的窗口,Watch1Watch2兩個窗口,都一樣,方便用戶多個窗口同時查看。

查看這些調試視圖窗口能夠通過菜單,或點擊工具欄按鈕翻開。

選中變 -> -> Add xxx to ->Watch1,此時自動會彈Watch1窗口:

5.2 System Viewer窗口

System Viewer系統(外IOUSARTTIM等)窗口,能夠了解查看外設寄存器的窗口,如下圖,查USART寄存器值的窗口。

這些調試視圖窗口只針對於調試時,方便大家查看一些調試信息,掌握這些內容會提高你的調試效率,以及更精確定Bug

六、說明

1.該文檔僅供個人進修使用,版權所有,禁商用。

2.本文由我一個人編輯並整理,難免存在一些錯誤。

彩蛋:最近有同學跟我要單片機的資料,我特意花幾個月時間,總結了我10年產品研發經驗,資料包幾乎覆蓋C語言、單片機、模電數電、原理圖PCB設計、單片機高級編程等等,非常適合初學者入門和進階。除此以外,再含淚分享我壓箱底22個熱門開源項目,包含源+原理+PCB+說明文檔,不是市面上打包賣的那種課程,我認為教程多未必是好事10年前我自學快,除了自身執行力以外,還有就是教程少。不要害羞做伸手黨,等你一個小紅點。後期我也會組建一些純技術交流的小圈子,讓大家能認識更多的大佬,有個好的圈子,你對行業的認知一定是最前沿的。

文章來源: https://twgreatdaily.com/zh-cn/3bfcbbe58c3a5a8ec491acd786b0c760.html