目录
结构体:(构造类型/用户自定义类型)
作用:用来描述复杂数据的一种数据类型。
1.怎么描述一个数据类型:
1.构造语法:
struct 结构体类型名 //struct关键字:表示在构建一个结构体的类型
{ //结构体类型名:用来描述结构体这一个类型的名称
成员列表; //成员列表:表示要描述的复杂数据中要用到的具体的成员变量
};(结束时用分号隔开) //定义的方式与之前变量的方式相同
//多个成员变量之间用分号隔开
(一般定义类型写在全局区)
eg:
struct student
{
char name[10];
int sno;
float score;
char sex[10];
}//表示定义一个数据类型:1.可定义变量 2.可定义指针变量 3.定义数组
2.定义变量语法:
struct 结构体名 (结构体类型) 变量名
3.结构体初始化:
struct student s = {"tom",211,70,"male"};
看每个所要使用到的成员变量具体是什么类型的。
根据各个成员变量自身的数据类型来进行初始化。
初始化的顺序按照定义的顺序,依次初始化。各个成员之间以,
隔开
4.结构体变量的引用:
结构体变量引用时,一般是应用到具体的成员数据。
应用到成员:
应用方法:借助.
运算来进行运用(.
含义指的是访问下级内容.可以理解为 “什么的(.
)什么”)
5.结构体指针:
结构体指针一般用来结合结构体数组使用
其结构体指针的定义方式:
struct 结构体名称 * 指针名
eg:
struct student//定义结构体
{
char[10] name;
int sno;
float score;
};
struct student s[10];//定义结构体数组
struct student *p = s;//定义结构体指针,并将其指向结构体数组。
如何使用结构体指针:
借助运算符:->
使用方法:
结构体指针 -> 结构体内部成员变量//表示从地址直接访问结构体内的成员变量
eg:
p->name //表示直接访问上面定义的结构体数组的第一个元素中的name成员变量,由于name表示的是字符数组。
//因此其表示访问的是name的首地址。如果要详细访问某个字符,则取以下形式:
p->name[i]//i表示要访问的字符的下标
6.结构体类型的定义方式:
形式1.先定义类型后定义变量
struct 类型名
{
成员列表:
};
struct 类型名 变量名 = {初始化内容};
形式2.同时定义类型和初始化(可以多次定义变量):
struct 类型名
{
成员列表:
};变量名 = {初始化内容};
形式3.定义类型的同时定义变量并忽略结构体类型名(其表示该数据类型在c文件中只使用一次,及只能定义一次该类型变量)
struct
{
成员列表:
};变量名 = {初始化内容};
注意:多次使用结构体的情况时,应将结构体放在全局变量区,不然在局部变量区会造成全局区使用该结构体类型时不被编译器识别。
7.结构体类型的大小:
结构此储存的原则:
内存对齐
结构体对齐的规则:
对齐指的是内存地址的对齐(对齐指的是整个结构体的空间字节数能成员变量类型的字节数整除)
1.对于整个结构体:在32位的平台上默认为按4字节对齐
2.对于成员变量:
各自在自己的自然边界上对齐。
char——以一个字节对齐
short——以2个字节对齐
int——以四个字节对齐
3.如果成员变量中有比四字节大的,那么整个结构体以4字节对齐//(在32位的平台之中)
4.如果成员变量没有超过4字节的,那么整个结构体以成员变量中最大对齐。
总结:
1.32位平台中:
没超过4字节,以最大的成员变量对齐,超过4字节,则按照四字节对齐。
2.64位平台中,没超过4字节的,按成员变量中最大的对齐
超过4字节的,按照结构体内最大字节的类型来对齐
8.同类型结构体变量之间可以互相赋值:
struct student s0;
struct student s1;
s0 = s1;//将相同结构体类型s1赋值给s0
数组排序qsort函数:
基本形式:
void qsort(void *base, size_t nmemb,size_t size,
int (*compar)(const void *,const void *))
//void *base指的是所要比较数组的首地址
//size_t nmemb 指的是数组的元素个数
//size_t size 指的是该数组一个元素占几个字节
//int (*compare)(const void*,const void *)指的是回调比较函数,其中回调函数需要我们自己写,函数名可任取,不一定是compare,然后将函数名放到最后一个位置,括号内部的void *空指针不用处理,只是在写函数的时候类型要写上。
int compar(const void *p,const void *q)
{
比较函数(诸如相减或是相除等运算用于返回一个int型的值来衡量)
形参p和q用来接收要比较的两个数组元素
}
在使用中需要对两个形参const void *p,const void *q进行转换,你所要比较的数组元素的数据类型是什么,那么你就要转换成什么类型的指针。
eg:
若要排列整形数组的大小
int a[4];
int compar(const void *p,const void *q)
{
const int *a = p;//将接收的指针转换成数组元素的形式
const int *b = q;//同上
return *a-*b;//返回一个两个数组元素相减后的值,作为大小的判断依据(该顺序是从小到大)
}
完整使用代码举例:
#include<stdio.h>
2 #include<stdlib.h>
3
4 int compar(const void *a,const void *b)
5 {
6 const int *p = a;
7 const int *q = b;
8 return *p - *q;
9 }
10
11 int main(int argc, const char *argv[])
12 {
13 int i;
14 int a[10] ={2,4,6,9,3,7,0,12,18,11};
15
16 qsort(a,10,sizeof(int),compar);
17
18 for(i = 0;i < 10;i++)
19 {
20 printf("%d ",a[i]);
21 }
22 return 0;
23 }
共用体:
定义:
共用一块空间的数据类型,公用的空间是最大数据类型的那一块空间。
语法:
union 共用体名
{
成员变量;
};
eg:
union demo
{
char a;
short b;
int c; //三个成员变量共用一个最大数据类型的空间(即int型的4字节)
}
注意事项:
1.共用体初始化时只能给到一个值,其默认给到第一个成员之中。
2.共用体变量中的值,只取决于最后一次给其的值。由于共用一块空间,所以还要看所给的这个值会更改几个字节空间里面的数据
对比结构体:
1.结构体每个成员有独立的空间。
2.公用体中,每一个成员公用同一个空间。