首頁 > 軟體

C語言基礎知識點指標的使用

2022-03-06 13:00:03

一、指標的作用

運用指標可以有效地表達一些複雜地資料結構,比如系統地動態分配記憶體、訊息機制、任務排程、定時器等等。掌握指標可以使你的程式更加簡潔、緊湊、高效。那麼在微控制器領域,如果是做稍微大一點的專案,需要把每一個功能做出模組化,硬體驅動層和應用層分別獨立執行,即使更換微控制器型號也不用修改應用層程式,即移植性非常強,這些都離不開指標。甚至沒有指標會很難實現,即使實現了程式碼可移植性也很差。
如果錯誤使用指標,可能會造成記憶體溢位錯誤從而導致程式’宕機‘。

二、地址與指標

指標是一個比較抽象的概念,如果想真正瞭解指標,那麼要先從資料是如何儲存在記憶體裡面說起,我們通過一個圖來看資料在記憶體裡面儲存的情況。

紅色框中是記憶體的地址,綠色框中是地址下面的資料,橙色框中是記憶體的偏移量。總結:通過地址就可以存取記憶體。

三、指標變數

變數型別 *變數名

unsigned char *p;
unsigned char a;
p=&a;

這個程式碼裡,我們定義了一個變數a,定義了一個指標變數p,我們通過運運算元&把變數a的記憶體地址賦值給變數p,所以p指向了變數a的記憶體儲存地址。
上面說了指標變數賦值的問題。那麼怎麼獲取和改變指標變數指向那個記憶體地址的資料,我們可以通過:
*指標變數 = 數值。如:*p = 10
這樣操作來改變指標變數指向的記憶體地址的資料。
通過:a = *p;
來獲取指標變數指向那個記憶體地址的資料。

四、陣列與指標

一般系統或編譯器會分配連續地址的記憶體來儲存陣列裡面的元素,如果把陣列地址賦值給指標變數,那麼就可以通過指標變數來參照陣列,讀寫陣列裡面的元素了,具體方法如下:
指標變數 = &陣列名[下標]
或者
指標變數 = 陣列名
例如:p = &buff[0]; 或者p = buff
p是指標變數,buff是陣列,通過這兩種方式可以把陣列地址賦值給指標變數。

五、指標自加自減運算

指標變數除了可以用來獲取記憶體地址的值以外,還可以用來進行加減運算,那麼這個加減呢跟普通變數加減不一樣,普通變數加減的是數值,而指標變數加減的是地址。

二維數值與指標:

二維陣列與一維陣列一樣,都是分配連續的地址來儲存資料的。

六、指向指標的指標

一個指標變數指向整型變數或者字元型變數,當然也可以指向指標變數的儲存地址,可以簡稱雙重指標。

定義方法:

資料型別 **指標變數名;

例如:unsigned char **p

這個含義就是定義了一個指向指標的指標變數p,它指向另一個指標變數。

七、指標變數作為函數形參

一般我們都是以字元型、整型、陣列等作為函數的形參帶入,除此以外,指標變數也可以作為形參使用,而且用的非常多,主要目的是為了改變指標指向地址的值,專業術語是通過形參改變實參的值。

八、函數指標

如果在程式中定義了一個函數,那麼在編譯時系統就會給這個函數程式碼分配一段儲存空間,這段儲存空間的首地址就稱為這個函數的地址。而且函數名錶示的就是這個地址。既然是地址我們就可以定義一個指標變數來存放,這個指標變數就叫函數指標變數,簡稱函數指標。

函數指標的定義:函數返回值型別 (*指標變數名) (函數參數列);

九、函數指標陣列

像字元型,整形都是可以單獨定義,也可以定義成陣列,同樣函數指標也可以定義成陣列,函數指標陣列定義格式如下:
函數返回值型別 ( *指標變數名[陣列大小] ) ( 函數參數列);

#include <stdio.h>
/*如果知道記憶體地址,就可以通過記憶體地址來改變變數的值 *(unsigned int *)0x404090 = 12;*/
enum /*列舉*/
{
    led1,
    led2,
    led3,
    led_sum    /*代表一共有多少個列舉變數,用來靈活定義陣列*/
};

void drive_led1(unsigned char sta)
{
    if(sta) printf("led1 onrn");
        else  printf("led1 offrn");
}
void drive_led2(unsigned char sta)
{
    if(sta) printf("led2 onrn");
        else  printf("led2 offrn");
}
void drive_led3(unsigned char sta)
{
    if(sta) printf("led3 onrn");
        else  printf("led3 offrn");
}

void (*funcled[led_sum])(unsigned char sta) = {drive_led1,drive_led2,drive_led3} ;/*函數指標陣列*/ 

void xxx1()
{
    printf ("func1 runningrn");
}
void xxx2()
{
    printf ("func2 runningrn");
}
void xxx3()
{
    printf ("func3 runningrn");
}

void (*func1[3])() = {xxx1,xxx2,xxx3} ;/*函數指標陣列 */
unsigned char (*func) (unsigned char ,unsigned char);/*函數指標*/

unsigned char sum(unsigned char v1,unsigned char v2)
{
    return v1+v2;
}

void setvlue (unsigned char *p)
{
    *p = 20;    
}

int main()
{
    unsigned char a;
    setvlue(&a);
    func=sum;
    
    a=func(1,2);
    a=(*func)(1,2);/*或者a = func(1,2); 都可以執行*/
    printf ("a=%drn",a);
    func1[0]();/*函數指標陣列*/
    func1[1]();/*函數指標陣列*/
    func1[2]();    /*函數指標陣列*/
    funcled[led3](1);//控制亮燈,一條程式碼即可 
            
    return 0;    
}

十、指標的應用場景

在嵌入式領域主要有兩個方面的作用:

  • 1、做底層作業系統,比如記憶體管理,訊息佇列等。
  • 2、做模組化程式介面。

 到此這篇關於C語言基礎知識點指標的使用的文章就介紹到這了,更多相關C語言指標使用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com