结构体(struct):
若干个相同或不同类型的数据构成的集合,构成结构体的数据称为结构体的数据成员。
结构体类型是一种自定义的数据类型,不是系统预定义的数据类型,所以在使用之前要声明结构体类型,然后再使用。结构体的定义和初始化
struct student{ unsigned num; char name[20]; char sex; int age; float score;}student1,student2;//在声明结构体类型的同时定义结构体变量
或者struct student a;
声明匿名结构体类型,需同时定义结构体变量。 truct student1={288829,”kafdk”,’m’}; //全部初始化,局部初始化typedef:给类型起别名
与#define之间的区别:#define INT_Q int* //单纯的替换,不考虑正确性typedef int* INT_R; // 起别名,考虑正确性INT_Q q1,q2;//q1是指针,q2是整型变量INT_R r1,r2;//都是指针,引入了一个新的助记符
结构体变量所占存储空间的大小至少为其所以成员所占空间的总和,还要考虑字节对齐机制的影响
结构体的内存布局:所有数据成员按照定义顺序由低地址向高地址依次连续存放结构体的访问
average=(student1.soure+student2.soure+student3.soure)/3;//和数组一样,不能整体访问,只能访问它的数据成员//.为成员运算符,作用为获取结构体的数据成员//通过结构体变量的指针访问其数据成员struct student* p=&a1;p->name="ajsdhk"; //->为指向运算符,作用为获取结构体的数据成员printf("%s\n",p->name);//堆区结构体struct book* p=(struct book*)malloc(sizeof(struct book));typedef struck student{ int id;}stu;Stu.id=(*stu).id=stu->id//将一个结构体变量赋给另外一个结构体变量;必须类型相同
typedef struct person{ int id; char sex; float sight; char name[100];}person;int main{ person p1; struct person p2; p1.id = 1001;//取结构体成员 等效于:*(int)&p1 = 1001; (取值---转换---指向----赋值) //下面两句编号无区别,内容有区别,基类型不同 &p1;//指向结构体(整体第一个) &(p1.id);//指向int(int第一个) return 0;}
结构体的输入输出:
printf(“%u,%s,%c”,num,name,sex); scanf(“&u,%s,%c”,&student1.num,student1.name,&student.sex); name[]是字符数组,所以不加&结构体的嵌套使用:
结构体的数据成员为结构体类型联合或公用体(union):
- 公用体类型让几个不同类型的变量存放在同一个内存区域中,这几个变量的起始地址是一样的,系统使用的数据值覆盖存储的方式使得这些不同类型的变量在同一时刻只有一个能起作用。
- 和结构体一样,也是自定义数据类型,用法基本相同,但不同的是结构体的数据成员都有自己独立的内存空间,而公用体的所有成员公用一块内存空间,所有共同体的首地址相同。
- 定义的同时只能用第一个成员的类型的值进行初始化
- 公用体所占存储空间大小由它的数据成员中占存储空间最大的决定
- 在某一时刻,只有一个数据成员有意义
- 访问最近被赋值的数据成员才有意义
枚举(enum):
也是自定义数据类型,表示取值只有有限种情况的数据
enum sex {male,female};//male,female称为枚举常量 其实枚举常量代表一个整数值,默认情况下从0开始 枚举值是常量,不是变量。枚举和共用体的例子:
#include#include #include #include enum NumType // 声明一个枚举类型来描述要输出的类型{ INTEGER_INT, // 整型类型 INTEGER_LONG, // 长整型类型 INTEGER_DOUBLE // DOUBLE类型};union NumValue // 声明一个包含下面三种类型的共用体{ int iValue; // int类型值 long lValue; // long类型值 double dValue; // double类型值};int main( int argc, char *argv[] ){ int count = argc - 1; // 计算输入的参数个数 NumValue *Values = new NumValue[count]; // 存放值的共用体 NumType *Types = new NumType[count]; // 存放类型的数组 for( int i = 1; i < argc; ++i ) // 循环处理每个参数 { if( strchr( argv[i], '.' ) != 0 ) // 判断输入参数中是否包含小数点 { Values[i].dValue = atof( argv[i] ); // 为dValue成员赋值,并记录类型。 Types[i] = INTEGER_DOUBLE; // 记录数组的成员的类型为DOUBLE型 } else // 不是Floating类型 { if (( atol( argv[i] ) > INT_MAX ) || (atol( argv[i] ) < 0)) { // 如果数据大于int类型的最大值,则将其存储在lValue成员中,并记录类型 Values[i].lValue = atol( argv[i] ); // 将值转换成长整型 Types[i] = INTEGER_LONG; // 记录数组的成员的类型为长整型 } else { // 否则,将其存储在iValue成员中,并记录类型 Values[i].iValue = atoi( argv[i] ); // 将值转换成整型 Types[i] = INTEGER_INT; // 记录数组的成员的类型为整型 } } switch( Types[i] ) // 根据类型种类,将种类信息和值信息输出 { case INTEGER_INT: // 如果数据为整型,输出整型值 printf( "数据类型为Integer,值为%d\n", Values[i].iValue ); break; case INTEGER_LONG: // 如果数据为长整型,输出长整型值 printf( "数据类型为Long,值为%d\n", Values[i].lValue ); break; case INTEGER_DOUBLE: // 如果数据为double型,输出double值 printf( "数据类型为Double,值为%f\n", Values[i].dValue ); break; } } //system("pause"); return 0;}