转载

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

声明定义虽然无处不在,但是真正的想区分它们,却不是表面上那么简单。

首先,从广义的角度来讲声明中包含着定义:定义又可以称之为,“声明性定义”;而狭义的声明,有可称之为“引用性声明”。

下面,我们就来讨论“声明性定义”与“引用性声明”。的区别,之后简称定义与声明。

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也不行。

正文到此结束
Loading...