在嵌入式培訓(xùn)班C語言實(shí)訓(xùn)過程中,我發(fā)現(xiàn),講數(shù)組學(xué)生們很容易理解,但是一旦涉及到指針,學(xué)生們開始懵了。對于他們來說,指針很難,這是因?yàn)楹芏鄬W(xué)生沒有系統(tǒng)的學(xué)習(xí)過C語言,或者說他們上C語言的時候沒有很好的學(xué)習(xí)。
反而嵌入式培訓(xùn)班C語言到了講數(shù)組,學(xué)生們卻運(yùn)用的很溜,針對于這種情況,我改變了我實(shí)訓(xùn)的方式,凡是涉及到指針方面的問題,盡量用數(shù)組的寫法表達(dá)出來,同時也給學(xué)生們分析一下指針與數(shù)組的聯(lián)系和區(qū)別。其中重點(diǎn)表示在開發(fā)板的LCD屏幕上顯示圖片這一塊。
對于數(shù)組來說,數(shù)組名是數(shù)組首元素的地址,也就是說數(shù)組名存儲的是數(shù)組的首元素地址,那么在C語言里面什么類型的變量是用來保存地址的呢?答案是指針。既然如此,那么使用一個類型對應(yīng)的指針變量來保存數(shù)組的首元素地址,是不是這個指針變量也可以使用數(shù)組表示數(shù)組元素的寫法來描述數(shù)組的元素?經(jīng)過測試,確實(shí)是可以的,而且指針更加靈活,因?yàn)閿?shù)組名雖然存儲的是數(shù)組首元素的地址,但是它不能被重新賦值,這是因?yàn)閿?shù)組一旦確定大小,在內(nèi)存中申請到空間后是固定的,但是指針變量沒有這種限制。所以,但使用mmap函數(shù)對屏幕進(jìn)行映射的時候,通常是先給學(xué)生講解二維數(shù)組的概念,如何使用二維數(shù)組和write函數(shù)對LCD屏幕進(jìn)行操作,以及指針與數(shù)組寫法的聯(lián)系,然后將mmap函數(shù)映射出來的地址保存到一個數(shù)組指針里面去,就可以在顯示的時候使用二維數(shù)組的寫法來實(shí)現(xiàn)。
以下是代碼示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int lcd_fd;
int (*fbp)[800];
int show_bmp(char * bmp_pathname)
{
int bmp_fd;
char bmp_buf[800*480*3] = {0};
int tmp_buf[800*480] = {0};
int i,j,x,y;
//打開圖片
bmp_fd = open(bmp_pathname,O_RDWR);
if(bmp_fd == -1)
{
perror("open bmp ");
return -1;
}
//跳過圖片54個字節(jié)的頭信息
lseek(bmp_fd,54,SEEK_SET);
//讀取像素數(shù)據(jù)
read(bmp_fd,bmp_buf,800*480*3);
//調(diào)整像素數(shù)據(jù)
for(i=0;i<800*480;i++)
{
tmp_buf[i] = bmp_buf[0+i*3] | bmp_buf[1+i*3]<<8 | bmp_buf[2+i*3]<<16 | 0x00<<24;
}
//像素位置調(diào)整并顯示到屏幕上面去
for(y=0;y<480;y++)
{
for(x=0;x<800;x++)
{
fbp[y][x] = tmp_buf[(479-y)*800+x];
}
}
close(bmp_fd);
return 0;
}
int main()
{
//打開LCD
lcd_fd = open("/dev/fb0",O_RDWR);
if(lcd_fd == -1)
{
perror("open lcd");
return -1;
}
//映射屏幕
fbp = (int (*)[800])mmap(0,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,lcd_fd,0);
if(fbp == MAP_FAILED)
{
perror("mmap fail");
return -1;
}
show_bmp("0.bmp");
close(lcd_fd);
return 0;
}
嵌入式培訓(xùn)班C語言中有關(guān)數(shù)組和指針的內(nèi)容,現(xiàn)在同學(xué)們都理解了嗎?如果還有不懂的地方,歡迎來粵嵌進(jìn)一步學(xué)習(xí)。