# 一、本章重点

1. 创建结构体
2. typedef与结构体的渊源
3. 匿名结构体
4. 结构体大小
5. 结构体指针
6. 其他

# 二、创建结构体

``````struct people
{
int age;
int id;
char sex[5];
};//不要少了分号。``````

?那么这样创建结构体呢？

``````struct phone
{
char brand[10];//品牌
int price;//价格
};

struct people
{
int age;
int id;
char sex[5];
struct phone;
};``````

``````struct people
{
int age;
int id;
char sex[5];
char phone_brand[10];
int phone_price;
};``````

?结构体能够嵌套另一结构体，那么结构体能否嵌套自己呢？

``````struct phone
{
char brand[10];
int price;
struct phone;
};``````

?原因是什么呢？

?在提一个问题，结构体是否可以嵌套自己的结构体指针呢？

``````struct people
{
int age;
int id;
char sex[5];
struct people* son[2];
};``````

# 三、typedef与结构体的渊源

``````struct people
{
int age;
int id;
}a;//a代表什么？

int main()
{
a.age = 20;
printf("%dn", a.age);
return 0;
}``````

?提问：a代表什么？

``````struct people{int age;int id;} a;

int main()
{
a.age = 20;
printf("%dn", a.age);
return 0;
}``````

``````int b;
struct people{int age;int id;} a;

int main()
{
a.age = 20;
printf("%dn", a.age);
return 0;
}``````

``````typedef struct people
{
int age;
int id;
}a;

int main()
{
a.age = 20;
printf("%dn", a.age);
return 0;
}``````

?此时加上typedef，a还能当结构体创建的变量吗？

理解方式以上述一致。

``typedef struct people{int age;int id;} a;``

``````typedef struct people{int age;int id;} a;
typedef int b;``````

typedef的作用是把struct people{int age;int id;}这一类型重命名为a。

``````typedef struct people
{
int age;
int id;
}b,a,*c;

int main()
{
a a1;
b b1;
c c1 = &a1;
a1.age = 5;
b1.age = 6;
c1->age = 10;
printf("%d %d %dn", a1.age, b1.age, c1->age);
return 0;
}``````

?你知道运行结果吗？

``````typedef struct people
{
int age;
int id;
}b, a, c[20];

# 四、匿名结构体

``````struct
{
int age;
int id;
};

int main()
{
struct p1;
p1.age = 10;
printf("%dn", p1.age);
return 0;
}``````

``````struct
{
int age;
int id;
}p1;

int main()
{
p1.age = 10;
printf("%dn", p1.age);
return 0;
}``````

接下来我们看下这段代码

``````typedef struct
{
int age;
int id;
}people;

int main()
{
people p1;
p1.age = 10;
printf("%dn", p1.age);
return 0;
}``````

``````//匿名结构体类型
struct
{
int a;
char b;
float c;
}x;

struct
{
int a;
char b;
float c;
}a[20], *p;

int main()
{
//在上面代码的基础上，下面的代码合法吗？
p = &x;
return 0;
}``````

# 五、结构体大小

?如何求结构体类型的大小？

?你知道下面这段代码的运行结果吗？

``````struct people
{
char a;
int b;
char c;
};

int main()
{
struct people p1;
printf("%dn", sizeof(p1));//大小是6吗？
return 0;
}``````

char是一字节大小

int是四字节大小

char是一字节大小

?那么这个结构体的大小是6吗？

? 这是为什么呢？

?什么是内存对齐？

?为什么要内存对齐？

1.不是所有的硬件平台都能访问任意地址上的任意数据的；
2.某些硬件平台只能在某些地址处取某些特定类型的数据，否则抛出硬件异常。

?️对齐规则：

Windows中默认对齐数为8，Linux中默认对齐数为4

：最后结构体的大小需要调整为最大对齐数的整数倍。

``````struct people
{
char a;
int b;
char c;
};``````

?️解析：

4是4的整数倍，所以在偏移地址为4处开始放数据。

8是1的整数倍，从偏移地址为8的位置开始放。

``````struct people
{
char a;
char c;
int b;
};

int main()
{
struct people p1;
printf("%dn", sizeof(p1));//大小是多少呢？
return 0;
}``````

?️解析：

再来看看下面这个如何？

``````struct people
{
char a;
int b;
short c[2];
char d;
};

int main()
{
struct people p1;
printf("%dn", sizeof(p1));//大小是6吗？
return 0;
}``````

?️解析：

# 六、结构体指针

``````struct people
{
char a;
int b;
};``````

``````int main()
{
struct people p1;
struct people* p = &p1;
return 0;
}``````

?访问变量方式1：

``````int main()
{
struct people p1;
struct people* p = &p1;
p1.a = 'a';
p1.b = 10;
printf("%c %dn", p1.a, p1.b);
return 0;
}``````

?访问变量方式2：

``````int main()
{
struct people p1;
struct people* p = &p1;
p->a = 'a';
p->b = 10;
printf("%c %dn", p->a, p->b);
return 0;
}``````

?访问变量方式3：

``````int main()
{
struct people p1;
struct people* p = &p1;
(*p).a = 'a';
(*p).b = 10;
printf("%c %dn", (*p).a, (*p).b);
return 0;
}``````

THE END