目录
定义一个结构体
先温习一下之前学过的#define和enum枚举类型:
#define MAN 'M'
#define WOMAN 'W'
typedef enum card {SFZ,XSZ,JSZ,JGZ} CARD;
创建结构体变量:
struct stu_info
{
unsigned int stuNum;//学号
CARD cardType;//证件类型
char cardNum[20];//证件号码
char name[20];//姓名
char sex;//性别'M''W'
} stu1 ;
创建结构体变量并赋初值:
struct stu_info stu2 = { 1,SFZ,"230281200307123245","张三",MAN };
存取结构体成员值 用.操作符:
stu1.stuNum = 2;
stu1.cardType = XSZ;
//stu1.cardNum = "13234324552";
strcpy(stu1.cardNum, "1234324324");
strcpy(stu1.name, "小美");
stu1.sex = WOMAN;
注:不能直接给数组名赋值,因为数组名是一个地址常量,要通过strcpy来赋值。
输入 输出:
struct stu_info stu3;
scanf_s("%u%d%s%s"
, &stu3.stuNum
, &stu3.cardType
, stu3.cardNum, 20
, stu3.name);
getchar();
stu3.sex = getchar();
定义一个结构体 用typedef重命名
typedef struct book
{
double price;//价格
int year;//印刷年代
char bookName[50];//书名
char* author;//作者
} BOOK;
结构体数组:
创建结构体数组变量:
BOOK books[5] = { { 23.8,2010,"龙族","江南"},
{56.8,2008,"三体","刘慈欣"},
{ 99,2000,"C++primer ","Colin"},
{23.87,2000,"流浪地球","刘慈欣"},
{10,2003,"阿衰","猫小乐"}};
排序:
BOOK temp;
for (int suo = 0; suo < 5 - 1; suo++)
{
for (int bi = suo + 1; bi < 5; bi++)
{
if (books[suo].price < books[bi].price
||books[suo].price < books[bi].price
&& strcmp(books[suo].author, books[bi].author) < 0)
//if(strcmp(books[suo].author,books[bi].author)<0)
{
temp = books[suo];
books[suo] = books[bi];
books[bi] = temp;
}
}
}
打印:
for (int i = 0; i < 5; i++)
{
printf("%-7.2f %4d %-10s %-10s\n", books[i].price, books[i].year, books[i].bookName, books[i].author);
}
结构体指针
直接封装BOOK*:
typedef struct book
{
double price;//价格
int year;//印刷年代
char bookName[50];//书名
char* author;//作者
} BOOK,*P_BOOK;//直接封装BOOK*
BOOK books[5] = { { 23.8,2010,"龙族","江南"},
{56.8,2008,"三体","刘慈欣"},
{ 99,2000,"C++ primer ","Colin"},
{23.87,2000,"流浪地球","刘慈欣"},
{10,2003,"阿衰","猫小乐"} };
创建结构体指针数组并指向结构体:
P_BOOK pbooks[5];
for (int i = 0; i < 5; i++)
{
pbooks[i] = &books[i];
}
通过结构体指针打印:
for (int i = 0; i < 5; i++)
{
printf("%-12s %-12s %4d %7.2f\n", pbooks[i]->bookName, pbooks[i]->author, pbooks[i]->year, pbooks[i]->price);
}
利用指针数组排序:
P_BOOK temp;
for (int suo = 0; suo < 5 - 1; suo++)
{
for (int bi = suo + 1; bi < 5; bi++)
{
//if ( books[suo].price < books[bi].price )
if (pbooks[suo]->price < pbooks[bi]->price
|| pbooks[suo]->price < pbooks[bi]->price
&& strcmp(pbooks[suo]->author, pbooks[bi]->author) < 0
) //按作者的升序排序 作者相同按价格降序排序
{
temp = pbooks[suo];
pbooks[suo] = pbooks[bi];
pbooks[bi] = temp;
}
}
}
打印:
printf("\n排序后:\n");
for (int i = 0; i < 5; i++)
{
printf("%-12s %-12s %4d %7.2f\n", pbooks[i]->bookName, pbooks[i]->author, pbooks[i]->year, pbooks[i]->price);
}
结构体指针的几种创建方法:
struct book* p1 = books;
BOOK* p2 = &books[1];
P_BOOK p3 = books + 2;
使用指针操作结构体成员:
方式一: (*指针).成员
方式二: 指针 -> 成员 推荐
printf("%s\n", (*p1).bookName);
printf("%s\n", p2->bookName);
printf("%s\n", p3->bookName);//vs中可以将.自动转换为->
结构体对齐
在结构体创建时会有一个对齐不齐的准则,他会选出所使用的数据类型中字节数最大的类型作为标准,并以它的字节数为一个单位,在创建空间时,如果某类型小于单位剩余字节数,那可以直接将这个类型在该单位的空间中创建,如果大于剩余字节数,那么就会再创建一个单位空间对其进行存储。要注意的是,数组的字节数是以它其中一个成员的字节数为标准的。对齐补齐的意义就是可以节省空间,提高空间使用效率。比如图中这个,这些数据类型最大字节数为4,所以一个单位空间就是四个字节,那么我们可以看到第二排剩余一个字节的空间,而最后一排只使用一个字节,如果将最后一排的char类型放在第二排进行创建,那么就会节省四个字节的空间。
#include <stdio.h>
struct AA
{
int a;
short c;
char b;
} ;
struct HH
{
int a;
short c;
char b;
short d;
char e;
short f;
} ;
struct HH2
{
int a;
short c;
short d;
char e;
char b;
short f;
} ;
struct FF1
{
char a[5];
char *e;
} ;
struct FF2
{
char a[5];
char *e;
} ;
测试不同结构体的空间大小:
int main ()
{
//测试不同结构体的空间大小
printf("%d\n",sizeof(struct AA));
printf("%d\n", sizeof(struct HH));
printf("%d\n", sizeof(struct HH2));
return 0;
}
结构体与堆内存
定义结构体指针:
BOOK book = {10,2010,"C语言","谭浩强"};//被创建在栈区
P_BOOK p = NULL;//也是在栈区创建
在堆内存中 创建结构体空间 并由指针指向:
p = (P_BOOK)malloc(sizeof(struct book));
利用指针处理堆空间的结构体:
p->price = 25;
//(*p).price = 30;
strcpy(p->bookName, "C++");
最后一定要记得释放堆空间中的结构体,否则会产生碎片
free(p);
p = NULL;
结构体位域使用
结构体位域 应用于嵌入式领域居多
定义一个结构体:
typedef struct
{
int a:2;//a变量占两个位的存储空间 但int会分配4个字节。
int b:8;
int c:2;
int :0;//断开
int d:2;
} TT;
int main ()
{
TT t ;
t.a = 1;
t.b = 2;
t.c = 3;
t.d = 4;
printf("%d\n",sizeof(TT));
printf("%d %d %d %d\n", t.a, t.b, t.c, t.d);
return 0;
}
结构体的嵌套
正常定义一个结构体:
typedef struct book
{
int price;
char* name;
} Book;
结构体当中含有结构体:
typedef struct
{
int age;
char *name;
Book book;//结构体当中含有结构体
} Student;
struct new_stu
{
int age;
char* name;
struct
{
int price;
char* name;
} book;
};
得到嵌套结构体内的成员,继续 . 运算:
Student s={ 20,"张三",{12,"如来神掌"} };
struct new_stu s2= { 20,"张三",{12,"如来神掌"} };
printf("书名:%s\n",s.book.name);//得到嵌套结构体内的成员,继续 . 运算
printf("价格:%d\n",s.book.price);
printf("书名:%s\n", s2.book.name);//得到嵌套结构体内的成员,继续 . 运算
printf("价格:%d\n", s2.book.price);