前言

我们知道,在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;

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

struct Books {//TODO
} book;

访问结构体成员

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

struct.c
#include <stdio.h>
#include <string.h>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;
}

结构体作为函数参数

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

#include <stdio.h>
#include <string.h>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);
}

结构体的指针

我们也可以定义结构体指针,像这样

struct Books *struct_pointer;

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

struct_pointer = &Book1;

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

#include <stdio.h>
#include <string.h>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);
}

结构体数组

#include <stdio.h>
#include <string.h>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);
}

结构体的内存计算

没错,估计你已经知道了,结构体变量的所占用内存空间的大小为各成员变量所占空间之和,如下所示的结构体占用内存大小在注释里面

#include <stdio.h>
#include <string.h>struct Books {
};int main( ) {printf("%d\n", (int) sizeof(struct Books)); /*0*/return 0;
}
#include <stdio.h>
#include <string.h>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 <stdio.h>
#include <string.h>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;
}

struct结构体数据类型相关推荐

  1. 1.0 基础、标示符、常量、数据类型(enum 枚举,struct 结构体)、操作符、循环、数组...

    一.程序 现实生活中,程序是指完成某些事务的一种既定方法和过程,可以把程序看成是一系列动作执行过程的描述. 在计算机世界,程序是指令,即为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集 ...

  2. c/c++教程 - 1.10 结构体 使用typedef定义struct结构体 结构体数组 结构体指针 结构体嵌套 结构体做函数参数 结构体const

    十二.结构体 (1)结构体定义和使用 基本概念:结构体属于用户自定义的数据类型,允许用户存储不同的数据类型. 参考视频:https://www.bilibili.com/video/BV1et411b ...

  3. Go语言核心之美 3.4-Struct结构体

    struct(结构体)也是一种聚合的数据类型,struct可以包含多个任意类型的值,这些值被称为struct的字段.用来演示struct的一个经典案例就是雇员信息,每条雇员信息包含:员工编号,姓名,住 ...

  4. Hive基础08、Hive引入Struct结构体

    Hive基础08.Hive引入Struct结构体 1.建表语句 创建一个温良贤淑女子的表 英文关键字解析: 1.CREATE TABLE 创建一个指定名字的表,如果库中已有相同名的表,则抛出异常: 用 ...

  5. (转载)虚幻引擎3--【UnrealScript教程】章节一:11.Struct结构体

    UnrealScript struct是把一组变量一起塞入到一个新类型称为struct的超级变量的一种方法.UnrealScript structs和C语言中的结构体很像,它可以包含变量.数组及其它的 ...

  6. go中Struct 结构体详解

    目录 一.结构体定义 1.结构体的定义 2.结构体字段的可见性 3.结构体的匿名字段 二.结构体实例化 1.基本实例化 2.针类型实例化 3.取地址实例化 三.结构体初始化 1.两种初始化的方式 2. ...

  7. Golang 基础知识(十一.struct结构体)

    struct结构体 1.定义 2.匿名结构体 3.键值对初始化 4.构造函数 4.1 (值)方法和接收者 4.2 (指针)方法和接受者 4.3 结构体的"继承 4.4 序列化与反序列化 4. ...

  8. c语言struct的作用和用法,c语言中的关键字struct(结构体)的用法

    在iOS开发中,结构体是经常用到的数据类型,使用频率不亚于指针,所以需要重视. 当一个整体由多个数据构成时,我们可以用数组来表示这个整体,但是数组有个特点:内部的每一个元素都必须是相同类型的数据.然而 ...

  9. 【C语言笔记】struct结构体变量的用法

    我们都知道C语言中变量的类型决定了变量存储占用的空间.当我们要使用一个变量保存年龄时可以将其声明为int类型,当我们要使用一个变量保存某一科目的考试成绩时可以将其声明为float. 那么,当我们要做一 ...

最新文章

  1. MySql按周,按月,按日分组统计数据
  2. 《圣洁》的读后感作文3000字
  3. impala元数据放到mysql_impala系列: 同步Hive元数据和收集统计信息
  4. dojo中的dojo/dom-attr
  5. java 序列化实例_Java中的序列化与反序列化实例
  6. 伪原创工具安全第一嘛~~
  7. java当前目录指什么_是什么决定了Tomcat Java进程的当前工作目录?
  8. 关于telnet的问题
  9. 《Spring Boot实战》读书笔记
  10. Python day17 模块介绍1(time,random)
  11. BAT经典面试题,深入理解Java内存模型JMM
  12. vue+nodejs+element 实现drawio绘图效果
  13. win10中鼠标点右键或者重命名文件夹系统卡顿解决方法
  14. linux逻辑分区如何创建,linux 创建扩展分区以及逻辑分区
  15. Cartopy绘图入门指南
  16. 阿里云ACE北京同城会-景山活动
  17. OCJP(1Z0-851) 模拟题分析(二)
  18. 用Matlab计算多项式的值
  19. ogg如何转换成mp3格式?
  20. 【cadence 16.6】PSPICE如何添加SPICE模型

热门文章

  1. springboot mybatis 项目框架源码 shiro 集成代码生成器 ehcache缓存
  2. AppStore 拒绝审核原因:PLA 2.3
  3. CJIS安全政策:企业如何确保FIPS合规性?
  4. 一起感受不一样的项目沙盘
  5. css3效果: animate实现点点点loading动画效果(一)
  6. 深入浅出 消息队列 ActiveMQ(转)
  7. 【转载】Deep learning:十九(RBM简单理解)
  8. [项目实施失败讨论Case] “凭心而论,在这家公司很敬业的工作了3年多,老板最后给我下的评语,大家都看看吧,千万别和我走同一条路!”(摘自csdn)...
  9. [物理学与PDEs]第2章习题参考解答
  10. KOFLive Beta 下载情况及用户反馈