zoukankan      html  css  js  c++  java
  • 由液晶字库的存放位置想到的

      当我们在做12864液晶的字库时,常常将一个汉字取模后,保存到一个数组中,如在zimo.h中,有:

      char zimo[]={
      /*-- 文字: 格 20--*/
      /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
      0x10,0x80,0x10,0x80,0x11,0xF8,0xFD,0x08,0x12,0x90,0x34,0x50,0x38,0x20,0x54,0xD8,
      0x57,0x06,0x91,0xF8,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0xF8,0x11,0x08};

      由于该处对数组zimo[]进行了初始化,因此此处是数组的定义,而不是声明

      当几个不同的源文件分别包含这个.h文件时,编译就会出现重复定义的错误,一般的解决办法有如下两种:

    方法1:规范模块化

      在我的前一篇文章《C代码与工程的规范》,已经介绍了关于模块化的文件组织,在这里,我们可以将该数组在一个.c文件中进行定义:

         /*    zimo.c     */
    
          char zimo[32]={
        /*-- 文字: 格 20--*/
        /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
        0x10,0x80,0x10,0x80,0x11,0xF8,0xFD,0x08,0x12,0x90,0x34,0x50,0x38,0x20,0x54,0xD8,
        0x57,0x06,0x91,0xF8,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0xF8,0x11,0x08};

      然后为该.c文件配置一个.h文件,对该数组进行全局性声明,内容如下: 

    /*    zimo.h     */
    
        extern char zimo[32];

      这样我们在使用该数组时,只需要包含zimo.h,就不会出现重复定义的错误;

    方法2:利用static进行声明;

      如果MCU系统的静态存储区较大,可以使用static定义该数组,此时只使用一个.h文件即可。但是这个方法个人不推荐!

          在zimo.h中,定义数组如下: 

    /*    zimo.h     */
    static char zimo[32]={
        /*-- 文字: 格 20--*/
        /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
        0x10,0x80,0x10,0x80,0x11,0xF8,0xFD,0x08,0x12,0x90,0x34,0x50,0x38,0x20,0x54,0xD8,
        0x57,0x06,0x91,0xF8,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0xF8,0x11,0x08};

      在.h文件中,出现static关键字意味着什么呢?

      我们知道,static关键字的作用之一是声明变量为本地变量,当A.c中,包含了zimo.h时,就相当于在A.c中定义了一个static型的数组,暂且称之为T1,它的作用范围仅限于A.c;

      同时,当B.c也包含了zimo.h时,也相当于在B.c中定义了一个static型的数组,称它为T2,它的作用范围仅限于B.c;

      两个数组T1、T2虽然重名,都叫zimo[],但是由于static的修饰,它们是互不影响的,等同于在内存空间中开辟了两块空间,分别用于保存T1和T2。这样就解决了重复定义的问题。但是弊端十分明显,就是包含了N次zimo.h,这个数组就新定义了N次,就浪费了N倍的存储空间。同时,在.h文件中出现实质性的定义,也不符合模块化编程的指导思想。

    另附:这里附上我曾经看过的一篇文章,《在头文件中使用static意味着什么》,现将内容修改和整理如下,可以加深对static的作用的理解。

      首先,在一个头文件中,用static定义一个变量:

    /*   Header.h   */
    static int g_int = 3;

      其次,新建两个源文件,都包含“Header.h”:

    /*   Source1.c   */
    #include <stdio.h>
    #include "Header.h"
    
    void Test1() 
    {
      g_int = 5;
      
      printf("g_int's address in Source1.c: %d\n", &g_int);     /*打印source1.c中g_int的地址*/
      printf("g_int's value in Source1.c: %d\n", g_int);       /*打印source1.c中g_int的值*/
    }
    /*   Source2.c   */
    #include <stdio.h>
    #include "Header.h"
    void Test2()
     {
      g_int = 3;
      printf("g_int's address in Source2.c: %d\n", &g_int);    /*打印source2.c中g_int的地址*/ 
      printf(
    "g_int's value in Source2.c: %d\n", g_int);     /*打印source2.c中g_int的值*/
    }

    然后在main函数中,调用这两个测试函数:

    1 /*    Main.c   */   
    2 #include "Test1.h"
    3 #include "Test2.h"
    4 
    5 void main(void) 
    6 {
    7     Test1();
    8     Test2();
    9 }

    得到的输出结果如下:

      可以看到,两个源文件中的g_int的地址和值都是不同的,说明它们即使同名,但它们是互不影响的完全不同的两个变量。这就是static本地化的作用。这种声明全局变量的做法十分的不科学,应该禁止使用。

      作为对比,下面给出正确的使用全局变量的方法:

    /*    Header.h      */
    extern int g_int;      /*全局变量的声明*/
    /*    Header.c    */
    int g_int = 0;     /*全局变量的定义*/
    /*   Source1.c   */
    #include <stdio.h>
    #include "Header.h"
    void Test1() 
    {
      g_int = 5;
        printf("g_int's address in Source1.c: %d\n", &g_int);
      printf("g_int's value in Source1.c: %d\n", g_int);
    }
    /*   Source2.c   */
    #include <stdio.h>
    #include "Header.h"
    void Test1() 
    {
      g_int = 5;
        printf("g_int's address in Source2.c: %d\n", &g_int);
      printf("g_int's value in Source2.c: %d\n", g_int);
    }
    1 /*    Main.c   */   
    2 #include "Test1.h"
    3 #include "Test2.h"
    4 
    5 void main(void) 
    6 {
    7     Test1();
    8     Test2();
    9 }

    运行后,得到结果如下:

    可见,两个源文件使用的是同一变量。

      

  • 相关阅读:
    一些必不可少的Sublime Text 2插件
    sublime text 使用小技巧
    Azure Queue 和 Service Bus Queue的比较
    怎么使用Windows Azure Queue Storage 服务
    配置 SharePoint 2010 使用本机默认 SQL Server 实例 Pan
    将两个字符串中相同的地方str2无重复的输出
    javascript笔记
    C#中怎样使控件随着窗体一起变化大小(拷来学习)
    在pictureBox中画方格矩阵地图,方法比较笨,有好方法望指导
    通过一个小推理写出的程序,结果出乎意料……有哪位知道为什么吗 已解决
  • 原文地址:https://www.cnblogs.com/BitArt/p/2794518.html
Copyright © 2011-2022 走看看