赞
踩
目录
结构体是用户自定义的一种类型,这种类型里面可以声明不同的数据类型,如char、int...等等,以此来满足用户对某种对象的具体描述。比如我想描述某个人的职业信息,那么通过描述他的姓名(char name[ ]),年龄(int),职业(char position[ ]),年薪( int )等就可以很清楚的知道这个的人的职业信息,当我需要把这个人的职业信息发给亲戚,总不能一句句发,而是全部整合到一起发,那么将多种数据类型整合到一起,我们可以使用结构体类型。
结构体定义的方式有很多种:
- struct Person
- {
- char name[16];
- int age;
- };
此定义,定义了一个Person结构体(记住是Person结构体,而不是叫结构体Person),意味着 struct Person才是结构体类型,struct叫做关键字,Person叫做标识符。因此,我们在使用的时候就得这样使用:
struct Person john;
这个Person结构体声明了一个对象,叫做 john。那么我们的某些编译器为了让我们节省打字压力,允许我们省略 struct 关键字:
Person john;
ps:这里Person没有变色是因为我们的结构体定义没有写进去,就写了一个声明对象。不是因为这种声明方式不可以哈(我的编译器是支持这种写法的)。但是这种写法在理论上来说是错误的(世上本没有路,走的人多了也就变成了路),如定义所说,这Person只是描述符,只有struct Person这种才代表了结构体类型,所以这种声明方式可以但不推荐大家这样写,以免对结构体定义有所混淆,那么如何正确省略struct这个关键字,看下面第2种定义。
- typedef struct Person
- {
- char name[16];
- int age;
- }per;
这里的定义,用口语正确表达是:首先定义了一个struct Person的结构体,然后 typedef 关键字(这个关键字我一般叫别定义。官方著这个关键字可以将复杂的声明或者数据类型另外定义一个简单的名字)将 struct Person 别定义为 per。也就是说现在 per 就等价于 struct Person。那么就有如下声明:
per john;
这样才是正确省略struct的方式。那么可以看出,用了 typedef 之后:
- struct Person john;//正确,最原始的声明
-
- per john;//正确,typedef的声明
- struct per john;//错误,per = struct Person
- struct Person
- {
- char name[];
- int age;
- }per;
这种没有使用typedef的定义方式,叫定义即对象,也就是per就是struct Person的对象,相当于第2条中的 john,且是全局变量。对于这种直接定义了对象的,可以重新使用如下声明第二个对象,也可以直接使用对象per:
struct Person john;//声明对象john
那么这里的per,也是对象,是可以直接使用的,无需再重复声明了,如下使用
- struct Person
- {
- char name[16];
- int age;
- }per;
-
- int main()
- {
- strcpy(per.name, "xiaoming");
- per.age = 16;
- printf("%s\n", per.name);
- printf("%d\n", per.age);
-
- return 0;
- }
- struct Person
- {
- char name[16];
- int age;
- }*per;
-
- int main()
- {
- per = (Person*)malloc(sizeof(struct Person));
- strcpy(per->name, "xiaoming");
- per->age = 16;
-
- printf("%s\n", per->name);
- printf("%d\n", per->age);
-
- free(per);
-
- return 0;
- }
这种定义方式,和第3条有点类似,都是直接定义了Person结构体的对象,不过现在这个对象是个指针,所以per我们称为结构体对象指针。
如果在定义时就声明了结构体指针,这指针是全局变量,存储在静态区,在整个程序结束后才会释放 指针per 的内存(当然,要明白这里的指针per的内存说的是 指针本身的内存 ,即该指针的地址,而不是指 指针per的内容(值)所指向的内存。 这个指针的变量per 的内容(值)是另一块内存的地址,即结构体数据成员的首地址,它所指向的是结构体成员name和age所在的内存块)。
其次,在其他函数中(如main函数)欲给 指针per 指向的数据成员赋值时,需要为数据成员开辟内存空间,使用malloc函数(因为定义对象即指针的所申请的内存仅这个指针本身,它的内容所指向的内存的空间还没有被开辟)。这样 指针per 指向的内存(数据成员的内存)就是存储在 堆 上,而非 栈(只存储局部变量) 上,也不是静态区(只存储静态变量和全局变量)。在使用完毕后,需要使用 free函数 手动释放存储在 堆 上的数据成员的内存空间。
- typedef struct Person
- {
- char name[16];
- int age;
- }per, *perptr;
-
- int main()
- {
- per a;
- a.age = 16;
- printf("%d\n", a.age);
-
- perptr v;
- v = (Person *)malloc(sizeof(struct Person));
- v->age = 14;
- printf("%d\n", v->age);
- free(v);
-
- return 0;
- }
看到这里,你就需要明白,既然用了typedef关键字,就代表 per 等价于 struct Person,perptr 等价于 struct Person*(这里需要加深理解哦,有typedef和没有typedef的区别,一个是结构体指针,一个是结构体对象指针)。既然是结构体指针,那么首先肯定要声明一个对象, perptr v;
结构体的使用其实在第二个里面有略微介绍到:主要就两种结构体和结构体指针的使用
- typedef struct Base
- {
- int a;
- }base;
-
- int main()
- {
- //1.结构体
- base A;
- A.a = 11;
- printf("%d\n", A.a);
-
- //2.结构体指针
- base* B;
- B = (base*)malloc(sizeof(base));
- B->a = 12;
- printf("%d\n", B->a);
- free(B);
-
- //2.结构体赋值给结构体指针,即这个结构体指针指向另一个结构体
- base* C;
- C = &A;
- printf("%d\n", C->a);
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。