变量的声明和定义以及extern的用法
                                        
变量的声明不同于变量的定义,这一点往往容易让人混淆。
l         变量的声明是告诉编译器,该变量名称已经存在,编译器认识这个名字,不会引起编译错误。
l         对变量进行定义之后,编译器就会给变量分配空间,链接时,链接器可以找到它们的地址。
在程序代码组织过程中,人们往往把变量的声明放在头文件中,而把变量的定义放在源文件中,如下面的例子所示(该例子在VC6.0中编译、链接通过):
file1.h
/////////////////////////////////////////////////////
// 文件名:file1.h
// 该文档用来测试extern的用法
// extern表示外部声明一个变量
// 声明一个变量就是告诉编译器,这个变量名已经存在
// 但是没有给它分配空间。也就是说,声明了一个变量
// 如果程序中引用了该变量,能够通过编译,但是,
// 如果没有在某个文件中定义该变量的话,则链接会出错
// 因为链接目标文件的时候,需要该变量的确切地址.
/////////////////////////////////////////////////////
 
#ifndef _FILE1_H
#define _FILE1_H
#include <iostream.h>
extern void FilePrint(int, int); //外部声明函数FilePrint
extern   m_nNum ;         //声明变量 m_nNum,常写成extern int m_nNum
 
#endif
 
file1.cpp
#include "file1.h"
 
int m_nNum = 1; //如果没有定义该变量,则main.cpp可以通过编译,但程序链接出错
void FilePrint(int a, int b)
{
 
       cout << "/n the num is " << a << "and the double is "
               << b <<endl;
       return;
}
 
main.cpp
#include "file1.h"
 
int main(int i, char b)
{
      
       cout << " the first parm is "<< i
               << " and the second char is " << b <<endl;
       FilePrint( m_nNum, 2*m_nNum);
       return 0;
}
 
在头文件中,声明了函数FilePrint和变量m_nNum,在file1.cpp中定义了这两个变量。如果没有在file1.cpp中定义这两个变量,那么,main.cpp可以通过编译,但是程序链接会出错。
变量的声明和定义往往不容易分清,很多时候声明的同时就定义了。如上例所示,如果没有在头文件file1.h中声明m_nNum,也没有在file1.cpp中定义,而是在main.cpp文件中声明全局变量:
int m_nNum;//声明的同时定义,编译器给该变量分配了空间
int main(int i, char b)
{
              m_nNum = 1;
              cout << " the first parm is "<< i
                      << " and the second char is " << b <<endl;
              FilePrint( m_nNum, 2*m_nNum);
              return 0;
}
函数的声明和定义比较容易区分。声明的时候不用写函数体,只需要确定函数名和参数就可以了;函数的定义需要函数体的实现。
如:void FilePrint(int, int) 告诉编译器函数FilePrint已经声明,它有两个int型的输入参数,在声明中,可以不写出形参的名称。
而 void FilePrint(int a, int b) { }表示函数已经定义,尽管它是一个空函数。
 
extern 关键字
extern 告诉编译器,该变量是在外部定义的,在本例中,当编译器对mail.cpp进行编译时,它告诉编译器,m_nNum和FilePrint是在其它文件 (file1.cpp)中定义的,链接的时候再到其它obj文件中寻找它们的地址。对于编译器来说,extern 告诉了它变量的名字。如在头文件file1.h中,只需要写成extern m_nNum 就可以了(当然也可以写成extern int m_nNum)。
另外要注意,并不是所有的变量都能够用extern 声明,只有全局非静态变量才能声明为extern。
如在file1.cpp中,static int m_nNum,编译会出错。

变量的声明和定义以及extern的用法的更多相关文章

  1. 【转】变量的声明和定义,从C到编译原理到C++,再到Java

    基础学了太久,时间一长有些东西就可能记得不太清楚,俗话说得好,"好记性不如烂笔头",所以把基础中的基础-变量的声明和定义,从C到编译原理到C++,再到Java用烂笔头记录下来 最早 ...

  2. JAVA学习笔记:注释、变量的声明和定义、

    本文内容: 注释 变量的声明和定义 成员变量和局部变量 首发时间:2018-03-16 15:59 注释: 单行注释:// 多行注释:/* - */ 变量: 变量是内存中的一个存储区域,变量的定义就是 ...

  3. 变量声明和定义及extern 转载

    在讨论全局变量之前我们先要明白几个基本的概念: 1. 编译单元(模块):    在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LINK ER ...

  4. C++ 变量的声明与定义的区别

    变量声明和定义的区别 我们在程序设计中,时时刻刻都用到变量的定义和变量的声明,可有些时候我们对这个概念不是很清楚,知道它是怎么用,但却不知是怎么一会事,下面我就简单的把他们的区别介绍如下:(望我的指点 ...

  5. 【C++】C++中变量的声明与定义的区别

    声明(declaration):意味着告诉编译器关于变量名称.变量类型.变量大小.函数名称.结构名称.大小等等信息,并且在声明阶段不会给变量分配任何的内存. 定义(definition):定义就是在变 ...

  6. C++变量的声明和定义

    1.变量的定义:变量的定义用于为变量分配存储控件,还可以为变量指定初始值.在一个程序中,变量有且仅有一个定义. 2.变量的声明:用于向程序表名变量的类型和名字.程序中变量可以声明多次,但只能定义一次. ...

  7. C:变量的声明与定义

    声明变量不需要建立存储空间,如:extern int a; 定义变量需要建立存储空间,如:int b; #include <stdio.h> int main() { //extern 关 ...

  8. Java变量常量声明和定义

    一.常量和变量 1.常量变量定义 在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量. 2 ...

  9. C语言函数及变量的声明与定义的区别

    变量: 1.声明变量不需要建立存储空间,如:extern int a; 2.定义变量需要建立存储空间,如:int a:或者 int b=10:无论变量是否赋值,只要定义它,即占用空间. 3.int a ...

随机推荐

  1. CodeForces 432C Prime Swaps

    Description You have an array a[1], a[2], ..., a[n], containing distinct integers from 1 to n. Your ...

  2. redis 介绍和常用命令

    redis 介绍和常用命令 redis简介 Redis 是一款开源的,基于 BSD 许可的,高级键值 (key-value) 缓存 (cache) 和存储 (store) 系统.由于 Redis 的键 ...

  3. 浅谈JS的继承

    JS继承 继承是OO语言中最为人津津乐道的概念,许多OO语言都支持两种方式的继承:接口继承:实现继承. 接口继承:只继承方法签名. 实现继承:继承实际的方法. 由于ES里函数没有签名,所以在ES里面无 ...

  4. 使用javaconfig配置freemarker

    package com.yy.config; import org.springframework.context.annotation.Bean; import org.springframewor ...

  5. css控制竖直文字显示

    假如有一天,你把水平文字看腻味了...... 我建议你不妨试试垂直文字显示,就像这样: 我 是 竖 直 显 示 的 : 哈哈! 言归正传,怎么把一段话,垂直显示呢? 方法1: //把下面代码另存为ht ...

  6. linux下操作mysql

    有关mysql数据库方面的操作,必须首先登录到mysql中. 开启MySQL服务后,使用MySQL命令可以登录.一般使用mysql -uroot -p即可.如果数据库不是本机,则需要加参数,常用参数如 ...

  7. python爬虫scrapy框架——人工识别知乎登录知乎倒立文字验证码和数字英文验证码

    目前知乎使用了点击图中倒立文字的验证码: 用户需要点击图中倒立的文字才能登录. 这个给爬虫带来了一定难度,但并非无法解决,经过一天的耐心查询,终于可以人工识别验证码并达到登录成功状态,下文将和大家一一 ...

  8. Stylus-NodeJS下构建更富表现力/动态/健壮的CSS

    --------------------------本文来自张鑫旭大神博客------------------------------ 一.为什么我会讲Stylus,而不是SASS和LESS? SAS ...

  9. 利用Java调用OpenCV进行人脸识别

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt409 今天我准备学习如何用Java来进行人脸检测.人脸检测有助于在任何数字图 ...

  10. 如何使用EF优雅的配置一对一的关系

    在这两天的时间已经有两位同事问到EF(Code First)如何配置一对一的关系,这个说难也不难,说简单吧,一旦设计跑偏那么在Coding的过程中将会很痛苦. 先举个很简单的例子,两个类User和Pr ...