zoukankan      html  css  js  c++  java
  • 声明与定义

    声明:听其言(extern、以及类的前向声明 forward declaration),定义:观其行;

    1. 变量

    从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存。而定义就是分配了内存(存在客观上的实物)。

    考虑下面的代码:

    void func() {
        int a;
        int b = 1;
        a = 0;
    }

    对于第一行代码,编译器不会做任何事?(仅仅是被通知存在 a 这样的一个变量而已),它不会为它在栈中分配一点东西,直到第三句,a = 0; 时,编译器才会将其压入栈中。而对于 int b=0; 这一句,编译器就会生成一条指令,为它赋值。可通过反汇编查看。

    编译器也有可能在声明 int a时,编译器就会把一个废值入栈,到第三条再为其赋值,这要看编译器的具体取舍,所以,声明不一定不是定义,而定义一定是定义。但是,下面的声明,一定仅仅是声明:

    extern int a;
                    // 声称(告诉编译器)其他存在一个变量 a,(当然编译器也不会为它做任何分配内存的事)
                    // 功能类似于类的前向声明,forward declaration

    尤其注意全局变量,虽然有时也可以像在函数的局部变量那样,仅仅看似是声明的形式,但编译器仍然会对其进行初始化(默认初始化方式),能够被初始化,显然占据着一定的内存空间。

    int a;
                        // 是定义,默认初始化为 0
    int main() {
        return 0;
    }

    2. 更准确地说明

    int a;

    是一种定义型声明(defining declaration),其实就是定义编译器已经分配了空间,如果连写 2 个 int a; int a;(vs 好像编译通过,运行不通过),

    extern int a; 

    这才是一个纯正的标准的声明,C++允许多个声明同名同类型,试试 extern int a; extern int a; 定义就不行。

    3. 函数

    • 声明:一般在头文件里,对编译器说:这里我有一个函数叫 function() 让编译器知道这个函数的存在;

    • 定义:一般在源文件里,具体就是函数的实现过程写明函数体;

  • 相关阅读:
    SQL创建索引
    SQLServer最耗资源时间的SQL语句
    C# Linq删除父级的同时删除子级
    C# 根据类名创建类的实例对象
    C#利用反射实现两个类的对象之间相同属性的值的复制
    linq时间筛选以及list时间筛选
    为什么watch机制不是银弹?
    我们的前端模版引擎更新总结
    小矮人Javascript模块加载器
    Javascript模版引擎简介
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9423594.html
Copyright © 2011-2022 走看看