基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。
有点生硬,对于java程序员来说,结构体就相当于java model
比如定义 person
class Person{
string name;
int arg;
string cardId;
}
对于c来说要把这个对象用结构体来描述,表示具有这一特征的一种结构
struct Person{
char * name;
int age;
char * cardId;
}
结构体是一种构造数据类型,把不同的数据类型整合起来成为一个自定义的数据类型 有点类似于java对象
结构体与结构体变量
struct Man{
char *name;
int age;
} man = { "Tom", 12};
结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&,所以给 p赋值只能写作:
struct Man * p= &man;
而不能写作:
struct stu *p= man;
结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量:
struct stu *pstu = &Man;
struct stu *pstu = Man;
需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储
初始化:
在定义结构体时候初始化
typedef struct Man{
char name[20];
int age;
}man ={"jack',20};
在使用时候初始化
struct Man{
char name[20];
int age;
}man;
void main (){
//1
man m1= {"lily",20};
//2
man m2;
strcpy(m2.name,"rose");
man m3 = {1, "wuli"};//可以初始化,设置i为1,s为一个字符串.
man m4 = {1};//初始化个数少于实际个数时,只初始化前面的成员。
man m5 = {.name="wuli"};//有选择的初始化成员。
}
结构体写法:
struct 结构体名{
结构体所包含的变量或数组
};
声明struct新对象时,必须带上struct,即struct tagXX a;写成tagXX a的形式是错误的,但是在C++中却是可以的。
struct Man{
char name[10];
};
void main(){
struct Man m = {"jack"};//声明对象时需要带上struct
}
在声明类型的同时定义变量
struct 结构体名{
结构体所包含的变量或数组
} 别名;
struct Man{
char name[10];
}man;
直接定义结构体类型变量,匿名结构体
struct {
结构体所包含的变量或数组
} 别名;
struct{
char name[10];
}man;
结构体嵌套:
struct Student{
char name[20];
};
struct Person{
char name[20];
int age;
struct Student s;
}
void main(){
struct Student s1;
strcpy(s1.name,"jack");
struct Person p = {"lili",20,{"wuli"}};
getchar();
}
结构体与指针
通过结构体指针可以获取结构体成员,一般形式为:
(*pointer).memberName
或者:
pointer->memberName
第一种写法中,.的优先级高于,(*pointer)两边的括号不能少。如果去掉括号写作*pointer.memberName,那么就等效于(pointer.numberName),这样意义就完全不对了。
第二种写法中,->是一个新的运算符,习惯称它为“箭头”,有了它,可以通过结构体指针直接取得结构体成员;这也是->在C语言中的唯一用途。(与java中 类.变量名 作用类似)
struct Man{
char name[10];
int age;
} man = { "Tom", 12}, *p = &man;
void main(){
//读取结构体成员的值
printf("姓名:%s,年龄:%d\n", (*).name,(*p).age);
printf("姓名:%s,年龄:%d\n", p->name,p->age);
getchar();
}
指针与结构体数组
struct Man{
char name[20];
int age;
};
void main(){
struct Man mans[] = {{"lily",20,},{"jack",19}};
//遍历结构体数组
struct Man *p = mans;
int len = sizeof(mans) / sizeof(struct Man);
//方法一
for(;p<mans+len;p++){
printf("%s,%d\n",p->name,p->age);
}
//方法二
int i =0;
for(;i<len;i++){
printf("%s,%d\n",mans[i].name,man[i].age);
}
}
结构体动态分配内存
void main(){
struct Man * p =(struct Man*) malloc(sizeof(struct Man)*10);
struct Man * p1 = p;
//赋值
p1->name ="jack";
p1->age = 20;
p1++;
p1->name = "rose";
p1->age =21;
struct Man *loop_p= p;
for(;loop_p<p+2;loop_p++){
printf("%s,%d\n",loop_p->name,loop_p->age);
}
free(p);
getchar();
}