声明和定义,文件保护符,extern

声明和定义以前关注的不够,导致文件保护符和extern理解不上去。这里先整理一下。

知识点:(变量可以被声明很多次,但是只能定义一次

所以我们就很有必要知道哪些是定义式哪些是声明式


声明式:

</pre><pre name="code" class="cpp"><span style="font-size:18px;">extern int x;//对象声明式

int num(int number);//函数声明式

class Widget;//类声明式

template<typename T>
class Graph;//模板声明式
</span>

定义式
<span style="font-size:18px;">int x;//对象的定义式</span>
函数,类,模板的定义式很容易理解


简单了解extern(英语翻译为“外来的”,“外面的”很贴切)

extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示 编译器遇到此变量或函数时,在其它模块中寻找其定义。另外,extern也可用来进行链接指定。(百度词条)
1.extern可以用于变量声明,如声明式
2.extern和const:如果想在多个文件之间共享const常量,必须在常量定义式前添加extern。
extern const int  a =10;//定义式
    extern const int a;//声明式
我的理解: 现代 编译器 一般采用按文件(.cpp)编译的方式,因此在编译时,各个文件中定义的 全局变量 是互相不透明的。也就是说,在编译时,全局变量的可见域限制在文件内部。如果我们想在一个(.cpp或.h)文件里用一个其他文件里定义的变量时,我们不能直接使用(我们知道这个变量在其他文件里定义了,但是编译器却不知道),这时候如果我们再次定义该变量就会出现重复定义,编译器报错。这时候就需要用到extern声明一个变量,告诉编译器“你给我放行,不要报错,我在其它文件里已经定义了这个变量”,然后就可以直接使用它。

头文件保护符
http://www.2cto.com/kf/201212/176881.html//这里说的比较细

这里只说一下 #ifdef 当且仅当预处理变量已定义时为真。#ifndef 当且仅当预处理变量未定义时为真。 #endif
用法如下,可以防止重复包含的发生。(我在一个.cpp里#include了head.h,如果我在其他.cpp里也包含了head.h,如果head.h里定义了一个变量或其它什么且没有采用头文件保护符,则重复包含就导致了重复定义,编译器肯定报错)
//head.h
#ifndef  HEAD_H      
#define  HEAD_H
#include <string>
 ...
#endif 

在学习期间看到一个很有意思的问题
看到一个公司的编程规则:“禁止在头文件里定义变量”,因为在头文件里定义变量,若被其它.C文件包含会导致变量重复定义。不是有#ifndef 、#define和#endif来防止重复包含吗?怎么会重复定义呢?在C++类的头文件中都定义了变量,照这样说的话,岂不是都重复定义了?我有些迷茫了,望大虾指点迷津。 http://bbs.csdn.net/topics/380170629
我的解答: #ifndef 、#define和#endif防止的是相同头文件的重复。(比如说,多次调用了head.h,文件保护符就避免了head中变量的重复定义),而公司规则“禁止在头文件里定义变量”是因为一个项目可能是由不同人写的,甲在头文件1里定义了变量a,而乙在头文件2里也定义了变量a,如果两人的a都是全局变量的话,重复定义就发生了。
重复定义发生的情况应该是在一个编译单元里。比如重复包含head.h是指:head1里有#include "head.h",那么,在haed2这个编译单元里如果有#include "head.h" 和#include "head1.h",则在head2这个编译单元中重复包含了两次head.h,如果没有头文件保护符,则可能会发生重复定义。
第二中情况,如果head1.h里定义了一个全局变量a,那么当head这个编译单元有#include "head1.h"并且也定义了个全局变量a,怎会发生重复定义。




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值