struct结构体数据类型

前言

我们知道,在C语言中有一些基本的数据类型,如char

int

float

long

double

string(c99)

等等数据类型,他们可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,这时候C提供了一种自定义数据类型,他可以封装多个基本数据类型,这种数据类型叫结构体,英文名称struct,可以使用struct关键词声明结构体

结构体的声明

结构体的声明语法如下struct [structure tag] /*结构体的标签*/{

member definition; /*零个或多个成员变量的定义*/

member definition;

...

member definition;

} [one or more structure variables];  /*一个或多个结构体变量的定义*/

结构体标签(structure tag)是可选的,但是推荐还是写上,这样使得代码更加规范清晰,成员变量的定义一般为基本数据类型,如 int age; char name[10]等,成员变量之间使用;隔开,最后一个成员变量后面的;可选, 如下面定义一个图书信息的结构体变量struct Books {

char  title[50];   char  author[50];   char  subject[100];   int   book_id;

} book;

如下所示struct Books {

char  title[50];   char  author[50];   char  subject[100];   int   book_id

} book;

我省略了最后一个成员变量后面的分号;代码可以正常运行,但是当我使用gcc编译的时候,出现了下面信息gcc struct.c

outputstruct.c:8:1: warning: no semicolon at end of struct or union

} book;

^

这是警告提示,提示我们需要在struct和union数据类型定义的后面加上分号;,这样的好处就是当我们需要再添加一个成员变量的时候,只需写上该成员变量的定义,而无需先敲;,我太机智了,手动滑稽...

没有成员变量的结构体

我们也可以定义一个空的结构体,有时候我们需要某一个结构体数据类型,但是暂时又不知道如何填充里面的成员变量,我们可以有如下定义struct Books {

//TODO} book;

访问结构体成员

定义完结构体积后接下来就是去访问它并给他赋值,为了访问一个结构体成员变量,我们可以使用成员操作符(.) 成员访问运算符被编码为结构变量名称和我们希望访问的结构成员之间的句点(.)如下所示的完整代码

struct.c#include #include struct Books {

char  title[50];   char  author[50];   char  subject[100];   int   book_id;

};int main( ) {   struct Books Book1;        /* Declare Book1 of type Book */

struct Books Book2;        /* Declare Book2 of type Book */

/* book 1 specification */

strcpy( Book1.title, "C Programming");   strcpy( Book1.author, "Nuha Ali");   strcpy( Book1.subject, "C Programming Tutorial");

Book1.book_id = 6495407;   /* book 2 specification */

strcpy( Book2.title, "Telecom Billing");   strcpy( Book2.author, "Zara Ali");   strcpy( Book2.subject, "Telecom Billing Tutorial");

Book2.book_id = 6495700;   /* print Book1 info */

printf( "Book 1 title : %s\n", Book1.title);   printf( "Book 1 author : %s\n", Book1.author);   printf( "Book 1 subject : %s\n", Book1.subject);   printf( "Book 1 book_id : %d\n", Book1.book_id);   /* print Book2 info */

printf( "Book 2 title : %s\n", Book2.title);   printf( "Book 2 author : %s\n", Book2.author);   printf( "Book 2 subject : %s\n", Book2.subject);   printf( "Book 2 book_id : %d\n", Book2.book_id);   return 0;

}

编译并执行gcc struct.c && ./a.out

输出Book 1 title : C Programming

Book 1 author : Nuha Ali

Book 1 subject : C Programming Tutorial

Book 1 book_id : 6495407

Book 2 title : Telecom Billing

Book 2 author : Zara Ali

Book 2 subject : Telecom Billing Tutorial

Book 2 book_id : 6495700

结构作为函数参数

同样的,我们也可以像基本数据类型一样,把结构体作为函数的参数,如下所示我们定义一个打印结构体的函数#include #include struct Books {

char  title[50];   char  author[50];   char  subject[100];   int   book_id;

};/* function declaration */void printBook( struct Books book );int main( ) {   struct Books Book1;        /* Declare Book1 of type Book */

struct Books Book2;        /* Declare Book2 of type Book */

/* book 1 specification */

strcpy( Book1.title, "C Programming");   strcpy( Book1.author, "Nuha Ali");   strcpy( Book1.subject, "C Programming Tutorial");

Book1.book_id = 6495407;   /* book 2 specification */

strcpy( Book2.title, "Telecom Billing");   strcpy( Book2.author, "Zara Ali");   strcpy( Book2.subject, "Telecom Billing Tutorial");

Book2.book_id = 6495700;   /* print Book1 info */

printBook( Book1 );   /* Print Book2 info */

printBook( Book2 );   return 0;

}void printBook( struct Books book ) {   printf( "Book title : %s\n", book.title);   printf( "Book author : %s\n", book.author);   printf( "Book subject : %s\n", book.subject);   printf( "Book book_id : %d\n", book.book_id);

}

编译运行gcc struct.c && ./a.out

输出Book 1 title : C Programming

Book 1 author : Nuha Ali

Book 1 subject : C Programming Tutorial

Book 1 book_id : 6495407

Book 2 title : Telecom Billing

Book 2 author : Zara Ali

Book 2 subject : Telecom Billing Tutorial

Book 2 book_id : 6495700

结构体的指针

我们也可以定义结构体指针,像这样struct Books *struct_pointer;

现在你可以存放结构体变量的地址在结构体变量指针中.和基本数据类型的变量一样,我们使用&操作符取一个变量的地址struct_pointer = &Book1;

接下来就是使用结构体指针去访问成员变量了,访问的操作符我们由原来的.变为->,没错,这个是不是很形象呢?完整代码如下#include #include struct Books {

char  title[50];   char  author[50];   char  subject[100];   int   book_id;

};/* function declaration */void printBook( struct Books *book );int main( ) {   struct Books Book1;        /* Declare Book1 of type Book */

struct Books Book2;        /* Declare Book2 of type Book */

/* book 1 specification */

strcpy( Book1.title, "C Programming");   strcpy( Book1.author, "Nuha Ali");   strcpy( Book1.subject, "C Programming Tutorial");

Book1.book_id = 6495407;   /* book 2 specification */

strcpy( Book2.title, "Telecom Billing");   strcpy( Book2.author, "Zara Ali");   strcpy( Book2.subject, "Telecom Billing Tutorial");

Book2.book_id = 6495700;   /* print Book1 info by passing address of Book1 */

printBook( &Book1 );   /* print Book2 info by passing address of Book2 */

printBook( &Book2 );   return 0;

}void printBook( struct Books *book ) {   printf( "Book title : %s\n", book->title);   printf( "Book author : %s\n", book->author);   printf( "Book subject : %s\n", book->subject);   printf( "Book book_id : %d\n", book->book_id);

}

编译运行gcc struct.c && ./a.out

输出Book 1 title : C Programming

Book 1 author : Nuha Ali

Book 1 subject : C Programming Tutorial

Book 1 book_id : 6495407

Book 2 title : Telecom Billing

Book 2 author : Zara Ali

Book 2 subject : Telecom Billing Tutorial

Book 2 book_id : 6495700

结构体数组#include #include struct Books {

char  title[50];    char  author[50];    char  subject[100];    int   book_id;

};/* function declaration */void printBook( struct Books *book );int main( ) {    struct Books books[2];

/* book 1 specification */

strcpy( books[0].title, "C Programming");    strcpy( books[0].author, "Nuha Ali");    strcpy( books[0].subject, "C Programming Tutorial");

books[0].book_id = 6495407;    /* book 2 specification */

strcpy( books[1].title, "Telecom Billing");    strcpy( books[1].author, "Zara Ali");    strcpy( books[1].subject, "Telecom Billing Tutorial");

books[1].book_id = 6495700;    /* print Book1 info by passing address of Book1 */

printBook( &books[0] );    /* print Book2 info by passing address of Book2 */

printBook( &books[1] );    return 0;

}void printBook( struct Books *book ) {    printf( "Book title : %s\n", book->title);    printf( "Book author : %s\n", book->author);    printf( "Book subject : %s\n", book->subject);    printf( "Book book_id : %d\n", book->book_id);

}

编译运行gcc struct.c && ./a.out

输出Book 1 title : C Programming

Book 1 author : Nuha Ali

Book 1 subject : C Programming Tutorial

Book 1 book_id : 6495407

Book 2 title : Telecom Billing

Book 2 author : Zara Ali

Book 2 subject : Telecom Billing Tutorial

Book 2 book_id : 6495700

结构体的内存计算

没错,估计你已经知道了,结构体变量的所占用内存空间的大小为各成员变量所占空间之和,如下所示的结构体占用内存大小在注释里面#include #include struct Books {};int main( ) {    printf("%d\n", (int) sizeof(struct Books)); /*0*/

return 0;

}#include #include struct Books {

char title[50];    char author[50];    char subject[100];    int book_id;

};int main() {    printf("%d\n", (int) sizeof(struct Books)); /*204*/

return 0;

}

位域

有时候我们内存紧张的时候,我们可以使用位域定义结构体成员变量,比如当我们需要定义一个表示true或false的时候,如果想这样定义int isOpen;

明显很浪费空间,因为一个真假值只需要一个字位表示,所以我们可以这样定义unsigned int isOpen:1;

但是如果你直接写在函数中是会报错的,我们应该写在结构体中int main() {    unsigned int isOpen:1; /*编译无法通过*/

return 0;

}

正确姿势struct packed_struct {

unsigned int f1:1;   unsigned int f2:1;   unsigned int f3:1;   unsigned int f4:1;   unsigned int type:4;   unsigned int my_int:9;

} pack;

C尽可能紧凑地自动打包上述位字段,前提是字段的最大长度小于或等于计算机的整数字长。如果不是这种情况,那么一些编译器可能允许字段存储器重叠,而其他编译器会将下一个字段存储在下一个字中。#include #include struct packed_struct {

unsigned int f1:1;    unsigned int f2:1;    unsigned int f3:1;    unsigned int f4:1;    unsigned int type:4;    unsigned int my_int:9;

} pack;int main() {    printf("%d\n", (int) sizeof(struct packed_struct));    return 0;

}

作者:shellhub

链接:https://www.jianshu.com/p/d2c666527954

c语言事件结构体,C语言结构体史上最详细的讲解相关推荐

  1. C语言——史上最全通讯录讲解(附源码)

    C语言--史上最全通讯录讲解(附源码) 一.开始界面的打印 二.对六大板块进行定义操作 三.对联系人进行初始化 四.对通讯录进行初始化 4.1动态版本 4.2静态版本 五.通讯录六大功能的具体实现 5 ...

  2. R语言基础之第六部分 分类(史上最全含ddply、aggregate、split、by)

    R语言基础之第六部分 分类(史上最全含ddply.aggregate.split.by) 数据: 某市2014年-2018年空气质量指数日数据,需要按年分类计算每年 warm值为1和 0的均值. 数据 ...

  3. 史上最详细的DOM事件之拖动事件

    史上最详细的DOM事件之拖动事件 上篇博客讲了DOM的剪贴板事件,这篇博客我们来讲一讲DOM的拖动(DragEvent)事件. HTMl代码: <img src="../../CSS/ ...

  4. hashmap中的key是有序的么_美团面试题:Hashmap结构,1.7和1.8有哪些区别(史上最最详细解析)...

    作者|依本多情 原文:blog.csdn.net/qq_36520235/article/details/82417949 一.真实面试题之:Hashmap的结构,1.7和1.8有哪些区别 不同点: ...

  5. 二十万字带你入门C语言-史上最强C语言教程(汇总篇)

    一.前言 至此,史上最强C语言教程系列已经全部完成,今天是给大家来做一个汇总,笔者目前已经完成了C语言阶段的学习,一直以来感谢大家的陪伴与支持,笔者后续还会继续更新C++.数据结构.Linux.Mys ...

  6. c语言中结构体数组的引用,【C语言入门教程】7.2 结构体数组的定义和引用

    7.2 结构体数组的定义和引用 当需要使用大量的结构体变量时,可使用结构体定义数组,该数组包含与结构体相同的数据结构所组成的连续存储空间.如下例所示: struct student stu_a[50] ...

  7. 简单介绍C语言使用四种方法初始化结构体

    这篇文章说明了什么是结构体,介绍了结构体的概念和使用优点,在C语言中如何使用和初始化结构体方法,通过详细的代码展开进行说明,希望该篇文章对你有所帮助 什么是结构体 在实际问题中,一组数据往往有很多种不 ...

  8. C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?

    C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题? 问题1:结构体指针最开始怎么分配内存?用sizeof()是不能确定大小的. 问题2:给结构体变量分配之后,是否还要 ...

  9. 黑马程序员C语言基础(第八天)复合类型(自定义类型)(结构体)、共用体(联合体)、枚举enum、 typedef

    黑马程序员C语言基础(第一天) 黑马程序员C语言基础(第二天) 黑马程序员C语言基础(第三天) 黑马程序员C语言基础(第四天)数据类型 黑马程序员C语言基础(第五天)运算符与表达式.程序流程结构.数组 ...

最新文章

  1. linux下安装navicat并生成桌面图标
  2. Win10上运行Docker
  3. 8.1 模型压缩的方法
  4. CSS3学习笔记--line-height:150%与line-height:1.5的真正区别
  5. 回顾频谱图卷积的经典工作:从ChebNet到GCN
  6. .net中哈希表的使用 Hashtable
  7. 罗技鼠标驱动G HUB导致触摸板无法使用
  8. 使用Cubic定制ubuntu系统
  9. 如何在对方不知情的情况下定位微信好友
  10. js 色卡 (javascript 色卡 hsv 色卡 hsb 色卡)
  11. java进程、线程知识扩充
  12. 用FPGA加速卷积神经网络的知识储备
  13. 绿色数据时代,全闪存与数据中心的注定邂逅
  14. 天降大任与斯人也,成功是有原因的
  15. python基础实例教程 微课版-从零开始学Python(微课视频版)
  16. springboot-banner
  17. ASEMI肖特基二极管MBR40200PT参数,MBR40200PT规格
  18. 简单的菜单,进行修改menu4
  19. 三分钟理解RAFT光流网络中的Iterative Updates
  20. 原力计划来了【协作共赢 成就未来】

热门文章

  1. 永辉发布元宵数据:汤圆销售明显提升,多个民生产品增长超150%
  2. 新冠病例继续攀升 苹果关闭纽约市所有实体店
  3. 万达辟谣王健林去世:已报警!造谣账号已封禁
  4. 外媒:欧盟针对谷歌语音助手展开反垄断调查
  5. “羊毛党”玩脱了!90后员工用优惠券狂薅45万被捕
  6. 2020年苹果App Store销售额达6430亿美元 同比增长24%
  7. 国产Model 3高性能版规格公布:充电15分钟续航250公里
  8. 00后网购消费报告:超九成用户跟好友拼过单 手机数码花销最大
  9. 小爱同学生病了,网友集体表示理解:小爱同学好好休息
  10. 微信官方回应iOS 13.2频繁杀后台问题:建议先不升级