织梦CMS - 轻松建站从此开始!

罗索

面向对象的C语言编程(用文件模仿类)

落鹤生 发布于 2010-01-06 22:08 点击:次 
面向对象的技术成为主流以前许多年,C语言的编程者使用C语言支持模块是的编程风格,使用这种方法,就可以即在C中创建“基于文件的类”,又不增加许多内存或CPU的负载。
TAG:

面向对象的技术成为主流以前许多年,C语言的编程者使用C语言支持模块是的编程风格,使用这种方法,就可以即在C中创建“基于文件的类”,又不增加许多内存或CPU的负载。文件变成了我们的类,且文件中“static”数据成为该类的私有数据成员,该文件中定义的 函数成为文件类的 成员函数,并且我们的整个程序可以分成许多清晰定义的(基于文件的)类。

 将一个单一文件的程序转为面向对象的C文件
    规则:
  1.公有“成员”函数,在.h文件中有他们的原型

  2.私有“成员”函数,在C文件中有他们的原型,并加static

  3.公有的常数,它的值必需要被程序中的其他部分访问,定义在.h文件中

  4.少数的一些公共变量,在C文件中定义(没有使用static关键字)

  5.私有常数及
有变量,他们在文件以外是“看不到的”

另外一遍文章中的内容。

模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行划分在面向对象设计中成为一个错误,牛顿定律遇到了相对论),C语言模块化程序设计需理解如下概念:

  (1) 模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;

  (2) 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明;

  (3) 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;

  (4) 永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。如:

/*module1.h*/
int a = 5; /* 在模块1的.h文件中定义int a */

/*module1 .c*/
#include "module1.h" /* 在模块1中包含模块1的.h文件 */

/*module2 .c*/
#include "module1.h" /* 在模块2中包含模块1的.h文件 */

/*module3 .c*/
#include "module1.h" /* 在模块3中包含模块1的.h文件 */

  以上程序的结果是在模块1、2、3中都定义了整型变量a,a在不同的模块中对应不同的地址单元,这个世界上从来不需要这样的程序。正确的做法是:

/*module1.h*/
extern int a; /* 在模块1的.h文件中声明int a */

/*module1 .c*/
#include "module1.h" /* 在模块1中包含模块1的.h文件 */
int a = 5; /* 在模块1的.c文件中定义int a */

/*module2 .c*/
#include "module1.h" /* 在模块2中包含模块1的.h文件 */

/*module3 .c*/
#include "module1.h" /* 在模块3中包含模块1的.h文件 */

  这样如果模块1、2、3操作a的话,对应的是同一片内存单元。

  一个嵌入式系统通常包括两类模块:

  (1)硬件驱动模块,一种特定硬件对应一个模块;

  (2)软件功能模块,其模块的划分应满足低偶合、高内聚的要求。

程序清单   基于文件的C语言类的一个例子(H文件)

/*------------------------------------------------------------------*-

   PC_IO.H (v1.00)

  ------------------------------------------------------------------

   - see PC_IO.C for details.


   COPYRIGHT
   ---------

   This code is associated with the book:

   EMBEDDED C by Michael J. Pont
   [Pearson Education, 2002: ISBN: 0-201-79523-X].

   This code is copyright (c) 2001 by Michael J. Pont.
 
   See book for copyright details and other information.

-*------------------------------------------------------------------*/

#ifndef _PC_IO_H
#define _PC_IO_H

// ------ Public constants --
公有的常数-------------------------------

// Value returned by PC_LINK_Get_Char_From_Buffer if no character is
// available in buffer
#define PC_LINK_IO_NO_CHAR 127

// ------ Public function prototypes -
公有“成员”函数-------------

void PC_LINK_IO_Write_String_To_Buffer(const char* const);
void PC_LINK_IO_Write_Char_To_Buffer(const char);

char PC_LINK_IO_Get_Char_From_Buffer(void);

// Must call this function frequently ...
void PC_LINK_IO_Update(void);

#endif

/*------------------------------------------------------------------*-
  ---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/

基于文件的C语言类的一个例子(C文件)
/*------------------------------------------------------------------*-

   PC_IO.C (v1.00)

  ------------------------------------------------------------------

   Core files for simple PC link library for 8051 family

   Uses the UART, and Pins 3.1 (Tx) and 3.0 (Rx)


#include "Main.h"
#include "PC_IO.h"

// ------ Public variable definitions -----
公共变量--------------

tByte In_read_index_G;      // Data in buffer that has been read
tByte In_waiting_index_G;   // Data in buffer not yet read

tByte Out_written_index_G;  // Data in buffer that has been sent
tByte Out_waiting_index_G;  // Data in buffer not yet sent

// ------ Private function prototypes ------------------------------

static void PC_LINK_IO_Send_Char(const char);

// ------ Private constants -----
私有常数------------------

// The receive buffer length
#define RECV_BUFFER_LENGTH 8

// The transmit buffer length
#define TRAN_BUFFER_LENGTH 50

#define XON  0x11
#define XOFF 0x13

// ------ Private variables ----
私有变量--------------------

static tByte Recv_buffer[RECV_BUFFER_LENGTH];
static tByte Tran_buffer[TRAN_BUFFER_LENGTH];

/*------------------------------------------------------------------*-

  PC_LINK_IO_Update()

  Checks for character in the UART (hardware) receive buffer
  Sends next character from the software transmit buffer
 
-*------------------------------------------------------------------*/
void PC_LINK_IO_Update(void) 
   {
   // Deal with transmit bytes here

   // Is there any data ready to send?
   if (Out_written_index_G < Out_waiting_index_G)
      {
      PC_LINK_IO_Send_Char(Tran_buffer[Out_written_index_G]);    

      Out_written_index_G++;
      }
   else
      {
      // No data to send - just reset the buffer index
      Out_waiting_index_G = 0;
      Out_written_index_G = 0;
      }

   // Only dealing with received bytes here
   // -> Just check the RI flag
   if (RI == 1)
      {
      // Flag only set when a valid stop bit is received,
      // -> data ready to be read into the received buffer

      // Want to read into index 0, if old data has been read
      // (simple ~circular buffer)
      if (In_waiting_index_G == In_read_index_G)
         {
         In_waiting_index_G = 0;
         In_read_index_G = 0;
         }
     
      // Read the data from UART buffer  
      Recv_buffer[In_waiting_index_G] = SBUF;

      if (In_waiting_index_G < RECV_BUFFER_LENGTH)
         {
         // Increment without overflowing buffer
         In_waiting_index_G++;
         }
   
      RI = 0;  // Clear RT flag
      }
   }

/*------------------------------------------------------------------*-

  PC_LINK_IO_Write_Char_To_Buffer()

  Stores a character in the 'write' buffer, ready for
  later transmission
 
-*------------------------------------------------------------------*/
void PC_LINK_IO_Write_Char_To_Buffer(const char CHARACTER)
   {
   // Write to the buffer *only* if there is space
   // - No error reporting in this simple library...
   if (Out_waiting_index_G < TRAN_BUFFER_LENGTH)
      {
      Tran_buffer[Out_waiting_index_G] = CHARACTER;
      Out_waiting_index_G++;    
      }
   }


/*------------------------------------------------------------------*-

  PC_LINK_IO_Write_String_To_Buffer()

  Copies a (null terminated) string to the character buffer. 
  (The contents of the buffer are then passed over the serial link)

  STR_PTR - Pointer to the NULL-TERMINATED string. 

-*------------------------------------------------------------------*/
void PC_LINK_IO_Write_String_To_Buffer(const char* const STR_PTR)
   {
   tByte i = 0;

   while (STR_PTR[i] != '\0')
      {
      PC_LINK_IO_Write_Char_To_Buffer(STR_PTR[i]);
      i++;
      }
   }

/*------------------------------------------------------------------*-

  PC_LINK_IO_Get_Char_From_Buffer()

  Retrieves a character from the (software) buffer, if available

  The character from the buffer is returned, or - if no
  data are available - PC_LINK_IO_NO_CHAR is returned.

-*------------------------------------------------------------------*/
char PC_LINK_IO_Get_Char_From_Buffer(void)
   {
   char Ch = PC_LINK_IO_NO_CHAR;

   // If there is new data in the buffer
   if (In_read_index_G < In_waiting_index_G)
      {
      Ch = Recv_buffer[In_read_index_G];

      if (In_read_index_G < RECV_BUFFER_LENGTH)
         {
         In_read_index_G++;
         }
      }
  
   return Ch;
   }

/*------------------------------------------------------------------*-

  PC_LINK_IO_Send_Char()

  Based on Keil sample code, with added (loop) timeouts.
  Implements Xon / Off control.

  Uses on-chip UART hardware.

-*------------------------------------------------------------------*/
void PC_LINK_IO_Send_Char(const char CHARACTER)
   {
   tLong Timeout1 = 0;
   tLong Timeout2 = 0;

   if (CHARACTER == '\n') 
      {
      if (RI) 
         {
         if (SBUF == XOFF) 
            {
            Timeout2 = 0;
            do {
               RI = 0;
               
               // Wait for uart (with simple timeout)
               Timeout1 = 0;
               while ((++Timeout1) && (RI == 0)); 

               if (Timeout1 == 0)
                  {
                  // UART did not respond - error
                  // No error reporting in this simple library...
                  return;
                  }

               } while ((++Timeout2) && (SBUF != XON));

            if (Timeout2 == 0)
               {
               // UART did not respond - error
               // No error reporting in this simple library...
               return;
               }

            RI = 0;
            }
         }

      Timeout1 = 0;
      while ((++Timeout1) && (TI == 0)); 

      if (Timeout1 == 0)
         {
         // UART did not respond - error
         // No error reporting in this simple library...
         return;
         }

      TI = 0;
      SBUF = 0x0D;  // Output CR 
      }
 
   if (RI) 
      {
      if (SBUF == XOFF) 
         {
         Timeout2 = 0;

         do {
            RI = 0;

            // Wait for UART (with simple timeout)
            Timeout1 = 0;
            while ((++Timeout1) && (RI == 0)); 

            if (Timeout1 == 0)
               {
               // UART did not respond - error
               // No error reporting in this simple library...
               return;
               }

            } while ((++Timeout2) && (SBUF != XON));
     
         RI = 0;
         }
     }

   Timeout1 = 0;
   while ((++Timeout1) && (TI == 0)); 

   if (Timeout1 == 0)
      {
      // UART did not respond - error
      // No error reporting in this simple library...
      return;
      }

   TI = 0;

   SBUF = CHARACTER;
   }


/*------------------------------------------------------------------*-
  ---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/

(落鹤生)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201001/8246.html]
本文出处:网络博客 作者:落鹤生
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容