//
// main.c
// constructedtype
//
// created by kenshin cui on 14-7-18.
// copyright (c) 2014年 kenshin cui. all rights reserved.
//
#include <stdio.h>
struct date{
int year;
int month;
int day;
};
struct person{
char *name;
int age;
struct date birthday;
float height;
};
void changevalue(struct person person){
person.height=1.80;
}
int main(int argc, const char * argv[]) {
struct person persons[]={
{"kenshin",28,{1986,8,8},1.72},
{"kaoru",27,{1987,8,8},1.60},
{"rosa",29,{1985,8,8},1.60}
};
for (int i=0; i<3; ++i) {
printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",
persons[i].name,
persons[i].age,
persons[i].birthday.year,
persons[i].birthday.month,
persons[i].birthday.day,
persons[i].height);
}
/*输出结果:
name=kenshin,age=28,birthday=1986-8-8,height=1.72
name=kaoru,age=27,birthday=1987-8-8,height=1.60
name=rosa,age=29,birthday=1985-8-8,height=1.60
*/
struct person person=persons[0];
changevalue(person);
printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",
persons[0].name,
persons[0].age,
persons[0].birthday.year,
persons[0].birthday.month,
persons[0].birthday.day,
persons[0].height);
/*输出结果:
name=kenshin,age=28,birthday=1986-8-8,height=1.72
*/
struct person *p=&person;
printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",
(*p).name,
(*p).age,
(*p).birthday.year,
(*p).birthday.month,
(*p).birthday.day,
(*p).height);
/*输出结果:
name=kenshin,age=28,birthday=1986-8-8,height=1.72
*/
printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",
p->name,
p->age,
p->birthday.year,
p->birthday.month,
p->birthday.day,
p->height);
/*输出结果:
name=kenshin,age=28,birthday=1986-8-8,height=1.72
*/
return 0;
}
//
// main.c
// constructedtype
//
// created by kenshin cui on 14-7-18.
// copyright (c) 2014年 kenshin cui. all rights reserved.
//
#include <stdio.h>
enum season{ //默认情况下spring=0,summer=1,autumn=2,winter=3
spring,
summer,
autumn,
winter
};
int main(int argc, const char * argv[]) {
enum season season=summer; //枚举赋值,等价于season=1
printf("summer=%d\n",season); //结果:summer=1
for(season=spring;season<=winter;++season){
printf("element value=%d\n",season);
}
/*结果:
element value=0
element value=1
element value=2
element value=3
*/
return 0;
}
需要注意的是枚举成员默认值从0开始,如果给其中一个成员赋值,其它后面的成员将依次赋值,例如上面如果summer手动指定为8,则autumn=9,winter=10,而sprint还是0。
共用体又叫联合,因为它的关键字是union(貌似数据库操作经常使用这个关键字),它的使用不像枚举和结构体那么频繁,但是作为c语言中的一种数据类型我们也有必要弄清它的用法。从前面的分析我们知道结构体的总长度等于所有成员的和(当然此时还可能遇到对齐问题),但是和结构体不同的是共用体所有成员共用一块内存,顺序从低地址开始存放,一次只能使用其中一个成员,union最终大小由共用体中最大的成员决定,对某一成员赋值可能会覆盖另一个成员。
//
// main.c
// constructedtype
//
// created by kenshin cui on 14-7-20.
// copyright (c) 2014年 kenshin cui. all rights reserved.
//
#include <stdio.h>
union type{
char a;
short int b;
int c;
};
int main(int argc, const char * argv[]) {
union type t;
t.a='a';
t.b=10;
t.c=65796;
printf("address(type)=%x,address(t.a)=%x,address(t.b)=%x,address(t.c)=%x\n",&t,&t.a,&t.b,&t.c);
//结果:address(type)=5fbff7b8,address(t.a)=5fbff7b8,address(t.b)=5fbff7b8,address(t.c)=5fbff7b8
printf("len(type)=%d\n",sizeof(union type));
//结果:len(type)=4
printf("t.a=%d,t.b=%d,t.c=%d\n",t.a,t.b,t.c);
//结果:t.a=4,t.b=260,t.c=65796
return 0;
}
这里需要重点解释一个问题:为什么t.a、t.b、t.c输出结果分别是4、260、65796,当然t.c等于65796并不奇怪,但是t.a前面赋值为'a'不应该是97吗,而t.b不应该是10吗?其实如果弄清这个问题共用体的概念基本就清楚了。
根据前面提到的,共用体其实每次只能使用其中一个成员,对于上面的代码经过三次赋值最终使用的其实就是t.c,而通过上面的输出结果我们也确实看到c是有效的。共用体有一个特点就是它的成员存储在同一块内存区域,这块区域的大小需要根据它的成员中长度最大的成员长度而定。由于上面的代码是在64位编译器下编译的,具体长度:char=1,short int=2,int=4,所以得出结论,type的长度为4,又根据上面输出的地址,可以得到下面的存储信息(注意数据的存储方式:高地址存储高位,低地址存储地位):
当读取c的时候,它的二进制是“00000000 00000001 00000001 00000100”,换算成十进制就是65796;而经过三次赋值后,此时b的存储就已经被c成员的低位数据覆盖,b的长度是二,所以从起始地址取两个字节得到的二进制数据此时是“00000001 00000100”(b原来的数据已经被c低2位数据覆盖,其实此时就是c的低2位数据),换算成十进制就是260;类似的a此时的数据就是c的低一位数据”00000100”,换算成十进制就是4。
网友评论