1. 程式人生 > >微控制器C語言指標意義淺析—Keil-C51

微控制器C語言指標意義淺析—Keil-C51

通常認為,C語言之所以強大,以及其自由性,很大部分體現在其靈活的指標運用上,甚至認為指標是C語言的靈魂。這裡說通常,是廣義上的,因為隨著程式語言的發展,指標也飽受爭議,並不是所有人都承認指標的“強大”和“優點”。在微控制器領域,指標同樣有著應用,本章節針對Keil C-51環境下的指標意義做簡要分析。



1     指標與變數
指標是一個變數,它與其他變數一樣,都是RAM中的一個區域,且都可以被賦值,如程式①所示。
#include "REG52.H"        
unsigned int j;
unsigned char *p;
void main()
{
         while(1)

         {
                   j=0xabcd;
                   p=0xaa;
         }
}
Debug Session模式下,將滑鼠指標移到到變數“j”“p”位置,可以顯示變數的實體地址,如圖1-1、1-2所示。






圖中箭頭所指處即為變數在RAM中的“首地址”,為什麼是“首地址”呢?變數根據型別可分為8位(單位元組)、16位(雙位元組),程式中變數“j”是無符號整型,所佔物理空間應為2位元組,而在8位微控制器中,RAM的一個儲存單元大小是8位,即1位元組,因此需2個儲存單元才滿足變數“j
”長度。所以實際上變數“j”的實體地址為“08H”“09H”。同理,“pD:0x0A)”即變數“p”的首地址為“0AH”。
下面通過單步執行程式來觀察RAM內的資料變化,開啟兩個Memory Windows視窗,在Keil軟體下方顯示為Memory1Memory2,在兩個視窗中,分別做如圖2-1、2-2所示的設定。






兩個Address填寫的內容分別是:D:0x08D:0x0A,即量“j”和變數“p”的首地址,輸入後回車,便可監視RAM中該地址下的資料。設定好後,準備除錯。

Debug Session模式中,箭頭所指處即為即將執行的語句,單擊“Step”功能按鈕(或按
F11鍵),讓程式執行,如圖3所示。

第一次單擊“Step”按鈕後,Memory1視窗內資料如圖4所示。

由除錯結果可知,08H資料由00H變為ABH09H資料由00H變為CDH,出現這種變化是因為執行了語句j=0xabcd;08H為變數“j”高八位,儲存“AB”,09H為變數“j”低八位,儲存“CD”。
第二次單擊“Step”按鈕,執行語句:p=0xaa;此時需觀察Memory2視窗內資料,如圖5所示。

由除錯結果可知,0CH處值由00變為“AAH”,程式相吻合。這裡需要注意,在Keil C-51編譯環境下,指標變數,不管長度是單位元組或是雙位元組,指標變數所佔位元組數為3位元組。故此處“AAH”不是儲存在0AH而儲存在0CH0A+2)地址中。
綜上所述,指標實際上是變數,都是對映到RAM中的一段儲存空間,區別是,指標佔用3位元組,而其他變數可根據需要設定其所佔RAM1位元組(char)、2位元組(int)、4位元組(long)。

2       指標作用
指標的作用是什麼呢?先來看下面的程式:
程式②
#include "REG52.H"         
unsigned chartab1[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
unsigned char codetab2[8]={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80}; 
unsigned char N1,N2;
void main()
{
            N1=tab1[0];
            N2=tab2[0];
}
顯然,程式執行的結果是N1=0x01N2=0x10。這裡都是講陣列內的資料賦值給變數,但存在區別,tab1陣列使用的是微控制器RAM空間,而tab2陣列使用的是微控制器程式儲存區(ROM)空間。儘管使用C語言為變數賦值時語句相同,但編譯結果並不相同,此程式編譯後的結果如圖6所示。
 


由編譯結果可知,N1=tab1[0]語句實際上是直接定址,而N2=tab2[0]是暫存器變址定址。不管是何種定址方式,都是將一個實體地址內的資料取出來使用:tab1陣列中,tab[0]對應的RAM地址是0x0Atab[1]對應的RAM地址是0x0B……以此類推;tab2陣列中,tab[0]對應的ROM地址是0x00A5tab[1]對應的ROM地址是0x00A6……以此類推。不管這些陣列或變數所在的RAMROM地址如何,使用者最終需要的是陣列或變數的資料,而指標,就是通過變數或陣列的實體地址訪問資料,也就是說,通過指標,同樣可以訪問陣列或變數資料。現將程式②做出調整,得到程式③如下:
#include "REG52.H"         
unsigned chartab1[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
unsigned char code tab2[8]={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80};
unsigned char N1,N2;
unsigned char  *p;
void main()
{        
         unsignedchar i;
         p=tab1;
         for(i=0;i<8;i++,p++)
         N1=*p;

         p=tab2;
         for(i=0;i<8;i++,p++) 
         N2=*p;
}
程式執行結果:tab1陣列內的8個數值依次被賦值給N1tab2陣列內的8個數值依次被賦值給N2
程式③執行Debug Session功能後,打Watch Windows視窗,在Watch1視窗下新增需要監視的變數,此處為“p”和“N1”,如圖7所示。

Value為當前變數數值,程式為執行前,p值為0x00,單擊Step按鍵功能後,執行p=tab1;p值變為0x0A,如圖8所示。

0x0A是什麼值呢?將滑鼠移至tab1陣列位置,可顯示出陣列所在的實體地址,0x0A就是陣列tab1的首地址,如圖9

相關推薦

微控制器C語言指標意義淺析Keil-C51

通常認為,C語言之所以強大,以及其自由性,很大部分體現在其靈活的指標運用上,甚至認為指標是C語言的靈魂。這裡說通常,是廣義上的,因為隨著程式語言的發展,指標也飽受爭議,並不是所有人都承認指標的“強大”和“優點”。在微控制器領域,指標同樣有著應用,本章節針對Keil C

微控制器C語言指標變數

微控制器C語言變數分別有char型,int型,long型,float型等,它們分別佔用記憶體為1個單元,2單元,4單元,4單元等,另外陣列和字串則佔用了記憶體某段連續的單元。這些變數的共同特徵是它們都裝的數值。那如果一個變數裡面裝的不是數值,而是地址,這個變數則稱為指標變數

C語言指標的運算(指標加或減一個整數的意義

        指標可以加上或減去一個整數。指標的這種運算的意義和通常的數值的加減運算的意義是不一樣的,以單元為單位。例一:#include<stdio.h> int main() { char a[]="0123456789"; int *ptr = (i

C語言指標訓練

去空字串 1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 6 char * removeSpace(c

嵌入式C語言--指標與字串

使用指標這一工具來操作字串。 定義字串變數的初始化方法 char *strptr = "liefyuan"; char strarray1[] = "liefyuan"; char strarray2[8] = "liefyuan"; char strarray3[8] = {'

C語言指標實現兩個數的互換

#include <stdio.h> void change1(int a, int b)//形參與實參不是同一個變數{ int t; t = a; a = b; b = t; } void change2(int * a, int * b)//只是把兩個變數的地址儲存的位置換了,但是變數的值

C語言 指標實現字串連線

C語言 指標實現字串連線 #include <stdio.h> #include <string.h> int main() { char s1[100], s2[100], s3[100]; char *p1=NULL; char *p2=NULL; char

C語言指標實現計算平均分等功能

4個學生5門課資料自己輸入,輸出第一門的平均分,並找出有兩門以上課程不及格的學生和平均成績在90分以上的或全部課程成績在85分以上的學生。程式不難,容易理解,但關鍵是思路要清楚。裡面涉及大量的指標的定義使用,多敲點這樣過百行的程式為以後大程式打基礎。程式碼如下: #include<iost

C語言指標——對普通變數的指標操作和對陣列(常量)的指標操作

       我們知道,每一個變數都有一個記憶體位置,每一個記憶體位置都定義了可使用連字號(&)運算子訪問的地址,它表示了在記憶體中的一個地址。        我們喜歡在程式中使用指標代替陣列,因為變數指標可

正確理解C語言指標中的 &a+1,假設a為一個數組

1.int a[5]={1,2,3,4,5}; int p=(int)(&a+1); printf("%d",*(p-1)); 答案為什麼是5? 這個問題的關鍵是理解 &a a是一個數組名,也就是陣列的首地址。 對a進行取地址運算子,得到的是一個指向陣列

c語言-指標陣列

指標 記憶體和地址怎麼理解呢? 機器中有一些位置,每一個位置被稱為【位元組】/byte,許多現代機器上,每個位元組包含8個位。更大記憶體單位【字】,通常包含2個或4個位元組組成。 一個字包含4個位元組,它的地址是什麼? 他仍然只有一個地址,是最左邊還是最右邊的那個位元組的位置,取

c語言指標探祕

今天寫AVL樹的時候突然出了個bug,死活找不出來,後來百度了一下發現是用指標傳當形參的時候指標指向的內容不會變化的,有點類似於直接傳值,所以打算好好總結一下c語言指標的知識。 首先,我們一起來看一下指標的基本知識 int main() { int *p; int a = 666; p

【SDCC】開源的微控制器C語言編譯器

轉自:http://blog.sciencenet.cn/blog-1750-689572.html    SDCC的全稱是Small Device C Compiler,所以不僅僅是微控制器的編譯器;目前SDCC支援Intel 8051, Maxim 80DS390,

C語言 指標基礎篇 陣列,函式與指標的運用 2 14

下面看看如何在函式中運用指標吧  下面是往函式傳入指標的簡單操作,不是傳入陣列的。判斷一個a是否大於b是的話給,是的話對其進行操作,不是的話就直接返回。 1 #include <stdio.h> 2 int main(){ 3 int num1,num2,*p1,

C語言指標詳解(經典,非常詳細)

C語言指標詳解(經典,非常詳細) 前言:複雜型別說明     要了解指標,多多少少會出現一些比較複雜的型別,所以我先介紹一下如何完全理解一個複雜型別,要理解複雜型別其實很簡單,一個型別裡會出現很多運算子,他們也像普通的表示式一樣,有優先順序,其優先順序和運算優先

C語言指標描述

C語言  指標語法 #include<stdio.h> #include<stdlib.h> main(){ int a=10; int* pointer=&a; } C語言裡面的指標只能操作地址  

18. C語言 -- 指標陣列和陣列指標

本部落格主要內容為 “小甲魚” 視訊課程《帶你學C帶你飛》【第一季】 學習筆記,文章的主題內容均來自該課程,在這裡僅作學習交流。在文章中可能出現一些錯誤或者不準確的地方,如發現請積極指出,十分感謝。 也歡迎大家一起討論交流,如果你覺得這篇文章對你有所幫助,記得評論、點贊哦 ~(。

17. C語言 -- 指標和陣列的關係

本部落格主要內容為 “小甲魚” 視訊課程《帶你學C帶你飛》【第一季】 學習筆記,文章的主題內容均來自該課程,在這裡僅作學習交流。在文章中可能出現一些錯誤或者不準確的地方,如發現請積極指出,十分感謝。 也歡迎大家一起討論交流,如果你覺得這篇文章對你有所幫助,記得評論、點贊哦 ~(。

16. C語言 -- 指標

本部落格主要內容為 “小甲魚” 視訊課程《帶你學C帶你飛》【第一季】 學習筆記,文章的主題內容均來自該課程,在這裡僅作學習交流。在文章中可能出現一些錯誤或者不準確的地方,如發現請積極指出,十分感謝。 也歡迎大家一起討論交流,如果你覺得這篇文章對你有所幫助,記得評論、點贊哦 ~(。

C語言指標初識

定義指標變數 定義指標變數,在變數名前面加星號*,格式為:                 int a; datatype *pointname;      int *p; p = &a; 或者              int a; datatype *pointname = v