注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

何静媛 勇往直前

学无止境!

 
 
 

日志

 
 
 
 

转载:变量——声明与定义  

2012-08-13 21:10:34|  分类: 转载日志 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
我们在程序设计中,时时刻刻都用到变量的定义和变量的声明,可有些时候我们对这个概念不是很清楚,知道它是怎么用,但却不知是怎么一会事,下面我就简单的把他们的区别介绍如下:
    变量的声明有两种情况:
    (1) 一种是需要建立存储空间的(定义、声明)。例如:int a在声明的时候就已经建立了存储空间。 
    (2) 另一种是不需要建立存储空间的(声明)。例如:extern int a其中变量a是在别的文件中定义的。
    前者是"定义性声明(defining declaration)"或者称为"定义(definition)",而后者是"引用性声明(referncing declaration)"。从广义的角度来讲声明中包含着定义,但是并非所有的声明都是定义,例如:int a它既是声明,同时又是定义。然而对于extern a来讲它只是声明不是定义。一般的情况下我们常常这样叙述,把建立空间的声明称之为"定义",而把不需要建立存储空间称之为"声明"。很明显我们在这里指的声明是范围比较窄的,也就是说非定义性质的声明。
例如:在主函数中 
int main()
{
    extern int A; //这是个声明而不是定义,声明A是一个已经定义了的外部变量
                  //注意:声明外部变量时可以把变量类型去掉如:extern A;
    dosth();      //执行函数
}
int A;            //是定义,定义了A为整型的外部变量(全局变量) 
    外部变量(全局变量)的"定义"与外部变量的"声明"是不相同的,外部变量的定义只能有一次,它的位置是在所有函数之外,而同一个文件中的外部变量声明可以是多次的,它可以在函数之内(哪个函数要用就在那个函数中声明)也可以在函数之外(在外部变量的定义点之前)。系统会根据外部变量的定义(而不是根据外部变量的声明)分配存储空间的。对于外部变量来讲,初始化只能是在"定义"中进行,而不是在"声明"中。所谓的"声明",其作用,是声明该变量是一个已在后面定义过的外部变量,仅仅是在为了"提前"引用该变量而作的"声明"而已。extern只作声明,不作定义。 
    用static来声明一个变量的作用有二:
    (1) 对于局部变量用static声明,则是为该变量分配的空间在整个程序的执行期内都始终存在
    (2) 外部变量用static来声明,则该变量的作用只限于本文件模块
《转自》 http://www.cnblogs.com/wangliang651/archive/2009/04/06/1430098.html
变量的声明和定义以及extern的用法
                                         
变量的声明不同于变量的定义,这一点往往容易让人混淆。
        变量的声明是告诉编译器,该变量名称已经存在,编译器认识这个名字,不会引起编译错误。
        对变量进行定义之后,编译器就会给变量分配空间,链接时,链接器可以找到它们的地址。
在程序代码组织过程中,人们往往把变量的声明放在头文件中,而把变量的定义放在源文件中,如下面的例子所示(该例子在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,编译会出错。
《转自》 http://blog.pfan.cn/12567/26210.html

一、变量
在将变量前,先解释一下声明和定义这两个概念。声明一个变量意味着向编译器描述变量的类型,但并不为变量分配存储空间。定义一个变量意味着在声明变量的同时还要为变量分配存储空间。在定义一个变量的同时还可以对变量进行初始化。
局部变量通常只定义不声明,而全局变量多在源文件中定义,在头文件中声明。
局部变量
在一个函数的内部定义的变量是内部变量,它只在本函数范围内有效。
自动变量auto
函数中的局部变量,其缺省格式是自动变量类型。例如,在函数体中int b, c=3; 和auto int b, c=3; 是等价的。
自动变量是动态分配存储空间的,函数结束后就释放。自动变量如不赋初值,则它的值是一个不确定的值。
静态局部变量static
静态局部变量是指在函数体内声明和定义的局部变量,它仅供本函数使用,即其他函数不能调用它。静态局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次函数调用时,该变量已有值,就是上一次函数调用结束时的值。
静态局部变量在静态存储区分配存储单元,在程序的整个运行期间都不释放。静态局部变量是在编译时赋初值的,即只赋初值一次。
在SDT编译器中,建议对静态局部变量赋初值,否则该静态局部变量的初值为不确定值。在其他编译器中,未初始化的静态局部变量的初值可能为零,这由具体的编译器所决定,使用前最好测试一下。
寄存器变量register
带register修饰符的变量暗示(仅仅是暗示而不是命令)编译程序本变量将被频繁使用,如果可能的话,应将其保留在CPU的寄存器中,以加快其存取速度。
对于现有的大多数编译程序,最好不要使用register修饰符。因为它是对早期低效的C编译程序的一个很有价值的补充。随着编译程序技术的进步,在决定哪些变量应当被存到寄存器中时,现在的C编译程序能比程序员做出更好的决定。
全局变量
在函数之外定义的变量称为外部变量,外部变量是全局变量,它可以为本文件中其他函数所共用。全局变量都是静态存储方式,都是在编译时分配内存,但是作用范围有所不同。
静态外部变量static
静态外部变量只能在本文件中使用。所以静态外部变量应该在当前源文件中声明和定义。
外部变量extern
定义函数中的全局变量时,其缺省格式是外部变量类型。外部变量应该在一个头文件中声明,在当前源文件中定义。外部变量允许其他文件引用。
下例声明了一个变量和一个结构,定义了两个变量,其中一个定义带初始化:
extern int   decl1;   // this is a declaration

struct decl2
{
   int member;
};       // this just declares the type – no variable mentioned

int     def1 = 8;   // this is a definition

int     def2;   // this is a definition
二、函数
内部函数的声明和定义多在当前源文件中完成;而外部函数通常在源文件中定义,在头文件中声明。
内部函数
只在当前源文件中使用的函数应该说明为内部函数。内部函数应该在当前源文件中声明和定义。若内部函数在头文件中声明,其他源文件通过包含这个头文件也可使用这个函数,但这样就失去了其做为内部函数的意义。
优点:使用内部函数,可以使函数只局限于所在文件。这避免了与其他源文件中可能出现的同名函数发生冲突。
例:
File: function1.c
#include “function1.h”
static int stat_func(void);

void MasterFunction(void)
{

rc = stat_func( );

}

static int stat_func(void)
{
   …
   return rc;
}

外部函数
对于可在当前源文件以外使用的函数,应该在一个头文件中声明。其他源文件可通过包含这个头文件或进行声明来使用这些函数(推荐用前者)。
一个良好的编程习惯是在头文件中声明函数的原型。这可方便编译程序查错。定义函数时,缺省的函数类型是外部函数。如:void fun2(void); 和extern void fun2(void); 其函数类型是等价的,但前一个是定义函数,后一个是声明函数。
小结
编写程序,尤其是大型程序时,建议采用上文所述的方法对不同的变量、函数进行必要的声明、定义。做好这些细节上的事务,可以为您的编程、调试、移植等带来很大的方便。


《转自》 http://blog.csdn.net/xuefu2008/article/details/4644665
  评论这张
 
阅读(144)| 评论(6)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017