• 你可能不知道的,定义,声明,初始化


    声明定义虽然无处不在,但是真正的想区分它们,却不是表面上那么简单。
    首先,从广义的角度来讲声明中包含着定义:定义又可以称之为,“声明性定义”;而狭义的声明,有可称之为“引用性声明”。
    下面,我们就来讨论“声明性定义”与“引用性声明”。的区别,之后简称定义与声明。

    1、定义时系统会为定义的变量分配空间,而声明时,不会分配空间。这个是本质上的区别。

    2、定义在程序中只能出现一次,而声明可以多次。比如:
    如果两个c中有相同的全局变量“定义”,且没有初始化,编译器会认为第二个是声明而不是定义。
    所以连续写两个int a;int a; 编译也不会出错,但是连续写int a = 1;int a = 1;编译出错。(函数也一样)

    3、由2可见,在定义变量时初始化的副作用是告诉编译器,这是一个定义,而不是一个声明。因为声明时,是不可以
    初始化的,具体的例子就是  extern int a; 这表示这是个声明而不是定义。如果写成extern int a = 1;编译就会报错。
    结合1来想,这个就很正常了,因为声明是没有分配空间的,如何赋值呢?

    4、定义时可以完成声明,并且初始化!例如 int a = 0; //定义,声明,初始化就包含这一条语句之中。
    //--------关于extern的用法-------------------
        extern的作用就是进行声明,实现调用其他文件的全局变量,或者函数。
    由于声明可以多次,一般有的变量会被其他文件文件调用,那么一般会在该文件的头文件多声明一次改变量——extern + 变量。
    那么如果另外一个文件包含了该头文件,就可以调用该变量。
    //--------关于struct的声明定义初始化-------------------
    1、struct的定义(这里注意的是,struct定义的是类型,而不是变量;但是以上结论同样适用!)
    struct people        //定义类型
    {
        char name[20];
        int age;
    };

    2、struct people;    //声明类型,同样写两句一模一样的不会错!但是类型定义也只能一次。

    3、定义类型时,同时利用类型声明(定义)变量。这里类肯定是定义好了,而s1如果没有其他初始化代码,这里就是即声明又定义了。
    struct student
    {
        char name[20];
        int age;
    }s1;

       4、结构体变量的初始化,这个需要在3的前提下,这种形式的初始化可以不按照定义时的顺序,可帅气的称之为“乱序初始化”
    struct student s1 =
    {
        .age = 10,   
        .name = "linux",    //注意初始化结构体变量是用的是逗号,而定义结构体类型时,用的是分号。
    };

    5、省略掉类型的声明(定义)
    struct
    {
        char name[20];
        int age;
    }s1;
    但是无法像4中那样单独的初始化。

    6、定义结构体类型时,无法初始化结构体变量,如下写法会报错:
    struct student  //错误写法
    {
        char name[20] = linux ;
        int age = 10;
    }s1;

    7、于似乎再次发现一种神奇的写法:这样写也是有效的
    struct student
    {
        char name[20];
        int age;
    }s1 =
    {
        .age = 10,
        .name = "linux",
    };

    8、去掉类型名字,这样写也是有效的
    struct
    {
        char name[20];
        int age;
    }s1 =
    {
        .age = 10,
        .name = "linux",
    };
    定义结构体类型,同时定义结构体变量,并初始化变量,就是这么帅~~

    9、struct {}a和 struct a{} 的区别
    前者是定义了a(结构体)变量,后者是定义了结构体类型a。

    //--------关于enum的声明定义初始化-------------------
    这个就直接摘抄朱老师(朱有鹏)笔记吧。
    /*
    ****************************************************************
    *     enumeration 类型定义
    ****************************************************************
    */
    // 定义方法1,定义类型和定义变量分离开
    enum week
    {
        SUN,        // SUN = 0
        MON,        // MON = 1;
        TUE,
        WEN,
        THU,
        FRI,
        SAT,
    };

    enum week today;

    // 定义方法2,定义类型的同时定义变量
    enum week
    {
        SUN,        // SUN = 0
        MON,        // MON = 1;
        TUE,
        WEN,
        THU,
        FRI,
        SAT,
    }today,yesterday;

    // 定义方法3,定义类型的同时定义变量
    enum
    {
        SUN,        // SUN = 0
        MON,        // MON = 1;
        TUE,
        WEN,
        THU,
        FRI,
        SAT,
    }today,yesterday;

    // 定义方法4,用typedef定义枚举类型别名,并在后面使用别名进行变量定义
    typedef enum week
    {
        SUN,        // SUN = 0
        MON,        // MON = 1;
        TUE,
        WEN,
        THU,
        FRI,
        SAT,
    }week;


    // 定义方法5,用typedef定义枚举类型别名,并在后面使用别名进行变量定义
    typedef enum
    {
        SUN,        // SUN = 0
        MON,        // MON = 1;
        TUE,
        WEN,
        THU,
        FRI,
        SAT,
    }week;

    结构体,枚举,使用方法总结:
    1、结构体,枚举使用有很多相似的地方;
    2、定义枚举类型时,用的是分号。而且可以同时初始化其实的变量。
    3、枚举类型不管是类型名还是,枚举内部的变量都是全局的,所以都不能重名。而结构体内部的变量是局部的。
    4、使用枚举是可以直接用其中的变量如:SUN;而结构体需要这么访问:s1.age

    最后是关于static的声明:
    static来声明一个变量的作用有二个:
    (1)对于局部变量用static声明,则是为该变量拥有全局变量的特性——在整个程序的执行期内都始终存在。因为他和全局变量一样在数据段。而不再栈上。
    同时拥有局部变量的特性——无法被外部程序访问,这个就是生命周期的问题。
    (2)全局变量或者是函数用static来声明,则起到“隐蔽”的作用——该变量的作用域只限于本文件。其他文件无法访问。
    加上extern也不行。

  • 相关阅读:
    Navicat远程连接服务器Mysql
    JSP与Servlet之间传值
    JSP获取绝对路径
    PIL的库学习
    科学计算与可视化
    预测球类比赛结果
    预测球类比赛结果
    汉诺塔问题
    有进度条圆周率计算
    turtle学习心得
  • 原文地址:https://www.cnblogs.com/douzi2/p/5044870.html
Copyright © 2020-2023  润新知