(二十一)QT专题-全局变量和全局函数

C++允许声明一些不属于任何类的函数和变量,并且这些函数和变量可以被其他的任意函数访问。我们已经看到了多个全局函数的例子,包括作为程序入口的main()函数。全局变量还没有看到几个,因为它们需要在程序的模块和线程之间来回重复以求取折中。但理解它们还是很重要的。因为你可能在那些C程序员高手和其他的C++用户那里遇到它们。
为了能够举例说明全局函数和全局变量是如何工作,我们将会从研究一个小程序开始,该程序使用quick-and-dirty算法打印一个由128个伪随机数构成的列表。这个程序的源代码放在两个.cpp文件中。
第一个.cpp文件的源文件是random.cpp:

int randomNumbers[128];
static int seed = 42;
static int nextRandomNumber()
{
  seed = 1009 +  (seed * 2011);
  return seed;
}

void populateRandomArray()
{
  for(int i = 0; i < 128; i++)
 {
    randomNumbers[i] = nextRandomNumber();
 }
}

这个文件声明了两个全局变量(randomNumbers和seed)和两个全局函数[nextrandomNumber()和populateRandomArray()]。其中的两个声明包含了关键字static,这样的声明只有在当前编译单元(random.cpp)中才是可见的,可以把这种情况称为静态连接(static linkage)。其他两个则可以从程序的任意编译单元中访问,可以把这种情况称为外部连接(external linkage)。
静态连接非常适合用于那些不需要在其他编译单元中使用的帮助函数和内部变量。它可以降低标识符(具有同样名字的全局变量或者是在不同编译单元中具有同样署名的全局函数)冲突的风险,并且可以防止那些不怀好意或者是考虑不成熟的用户访问一个编译单元的内部。
现在,让我们一起来看一看第二个文件,main.cpp,它使用了在random.cpp文件中用外部连接声明的两个全局变量:

#include <iostream>
extern int randomNumber[128];

void populateRandomArray();
int main()
{
  populateRandomArray();
  for(int i = 0; i < 128; i++)
  {
    std::cout<<randomNumbers[i] <<std::endl;
  }
  return 0;
}

在调用外部变量和函数之前,需要先声明它们。对randomNumbers的外部变量声明(可以让一个外部变量在当前编译单元中可见)以extern关键字开始。没有extern,编译器就会认为它需要处理的是一个不确定的定义,这样就会导致连接器报错,因为同一变量同时在两个编译单元(random.cpp和main.cpp)中都被定义了。只要需要,可以任意多次地声明变量,但是只能定义它们一次。定义(definition)就是让编译器为该变量保留内存空间。
populateRandomArray()函数是通过使用函数原型来声明的。对于函数,extern关键字是可有可无的。
通常情况下,会把external变量和函数声明放在头文件中,并且把该文件在所有需要它们的文件中包含一次:

#ifndef RANDOM_H
#define RANDOM_H

extern int randomNumbers[128];
void populateRandomArray();

#endif

我们已经看到了如何使用static来声明一些不属于任何一个类实例的成员变量和成员函数,并且现在也已经看到了如何使用它来声明静态连接的函数和变量。static关键字还有另外一种用法不能忘记。在C++中,可以声明一个局部静态变量(local static variable)。这样的变量会在第一次调用函数的时候得到初始化,并且会在两个函数调用时保留它们的值。例如:

void nextPrime()
{
  static int n = 1;
  do
  {
    n++;
  }while(!isPrime(n));
  return n;
}

局部静态变量除了只能在定义它们的函数中可见之外,在其他方面,它们都与全局变量一样。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,809评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,189评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,290评论 0 359
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,399评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,425评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,116评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,710评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,629评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,155评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,261评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,399评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,068评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,758评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,252评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,381评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,747评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,402评论 2 358

推荐阅读更多精彩内容