• 头文件定义全局变量的几个问题


    工程中有三个文件如下:main.cpp,Calc1.h和Calc1.cpp.内容如下:

    //****************mian文件的内容******************************//

    //---------------------------------------------------------------------------

    #include <vcl.h>

    #pragma hdrstop

    #include "Calc1.h"

    #include "main.h"

    //---------------------------------------------------------------------------

    #pragma package(smart_init)

    #pragma resource "*.dfm"

    TForm1 *Form1;

    double temp;

    //---------------------------------------------------------------------------

    __fastcall TForm1::TForm1(TComponent*Owner)

             :TForm(Owner)

    {

    }

    //---------------------------------------------------------------------------

    void __fastcallTForm1::Button1Click(TObject *Sender)

    {

             change();

             Label2->Caption=FloatToStr(a);

             Label3->Caption=FloatToStr(b);

             temp=chu();

             Label1->Caption=FloatToStr(temp);

             Label4->Caption=FloatToStr(display());

    }

    //---------------------------------------------------------------------------

    //本文地址:http://hi.baidu.com/phykingpeng/blog/item/7dd099226168c3844723e86e.html

    //************************Calc1.h的内容*******************************//

    /*#ifndef __CALC1__H__

    #define __CALC1__H__  */

    double a,b;

    double chu();//double,double);

    void change();

    double display();

    //#endif      //  __TEMP__H__

    //************************Calc1.cpp的内容*******************************//

    #include "main.h"

    #include "Calc1.h"

    //extern double a,b;

    /*

    这里用#include "Calc1.h"后第一次编译会报错(有warning,

    [BCC32 Warning] Calc1.h(3): W8058 Cannotcreate pre-compiled header: initialized data in header),之后编译有下面这个警告

    [ILINK32 Warning] Warning: Public symbol'_a' defined in both module DEBUG\CALC1.OBJ and \DEBUG\UNIT1.OBJ

    但是访问的值感觉是二个不同的值(表面上同名实际上是两个值)

    */

    void change()

    {

             a=StrToFloat(Form1->Edit1->Text);

             b=StrToFloat(Form1->Edit2->Text);

    }

    double chu()//double i,double j)

    {

             return(b/a);//i/j;

    }

    double display()

    {

             returna;

    }

    分析:Calc1.h无论用不用宏定义,编译的时候都会有[ILINK32 Warning] Warning: Public symbol '_a' defined in both module..\RAD STUDIO\PROJECTS\多文件\DEBUG\MAIN.OBJ and ..\RAD STUDIO\PROJECTS\多文件\DEBUG\CALC1.OBJ这个警告。原因是工程中含有两个CPP文件,编译器分别讲Calc1.h插入到main.cpp和Calc.cpp对应的位子,编译成对应的两个.OBJ文件(MAIN.OBJ和CALC1.OBJ)。这样在link的时候,两个OBJ中就分别有一份a,b的定义,连接的时候就有重复定义的warning。实际运行的时候Calc1.cpp中三个函数调用的是自己文件中定义的a,b。main.cpp中调用的是全局的a,b(Label2->Caption=FloatToStr(a);)这里相当于有个全局的a,b和一个局部的a,b。所以同样使用两个参数得出的结果却不一样lable2和Label3为0(全局),Label4为edit中的a值(Edit1->Text);)(局部)label1输出除法为edit控件保存到局部变量中的计算值。


    总结:1. #include中定义全局变量用宏定义,就像上面Calc1.h注释掉的那样。但是引用的时候包含只能一次,其他文件中应该以extern声明,像Calc1.cpp中注释掉的那样//extern double a,b;。不要用#include "Calc1.h"包含头文件,否则就会出现上面的局部和全局变量重名,访问的不一致的问题。有说法是最好不要再头文件中定义变量,有一定的道理。

    2.注意编译的过程:#include是完全复制被包含的文件到这一行,工程中的多个CPP文件分别编译成不同的OBJ,再连接成exe.

    3.宏定义是用来避免重复包含的,比如多个文件有重叠包含关系。有全局变量的头文件只被主程序包含,其他文件中用extern。

  • 相关阅读:
    【转载】mysql dual 虚拟表
    Mysql中DATE_SUB函数
    mybatis中<include>标签的作用
    IDEA提升幸福感的小技巧之"快速从controller跳转到serviceImpl"
    MySQL一些常用的时间函数 current_timestamp()
    SpringCloud配置中心搭建与使用(本地存储配置)
    Linux内存管理 (7)VMA操作【转】
    linux下的调试工具ltrace与strace【转】
    (十四)Linux内存管理之page fault处理【转】
    Linux系统调用详解(实现机制分析)--linux内核剖析(六)【转】
  • 原文地址:https://www.cnblogs.com/phyking/p/4456667.html
Copyright © 2020-2023  润新知