嵌入式系统C语言编程的心得体会

转载 2013年12月02日 22:32:50
最近经常在解释程序中指针的应用手法,发现多数人对指针的认识并不完整,捉住了指针的表面现象却没有很好的理解指针的本质特性。上次写指针编的时候也没有很好的解释指针的本质特性,以及这个特性在C语言中的应用方法。
    今天就把这些天的体会总结一下,从三个方面来说明这个问题,一是指针相关的名称以其含义,二是指针在C语言编译时的编译器的工作原理,三是应用时的使用注意事项和优缺点。
    在这里我以8位系统(AVR单片)来解释,其他系统以此类推,主要针对GNU的GCC编译器来说明。首先说一下定义我们定义uint8是8位无符号型变量,因此定义: uint8 v 这里v就是一个无符号的8位变量;uint8 *p 这里p就是一个指针型变量,这个指针型变量是一个指向8位无符号型变量的指针。在AVR中地址位数是16位的,因此,这个指针变量是个16位的数据。编译时在内存中将分配一个8位的空间给变量v,假设分配给v的内存地址是0x000A;分配两个8位空间给变量p,因为p是个指针型的变量,存放的是16位的地址数据,假设分配p的内存地址是0x00010-0x0011。
    考查以下代码
    uint8 v;执行这个语句仅是分配了一个内存空间给v,v是什么值并不确定;
    uint8 *p;执行这个语句分配了一个内存空间给p,p的值也是不确定的;
    v = 0;  执行这个语句的时候对v变量赋值也就是对0x000A空间赋值0;
    *p = 0; 我们看看这时汇编语句是什么LDD     R30,Y+1  
                                    LDD     R31,Y+2   
                                    STD     Z+0,R1    注:在AVR中Z寄存器有R30和R31构成
            从这里我们看到,实际上就是把R1的值付给了Y寄存器里存放的地址空间,而Y的值并没有赋值,而且延续前一次赋值的状态,这个就造成了*p=0赋值位置的不确定性。在程序运行的过程中就会出现致命的问题,可能会造成系统死机。从这个例子也可以看出,简单的把*p看作是一个变量,而采用一般变量的使用方法来处理它是不妥当的,这是有前提的。
    p = &v;我们看这个汇编 MOVW    R24,R28     
                         ADIW    R24,0x03 
                         STD     Y+2,R25   
                         STD     Y+1,R24   注:对Y赋值

    *p = 0;在看这个汇编   LDD     R30,Y+1   
                         LDD     R31,Y+2    
                         STD     Z+0,R1   
    从这里我们可以发现,只有定义一个变量,并且将这个变量的地址赋值给指针变量后,*p才可以采用一般变量的处理方法对其进行操作。
    很多时候发现是使用指针后系统会死机或数据并非我们预想的,主要问题就出在这。在使用操作系统传递消息或邮箱时,这种情况特别明显。看是和说明的操做相同,却为什么不能正常工作呢。因为你忽略对指针变量的赋值,而直接使用*p来作为变量处理。
    这个解释比较绕口,要实际操作中慢慢体会,但要捉住一点,指针就是地址,指针变量就是一个存放地址的空间。但出现问题或思路混乱的时候,将地址空间画出来,并按照你的程序编写的步骤推算一下。

C语言嵌入式系统编程修炼之三:内存操作

数据指针   在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力。在嵌入式系统的实际调试中,多借助C语...
  • xjbclz
  • xjbclz
  • 2016年07月07日 20:51
  • 509

嵌入式系统C语言编程的心得体会(宏应用篇)

在C语言里面宏定义的应用是很灵活的,但是一般讲C语言的书往往并不详细讲述宏的应用,只是简单提一下。 宏的应用是程序模块化,通用化一个重要手段。嵌入式系统做多了就会发现其实没给项目应用的底层函数都十分...
  • chenyi22
  • chenyi22
  • 2013年12月02日 22:35
  • 955

浅谈C语言嵌入式系统编程注意事项

C语言嵌入式系统编程注意事项之背景篇 本文的讨论主要围绕以通用处理器为中心的协议处理模块进行,因为它更多地牵涉到具体的C语言编程技巧  不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,...
  • u013467442
  • u013467442
  • 2015年07月26日 00:39
  • 2679

编写优质嵌入式C程序

前言:这是一年前我为公司内部写的一个文档,旨在向刚踏入嵌入式编程的年轻工程师们介绍如何在裸机环境下编写优质嵌入式C程序。本文通过一些我遇到的、同事遇到的或者一些前人遇到的典型案例来分析嵌入式C中的一些...
  • zhzht19861011
  • zhzht19861011
  • 2015年05月05日 21:26
  • 27508

《嵌入式linux上的c语言编程实践》(亚嵌教材)学习笔记

第九章内存的堆和栈   c使用的内存分为:静态区和动态区,静态区 静态区:只读数据区,初始化数据区,未初始化数据区 动态区:堆区,栈区   栈: 1.使用依赖硬件机制,有两种增长方向。有...
  • maochengtao
  • maochengtao
  • 2015年05月19日 13:15
  • 781

嵌入式开发中为什么选择C语言?

关于为何在嵌入式开发中选择C语言,我将从嵌入式开发的定义,C语言的特点,及嵌入式系统与C语言的联系几方面来作解释。 什么是嵌入式开发: 嵌入式开发就是指在嵌入式操作系统下进行开发,一般常...
  • qq_31108501
  • qq_31108501
  • 2016年07月10日 20:17
  • 2183

嵌入式C语言修炼之道.软件架构篇

模块划分   模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行划分...
  • wangshuwang
  • wangshuwang
  • 2015年01月11日 14:17
  • 728

嵌入式linux开发面试题解析——C语言部分

 1、编写统计一个数二进制表示中有多少个1的函数         int count_bit1(int m)         {      int count = 0;      whi...
  • qr_ljj
  • qr_ljj
  • 2016年11月07日 19:55
  • 451

嵌入式Linux C笔试题积累

http://blog.csdn.net/h_armony/article/details/6764811 1.   嵌入式系统中断服务子程序(ISR)   中断是嵌入式系统中重要的组...
  • tanqiuwei
  • tanqiuwei
  • 2014年03月26日 10:13
  • 5136

经典16道:嵌入式C语言笔试题

1.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)      #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL   我在...
  • you_shou
  • you_shou
  • 2016年09月21日 10:01
  • 4248
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:嵌入式系统C语言编程的心得体会
举报原因:
原因补充:

(最多只允许输入30个字)