结构基础知识
在C语言中结构体是一种数据结构。结构体可被声明为变量,指针或者数组等;同时,也是一些元素的集合,这些元素被称为结构体成员,且这些成员可以是不同的类型,成员一般用名字访问
struct Stu //Stu为结构体标签
{
char name[20];
int age;
charsex[5];
char tele[12];
char addr[30];//成员
}stu1,stu2;
//stu1和stu2均为全局的结构体变量,
int main()
{
struct Stu stu;//创建结构体变量
}匿名结构体,将结构体标签省略,则必须在后面申明全局变量,但是也存在类型不同的问题
struct
{
char name[20];
int age;
charsex[5];
char tele[12];
char addr[30];//成员
}stu1;
struct
{
char name[20];
int age;
charsex[5];
char tele[12];
char addr[30];//成员
}*pstu;
//两结构体成员一模一样
int main()
{
pstu=&stu1;/*error,两个类型不同,因为是匿名的结构体类型,通过其创建的变量编译器会认为他们是不同的类型*/
}typedef简化struct
struct Stu
{
char name[20];
int age;
charsex[5];
char tele[12];
char addr[30];//成员
}stu1,arrstu[10],*pstu;
typedef struct Stu stu;/*如果typedef加在结构体前面,则后面的全局变量则表示为这个结构体的新名字*/
int main()
{
stu stu2;//省略struct
stu arr2[10];
stu *pstu;
return 0;
}结构体成员
1.直接访问
struct stu
{
char name[20];
int age;
char sex[5];
char tele[12];
char addr[30];//成员
};
typedef struct stu stu;
int main()
{
stu stu;//结构体变量
//stu.name="bit";//error,不能给常量赋值
strcpy(stu.name,"aaa");
stu.age=10;
printf("name=%s",stu.name);
printf("age=%d",stu.age);
return 0;
}2.间接访问
-> 用于结构体指针
. 用于结构体变量
struct stu
{
char name[20];
int age;
char sex[5];
char tele[12];
char addr[30];//成员
};
typedef struct stu* pstu;
int main()
{
stu stu;//结构体变量
pstu pstu1=&stu;
//strcpy((*pstu1).name,"aaa");
//(*pstu1).age=20;
strcpy(pstu1->name,"aaa");
return 0;
}结构体自引
例1.错误的方式
struct A
{
char name[10];
int age;
struct A sa;
}
int main()
{
struct A sa;
}用递归造成死循环,不断的自己引用自己
改正
struct A
{
char name[10];
int age;
struct A *sa;//大小为一个确切的值,通过指针找到下一个
}
int main()
{
struct A sa1;
struct A sa2;
struct A sa3;
sa1.pa=&sa2;
sa2.pa=&sa3;
sa3.pa=NULL;
}若想用typedef改写,则
typedef struct A//结构体内部嵌套同类型指针,重命名不能是匿名的结构体
{
char name[10];
int age;
struct A *sa;
}a;
int main()
{
a sa1;
a sa2;
a sa3;
sa1.pa=&sa2;
sa2.pa=&sa3;
sa3.pa=NULL;
}不完整声明
struct A
{
int i;
struct B b;
};
struct B
{
int i;
struct A a;
};
//不允许这种写法,会一直相互调用下去改写为
struct B;
struct A
{
int i;
struct B *b;
};
struct B
{
int i;
struct A *a;
};结构体初始化
struct stu
{
char name[10];
int age;
char sex[4];
char tel[12];
char add[20];
};
int main()
{
struct stu stu={"aaa",12,"male","123","xia"};
printf("%s\n",stu.name);
printf("%d\n",stu.age);
return 0;
}结构体中含有结构体的初始化
struct A
{
int a;
char c;
double d;
};
struct stu
{
char name[10];
int age;
char sex[4];
char tel[12];
char add[20];
struct A sa;
};
int main()
{
struct stu stu={"aaa",12,"male","123","xian"};//不完全初始化
struct stu stu={"aaa",12,"male","123","xian",{1,‘w‘,12.34}};//sa前的成员不可省略
printf("%s\n",stu.name);
printf("%d\n",stu.age);
printf("%1f\n",stu.sa.d);
return 0;
}结构体大小
struct s
{
int a;
char c;
couble d;
};
struct s2
{
int a;
double d;
char c;
};
int main()
{
printf("%d\n",sizeof(struct s));
printf("%d\n",sizeof(struct s2));
return 0;
}
//输出16
24存在内存对齐规则
第一个成员在与结构体变量偏移地址为0的地址处
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址
对齐数=编译器默认的一个对齐数与该成员大小的较小值
vs中默认8,linux默认4
3. 结构体总大小为最大对齐数(每个成员变量除了第一个成员都有个对齐数)的整数倍
4. 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍出,结构体的整体大小就是所有最大对其数(含嵌套结构体的对齐数)的整数倍
struct A
{
double d;
char c;
short s;
dpuble d2;
};
int main()
{
printf("%d",sizeof(struct A));//24
printf("%d",offsetof(struct A,d));//0
}offsetof是求每个类型对其的地址
本文出自 “无以伦比的暖阳” 博客,请务必保留此出处http://10797127.blog.51cto.com/10787127/1726525
原文地址:http://10797127.blog.51cto.com/10787127/1726525