格式:
struct 结构体名
{
数据类型 成员1;
数据类型 成员2;
数据类型 成员3;
...
数据类型 成员n;
};
格式解析:
1.struct:是结构体关键字
2.结构体名,需要满足命名规范,可以省略,与typedef结合直接定义结构体类型
3.{}不可以省略,;也不可省略
4.成员变量的数据类型可以为基本类型,构造类型,指针,空类型(void)
5.成员的个数任意
6.结构体描述时,计算机不分配空间,直到定义结构体变量计算机才分配空间,分配空间大小为各成员字节大小的总和
实例:
/*定义车的信息:品牌,单价,颜色,车牌号*/
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
间接定义:在结构体描述完成后,通过描述的结构体类型定义变量
1)间接定义变量按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car={"大众",123456,"白色","沪A1111"};
2)间接定义变量不按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car={.price=123456,.color="白色",.id="沪A1111",.name="大众"};
3)间接定义变量,单个赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car;
strcpy(car.name,"大众"); //为字符串赋值时必须使用字符串函数,不能直接赋值
car.price=123456;
strcpy(car.color,"白色");
strcpy(car.id,"沪A88888");
注意:car.name="大众",这种赋值方式是错误的,在C99标准中不允许将字符串赋值给数组,如果强行赋值,编译器会直接报语法错误: [Error] assignment to expression with array type。
4)间接定义变量,输入赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car;
scanf("%s",car.name);
scanf("%d",&car.price);
scanf("%s",car.color);
scanf("%s",car.id);
定义结构体描述的同时定义结构体变量
1) 直接定义变量按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car={"大众",123456,"白色","沪A1111"};
2)直接定义变量不按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car={.price=123456,.color="白色",.id="沪A1111",.name="大众"};
3)直接定义变量,单个赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car;
strcpy(car.name,"大众");
car.price=123456;
strcpy(car.color,"白色");
strcpy(car.id,"沪A88888");
4)直接定义变量,输入赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car;
scanf("%s",car.name);
scanf("%d",&car.price);
scanf("%s",car.color);
scanf("%s",car.id);
5) 直接定义可以省略结构体名,称“无名结构体”
struct
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car;
1)间接定义变量按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car[3]={"大众",123456,"白色","沪A1111","大众",123456,"白色","沪A2222","大众",123456,"白色","沪A33333"};
2)间接定义变量不按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car[3]={[0]={.price=123456,.color="白色",.id="沪A1111",.name="大众"},[2]={.price=123456,.color="白色",.id="沪A2222",.name="大众"},[1]={.price=123456,.color="白色",.id="沪A3333",.name="大众"}};
3)间接定义变量,单个赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car[3];
//第一辆车的信息
strcpy(car[0].name,"大众");
car[0].price=123456;
strcpy(car[0].color,"白色");
strcpy(car[0].id,"沪A1111");
//第二辆车的信息
strcpy(car[1].name,"大众");
car[1].price=123456;
strcpy(car[1].color,"白色");
strcpy(car[1].id,"沪A2222");
//第三辆车的信息
strcpy(car[2].name,"大众");
car[2].price=123456;
strcpy(car[2].color,"白色");
strcpy(car[2].id,"沪A3333");
4> 间接定义变量,输入赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car[3];
for(int i=0;i<3;i++)
{
scanf("%s",car[i].name);
scanf("%d",&car[i].price);
scanf("%s",car[i].color);
scanf("%s",car[i].id);
}
1)直接定义变量按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car[3]={"大众",123456,"白色","沪A1111","大众",123456,"白色","沪A2222","大众",123456,"白色","沪A33333"};
2)直接定义变量不按顺序初始化
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car[3]={[0]={.price=123456,.color="白色",.id="沪A1111",.name="大众"},[2]={.price=123456,.color="白色",.id="沪A2222",.name="大众"},[1]={.price=123456,.color="白色",.id="沪A3333",.name="大众"}};
3)直接定义变量,单个赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car[3];
strcpy(car[0].name,"大众");
car[0].price=123456;
strcpy(car[0].color,"白色");
strcpy(car[0].id,"沪A88888");
strcpy(car[1].name,"大众");
car[1].price=123456;
strcpy(car[1].color,"白色");
strcpy(car[1].id,"沪A88888");
strcpy(car[2].name,"大众");
car[2].price=123456;
strcpy(car[2].color,"白色");
strcpy(car[2].id,"沪A88888");
4)直接定义变量,输入赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car[3];
for(int i=0;i<3;i++)
{
scanf("%s",car[i].name);
scanf("%d",&car[i].price);
scanf("%s",car[i].color);
scanf("%s",car[i].id);
}
格式:
struct 结构体名 *指针变量名
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car c={.price=123456,.color="白色",.id="沪A1111",.name="大众"};
struct Car *p=&c;
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car car[3]={"大众",123456,"白色","沪A1111","大众",123456,"白色","沪A2222","大众",123456,"白色","沪A33333"};
struct Car *p=car;
#include
#include
#include
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
//输出对去空间内存
void Output(struct Car *p,int len)
{
for(int i=0;iname,(p+i)->price,(p+i)->color,(p+i)->id);
printf("%s\t%d\t%s\t%s\n",(*(p+i)).name,(*(p+i)).price,(*(p+i)).color,(*(p+i)).id);
}
}
//在堆区空间申请
struct Car * create()
{
struct Car *p=(struct Car *)malloc(sizeof(struct Car)*3);//
if(NULL == p)
{
return NULL;
}
return p;
}
//在堆区实现循环输入
void Input(struct Car *p ,int n)
{
for(int i=0;i<3;i++)
{
scanf("%s",(p+i)->name);
scanf("%d",&(p+i)->price);//(p+i)->price===>price
scanf("%s",(p+i)->color);
scanf("%s",(p+i)->id);
}
}
//释放堆区空间
struct Car * free_space(struct Car *p)
{
if(NULL==p)
{
return NULL;
}
free(p);
p=NULL;
return p;
}
int main(int argc, const char *argv[])
{
struct Car *p=create();
Input(p,3);
Output(p,3);
p=free_space(p);
return 0;
}
1.基本结构使用“.”进行引用,只能使用结构体变量名引用
2.结构体数组使用"."进行引用,只能使用结构体数组名引用
3.值使用".",地址使用“->”
4.结构体名表示所有信息,不可以直接打印,结构体整体引用常用于传递参数,或者元素的赋值
struct Car
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
};
struct Car a={"大众",123456,"白色","沪A1111"};
struct Car b;
/*将a的赋值给b,方法一*/
strcpy(b.name,a.name);
b.price=a.price;
strcpy(b.color,a.color);
strcpy(b.id,a.id);
/*将a的赋值给b,方法一*/
b=a;
typedef struct
{
char name[20]; //品牌
int price; //单价
char color[10]; //颜色
char id[20]; //车牌号
}car_t,car_arr[3],*car_p;
注意:car_t:不是变量名,是基本结构体类型别名,car_arr:不是结构体数组名,是结构体数组的别名,car_p:不是结构体指针变量名,是结构体指针的别名,当typedef和结构体结合时,结构体名可以省略不写。
练习:定义一个学生:姓名、性别、出生日期【年月日】
typedef struct
{
int year,month,day;
}Birthday;
typedef struct
{
char name[10];
char sex;
Birthday bir;
}Stu;
Stu student={"张三",'M',2000,7,14};
printf("%s %c %d年%d月%d日\n",student.name,studnet.sex,student.bir.year,student.bir.month,student.bir.day);
练习:定义一个人的信息:姓名,性别,年龄,车辆多辆【品牌,单价】
typedef struct
{
char name[10];
int price;
}Car_t;
typedef struct
{
char name[10];
char sex;
int age;
Car_t arr[2];
}person;
person per={"张三",'M',18,"奔驰",555555,"宝马",666666};
printf("",per.name,per.sex,per.age,per.arr[0].name,per.arr[0].price,per.arr[1].name,per.arr[1].price);
1.结构体的总字节是各个成员字节的总和
2.结构体变量的地址是第一个成员的首地址,各个成员的地址连续
3.结构体需满足字节对齐原则
i.结构体的首地址是最宽成员的倍数
如果最宽成员是1字节,则地址是1的倍数
如果最宽成员是2字节,则地址是2的倍数
如果最宽成员是4字节,则地址是4的倍数
如果最宽成员是8字节,则地址是8的倍数
ii. 结构体总字节数是最宽成员的倍数,如果不是则填充空字节
iii.各个成员的地址偏移量是各个成员字节的倍数,如果不是则填充空字节
地址偏移量:该成员的首地址到结构体的起始地址之间的差
typedef struct
{
int a;
float b;
}A_t;
A_t var;
printf("&var=%p\t&var.a=%p\t&var.b=%p\n",&var,&var.a,&var.b);
printf("sizeof(A_t)=%ld\n",sizeof(A_t)); //结构体字节长度为:8
typedef struct{
char a;
double b;
}B_t;
B_t var1;
printf("&var1=%p\t&var1.a=%p\t&var1.b=%p\n",&var1,&var1.a,&var1.b);
printf("sizeof(B_t)=%ld\n",sizeof(B_t)); //结构体字节长度为:16
typedef struct
{
int a;
char b;
float c;
char *p;
char d;
}C_t;
C_t c;
printf("c.a=%p\n",&c.a);
printf("c.b=%p\n",&c.b);
printf("c.c=%p\n",&c.c);
printf("c.p=%p\n",&c.p);
printf("c.d=%p\n",&c.d);
printf("sizeof(C_t)=%ld\n",sizeof(C_t));//结构体字节长度为:32
typedef struct
{
a_str a;
int b;
}D_t;
printf("sizeof(D_t)=%ld\n",sizeof(D_t));//12
typedef struct{
char a;
double b;
}E_t;
typedef struct
{
char a;
short b;
E_t c;
}F_t;
printf("sizeof(F_t)=%ld\n",sizeof(F_t));//结构体字节长度为:24
1.结构体的总字节是各个成员字节的总和
2.结构体变量的地址是第一个成员的首地址,各个成员的地址连续
3.结构体需满足字节对齐原则
i.结构体的首地址是最宽成员的倍数
如果最宽成员是1字节,则地址是1的倍数
如果最宽成员是2字节,则地址是2的倍数
如果最宽成员是4字节或者8字节,则地址是4的倍数
ii. 结构体总字节数是最宽成员的倍数,如果不是则填充空字节
如果最宽成员是4字节或者8字节,则总字节是4的倍数
iii.各个成员的地址偏移量是各个成员字节的倍数,如果不是则填充空字节
如果最该成员是4字节或者8字节,则地址偏移量是4的倍数