1、程序的样式与结构

  C语言与C++和python等语言不同,他是一门面向过程的编程语言,所以其的应用大多是用在单片机及嵌入式的驱动方向,同时由于其入门相对简单,所以其基本上是大多数人入门程序设计时第一门接触到的语言,对于入门来说,在课堂上老师基本上不会讲解一项工程设计时,对于程序的样式和结构的要求,这就导致了很多学生只求把老师要求的任务完成就万事大吉了,对于程序样式和程序结构都没有太过注意,我本科在电子设计实验室学习的时候,周围有很多同学都是这样的态度,对项目指标的要求只求达到即可,但是对于整个程序的调用胡乱无章,最后工程完成,同项目组的同学对程序进行查看时,往往一头乱麻不知道从何看起,自己过一段时间后需要对原来项目进行调用修改时,也是一头雾水,这个在实际工作中是不可取的,第一这样会导致效率低下,第二,在后期对程序进行维护的时候往往很容易出现意想不到的BUG。

 

下面介绍一个好的项目程序应该如何布局和搭建。

  首先,对于没有调用RTOS的一个项目,程序的结构要清晰,一般main.c文件应该为工程文件的顶层头文件,其他的.c类文件应该为对应功能的完成文件,其中.c类文件的.h 类文件应该为该类文件的API接口,然后通过include.h文件来进行调用设置,最后被main.c文件进行调用。但是,当工程特别巨大时,还是建议另外在建立一个schedule.c文件将初始化的调用和中断处理等作为函数在这里进行分级后再在main.c里面进行调用,这样工程结构就会特别清晰了,对于后期的修改和维护也会方便的多。

下面以我最近在看的GIT上的文件为例:

  1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
  2 //
  3 // Licensed under the Apache License, Version 2.0 (the "License");
  4 // you may not use this file except in compliance with the License.
  5 // You may obtain a copy of the License at
  6 
  7 //     http://www.apache.org/licenses/LICENSE-2.0
  8 //
  9 // Unless required by applicable law or agreed to in writing, software
 10 // distributed under the License is distributed on an "AS IS" BASIS,
 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 // See the License for the specific language governing permissions and
 13 // limitations under the License.
 14 
 15 #include <stdio.h>
 16 #include <stdlib.h>
 17 #include <unistd.h>
 18 #include <string.h>
 19 #include "freertos/FreeRTOS.h"
 20 #include "freertos/task.h"
 21 #include "nvs.h"
 22 #include "nvs_flash.h"
 23 #include "esp_system.h"
 24 #include "esp_log.h"
 25 
 26 #include "bt.h"
 27 #include "bt_app_core.h"
 28 #include "bt_app_av.h"
 29 #include "esp_bt_main.h"
 30 #include "esp_bt_device.h"
 31 #include "esp_gap_bt_api.h"
 32 #include "esp_a2dp_api.h"
 33 #include "esp_avrc_api.h"
 34 
 35 /* event for handler "bt_av_hdl_stack_up */
 36 enum {
 37     BT_APP_EVT_STACK_UP = 0,
 38 };
 39 
 40 /* handler for bluetooth stack enabled events */
 41 static void bt_av_hdl_stack_evt(uint16_t event, void *p_param);
 42 
 43 
 44 void app_main()
 45 {
 46     /* Initialize NVS — it is used to store PHY calibration data */
 47     esp_err_t ret = nvs_flash_init();
 48     if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
 49         ESP_ERROR_CHECK(nvs_flash_erase());
 50         ret = nvs_flash_init();
 51     }
 52     ESP_ERROR_CHECK( ret );
 53 
 54 
 55     esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
 56     if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
 57         ESP_LOGE(BT_AV_TAG, "%s initialize controller failed\n", __func__);
 58         return;
 59     }
 60 
 61     if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) {
 62         ESP_LOGE(BT_AV_TAG, "%s enable controller failed\n", __func__);
 63         return;
 64     }
 65 
 66     if (esp_bluedroid_init() != ESP_OK) {
 67         ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed\n", __func__);
 68         return;
 69     }
 70 
 71     if (esp_bluedroid_enable() != ESP_OK) {
 72         ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed\n", __func__);
 73         return;
 74     }
 75 
 76     /* create application task */
 77     bt_app_task_start_up();
 78 
 79     /* Bluetooth device name, connection mode and profile set up */
 80     bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
 81 }
 82 
 83 
 84 static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
 85 {
 86     ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
 87     switch (event) {
 88     case BT_APP_EVT_STACK_UP: {
 89         /* set up device name */
 90         char *dev_name = "ESP_SPEAKER";
 91         esp_bt_dev_set_device_name(dev_name);
 92 
 93         /* initialize A2DP sink */
 94         esp_a2d_register_callback(&bt_app_a2d_cb);
 95         esp_a2d_register_data_callback(bt_app_a2d_data_cb);
 96         esp_a2d_sink_init();
 97 
 98         /* initialize AVRCP controller */
 99         esp_avrc_ct_init();
100         esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
101 
102         /* set discoverable and connectable mode, wait to be connected */
103         esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
104         break;
105     }
106     default:
107         ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
108         break;
109     }
110 }

这里文件按的内容并不是最重要的,贴出这篇文档是为了由此学习一份好的程序的大致样式,从这篇文章可以可看出文件基本的书写样式如下:

/*************************************************************************
*    版权所有 (C)2013,公司(或个人)名称。
*    公司网站或个人联系方式
*    文件名称:
*    内容摘要:
*    其他说明:
*    作者:
*    完成日期:
*
*    修改记录1:
*        修改日期:
*        版本号:
*        修改人:
*        修改内容:
*
*
*
**************************************************************************/
#include 'XXX.h'        //自写的.h文件最好加备注




#ifdef _XXX_H            //防止头文件被重复引用
#define _XXXX_H
#endif

/*************************************************************************
                        变量及相关宏定义
**************************************************************************/



/*************************************************************************
                        相关结构体定义
**************************************************************************/


/*************************************************************************
                        源程序中出现的函数声明
**************************************************************************/

/*************毫无疑问,上面声明部分的变量结构体和函数等最好进行相关注释**********/


//相关main函数实现功能说明
void main(void)
{
    //main函数内除了函数的调用尽量少的涉及无关操作,这样可以保持程序的整洁性,并保持系统逻辑性
}

这里,可以看到对程序进行了严格的排版操作,这样,对于程序的阅读和修改都提供了良好的代码环境,这个部分从小的项目开始训练是最好的,开始可能感觉不到什么用处,但是当做到大型项目的时候,可以明显感觉到这种做法为程序编程提供了很大的便利。

posted @ 2017-10-13 10:26  noticeable  阅读(524)  评论(0)    收藏  举报