zoukankan      html  css  js  c++  java
  • 转载:全局变量使用

    https://www.cnblogs.com/wanghetao/p/4492582.html

    1. 用extern修饰的全局变量
        以上已经说了extern的作用,下面我们来举个例子,如:
        在test1.h中有下列声明:
        #ifndef TEST1H
        #define TEST1H
        extern char g_str[]; // 声明全局变量g_str
        void fun1();
        #endif
        在test1.cpp中
        #include "test1.h"
       
        char g_str[] = "123456"; // 定义全局变量g_str
       
        void fun1()
        {
            cout << g_str << endl;
        }
       
        以上是test1模块, 它的编译和连接都可以通过,如果我们还有test2模块也想使用g_str,只需要在原文件中引用就可以了
        #include "test1.h"

        void fun2()
        {
            cout << g_str << endl;
        }
        以上test1和test2可以同时编译连接通过,如果你感兴趣的话可以用ultraEdit打开test1.obj,你可以在里面着"123456"这 个字符串,但是你却不能在test2.obj里面找到,这是因为g_str是整个工程的全局变量,在内存中只存在一份, test2.obj这个编译单元不需要再有一份了,不然会在连接时报告重复定义这个错误!
        有些人喜欢把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如把上面test1.h改为
        extern char g_str[] = "123456"; // 这个时候相当于没有extern
        然后把test1.cpp中的g_str的定义去掉,这个时候再编译连接test1和test2两个模块时,会报连接错误,这是因为你把全局变量 g_str的定义放在了头文件之后,test1.cpp这个模块包含了test1.h所以定义了一次g_str,而 test2.cpp也包含了test1.h所以再一次定义了g_str, 这个时候连接器在连接test1和test2时发现两个g_str。如果你非要把g_str的定义放在test1.h中的话,那么就把test2的代码 中#include "test1.h"去掉 换成:
        extern char g_str[];
        void fun2()
        {
            cout << g_str << endl;
        }
        这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,但是我想说这样做非常糟糕,因为你由于无法在 test2.cpp中使用#include "test1.h", 那么test1.h中声明的其他函数你也无法使用了,除非也用都用extern修饰,这样的话你光声明的函数就要一大串,而且头文件的作用就是要给外部提 供接口使用的,所以 请记住, 只在头文件中做声明,真理总是这么简单。

  • 相关阅读:
    C#将List<T>转化为DataTable
    SqlServer常用内置函数
    C#索引器
    验证Textbox的字符长度
    WM消息对应的Message消息中的Lparam和WParam
    对窗体操作的WM消息
    DllImport使用
    C#获取当前路径的七种方法
    注册ActiveX控件
    [转]VS2010中水晶报表安装应用及实例
  • 原文地址:https://www.cnblogs.com/rainsoul/p/10001691.html
Copyright © 2011-2022 走看看