编译单元

编译分为两个步骤:

第一步:将每个.cpp或.c和相应的.h文件编译乘obj文件(包含预编译,汇编、编译)

第二部:将obj文件进行Link,生成最终的可执行文件

根据该阶段错误大致可分为两类:

一个,编译时的错误,大多为语法错误

一个,链接时错误,主要是变量、函数定义错误

编译单元指在编译阶段生成的每个obj文件

一个obj文件就是一个编译单元

一个.cpp或.c和它相应的.h文件共同组成了一个编译单元

一个由很多编译单元组成,每个obj文件里包含了变量存储的相对地址等

声明和定义

函数或变量在声明时,并不给它分配实际的物理内存空间,他有时候可以保证程序编译通过

函数或变量在定义时,它就在内存中有了实际的物理空间

如果在编译单元中引用的外部变量没有在整个工程中任何一个地方定义的话,那么即使它在编译时可以通过,链接时也会报错,因为程序内存中找不到这个变量

函数可以声明多次,但是只能定义一次

extern作用

作用1,当与“C”一起使用时,如 extern "C" void fun(int a, int b),则编译器中fun这个函数名按照c语言规则命名,而不是用c++规定命名。故C++中可以利用该法则调用c函数

作用2,当他不与“C"在一起修饰变量或者函数时,如在头文件中,extern int g_Num;其作用就是声明函数或者变量的作用范围的关键字,其声明的函数和变量可以在本编译单元或者其他编译单元使用

即b编译单元要引用A编译的单元的全局变量或者函数时,b编译单元只要包含a编译单元的头文件即可,在编译阶段,b编译单元虽然找不到该函数或变量,但是不会报错,他会在链接时从A编译单元的目标文件中找到该定义

全局变量(extern)

有两个类都需要使用共同的变量,这种变量就定义为全局变量。一般在头文件中声明,在cpp中定义,定义只能出现一次

静态全局变量(static)

使用static修饰的变量,不能用extern修饰。

static修饰的全局变量的声明与定义同时进行,即当你在头文件中是使用static声明了全局变量,同时也别定义了,

static修饰的全局变量的作用域只能是本身的编译单元内,不同编译单元的同名全局静态变量是没有关联的,占用的物理空间也是完全独立的

全局静态变量一般定义在.cpp中

全局常量(const)

const单独使用时,其特性与static一样(每个编译单元中地址都不一样,不过因为是常量,也不能修改,所以就没有多大关系)

const与extern一起使用时,其特性与extern一样,但不能修改

C++全局变量的定义和声明的更多相关文章

  1. C语言全局变量的定义与声明

    C语言中全局变量的定义与声明困扰着许多C语言初学者.本文讲述了全局变量定义与声明的用法,而且本为也将阐述这种用法的内在原理.我们先从两个错误例子引入,以下两个例程都在vc6.0平台上测试. 两种错误例 ...

  2. 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法

    一.关于全局变量的定义.声明.引用: (只要是在.h文件中定义的变量,然后在main.c中包含该.h文件,那么定义的变量就可以在main函数中作为全局变量使用) 方法1: 在某个c文件里定义全局变量后 ...

  3. keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法

    以前写单片机程序时总是把所用函数和变量都写在一个c文件里,后来遇到大点的项目,程序动则几千行,这种方式无疑会带来N多麻烦,相信大家都有所体验吧! 后来学会了在keil里进行模块化编程,即只把功能相同或 ...

  4. QT中全局变量的定义

    多的就不说了,本来就是一个简单地内容,只是不会的话会很头疼 我们首先新建两个文件,文件名可以自定义,我们在这里定义为variate.h 和 variate.cpp 当然了,后缀是不能变的. 和函数一样 ...

  5. 定义与声明、头文件与extern总结

     用#include可以包含其他头文件中变量.函数的声明,为什么还要extern关键字? 如果我想引用一个全局变量或函数a,我只要直接在源文件中包含#include<xxx.h> (xxx ...

  6. sql 简单的定义变量 声明 输出

    --定义变量 声明 变量名 数据类型 varchar默认长度为1 --char 当字符不够时 用空格代替 declare @a char(10) --字符串用单引号 set @a ='abcdef' ...

  7. 定义与声明、头文件与extern总结(转)

    本文转自: http://lpy999.blog.163.com/blog/static/117372061201182051413310/ http://blog.csdn.net/feitianx ...

  8. 关于c++中的全局变量(不赋值的全局变量算定义)

    定义有三种: 1.不赋值的定义:int a; 2.赋值的定义:int a=5; 或者 int a;a=5; 3.加extern的定义:extern int a=5;//其实和不加是一样的. 声明只有一 ...

  9. C基础知识(2):变量&常量的定义和声明

    变量定义和声明 (1) 使用int,char等类型符定义变量 使用int,char等类型符定义变量时,不管有没有指定初始值,都就已经建立了存储空间(开辟内存).内存寻址由大到小,优先分配内存地址比较大 ...

随机推荐

  1. QT 线程的使用(继承QThread)

    对于多线程而言,要注意资源的同步和互斥问题,但对于单独的一个线程,则只需要对它的run方法进行重写. 下面实现了一个简单的线程 widget.h文件 #ifndef WIDGET_H #define ...

  2. php 栈、 出栈、入栈

    最近在面试的时候被问到栈,回来做个总结,希望对大家有帮助 栈是线性表的一种,他的特点是后入先出,可以这么理解,栈就像一个存东西的盒子,先放进去的在最底层,后放进去的在上层,因为上层的东西把底层的东西压 ...

  3. 【Trie】Secret Message 秘密信息

    [题目链接]: https://loj.ac/problem/10054 [题意] 我认为这个题目最难的是题意: 其实分了两种情况: 1.如果当前文本串匹配不完,那么答案的是:匹配过程中遇到的模式串结 ...

  4. react项目中关于img标签的src属性的使用

    在一个html文件中,img的src属性赋值为相对路径或绝对路径的字符串即可访问到图片.如下: <img src="../images/photo.png"/> 但在j ...

  5. 如何给Swagger加注释

    在Startup.cs文件中的ConfigureServices()方法中添加如下代码即可 services.AddSwaggerGen(options => { options.Swagger ...

  6. C++ 构造函数后面的冒号的作用

    其实冒号后的内容是初始化成员列表,一般有三种情况:     1.对含有对象成员的对象进行初始化,例如,     类line有两个私有对象成员startpoint.endpoint,line的构造函数写 ...

  7. gzip: stdin: not in gzip format 解决办法

    # sudo tar zxvf ./jdk-7ull-linux-i586.tar.gz -C /usr/lib/jvm gzip: stdin: not in gzip format tar: Ch ...

  8. Springboot整合MybatisPlus

    目录 1.pom文件 2.创建CodeGenerator.java 3.在application.yml中配置mybatis-plus 4.创建MybatisPlusConfig.java文件 其他 ...

  9. parseInt parseFloat Number三者转换的方式

    1.parseInt:从左到右检测字符串,若能先检测到数字,则将数字转换成整形,否则返回NaN. 2.parseFloat:从左到右检测字符串,若能先检测到数字,则将数字转换成浮点型,否则返回NaN. ...

  10. centeros7安装mysql

    转载自:https://www.linuxidc.com/Linux/2016-09/135288.htm 安装之前先安装基本环境:yum install -y perl perl-Module-Bu ...