《C语言结构体史上最详细的讲解》

【结构体类型——详细讲解】 一篇就会让你学懂结构体类型!!! 阅读详情

原文链接

https://github.com/shellhub/blog/issues/40

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

output

struct.c:8:1: warning: no semicolon at end of struct or union
 } book;
 ^

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

没有成员变量的结构体

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

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;
}

编译并执行

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 <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);
}

编译运行

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 <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);
}

编译运行

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 <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);
}

编译运行

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 <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;
}

输出结果
8

C语言——结构体(全) 一、结构体的设计 C语言提供了基本的数据结构,例如 char 、short 、int 、float....等类型;这些偶称为内置类型。怎样设计出来属于自己的类型? 程序员可以使用结构体来封装一些属性,设计出新的类型,在C语言中称为结构体类型。 结构体的定义形式为 struct 结构体名 { 成员列表(可以是基本的数据类型,指针,数组或其他结构类型) }; 举个例子来说吧; 客观事务(实体)是复杂的,要描述它必须从多方面进行;也就是用不同的数据类型来描述不同的方面;用学生实体来说: .. 阅读详情

相关推荐

【C语言】结构类型的定义和使用

结构体(struct)类型;结构标记;typedef;将结构体传入函数;定义结构数组的方法;调用结构数组的方法

小人物,大梦想! 2478

数据结构结构不同,分配的大小不一定一样

<br />#include <stdio.h><br />struct fir<br />{<br />    char a;<br />    int b;<br />    char c<br />}fir;<br />struct tw<br />{<br />    char ab;<br />    char bb;<br />    int  cb<br />}tw;<br />int main(void)<br />{<br />int dd;<br />int cc;<br />dd=si

benico的专栏 1328

基于FaceX-Zoo实现的Face Mask Adding人脸戴口罩

人脸系列文章目录 文章目录人脸系列文章目录前言一、加口罩效果二、实现原理二、代码实现 前言 目前人脸加口罩均为在人脸位置贴图式的,非常不真实。前段时间京东开源一个基于PRnet实现的3D口罩拟合人脸,加口罩非常逼真,但是只是单独一个加口罩demo,没有完整的流程。于是本人结合人脸检测,关键点对齐。PRnet加口罩实现一个完整的加口罩流程。只需一个命令简单方便调用,实现人脸加口罩。 https://github.com/JDAI-CV/FaceX-Zoo 一、加口罩效果 下图可以看出效果还是非常逼真的

zengwb的博客 3390

关于RA编译的一些问题记录

1、使用cygwin下载的SDL库文件,存在错误: "Couldn't initialize SDL: No available video device";这个应该是cygwin的库里SDL与操作系统不匹配造成的。 解决方法:先在cygwin中安装一次,然后在http://www.libsdl.org/download-1.2.php上下载”SDL-devel-1.2.15-mingw32

zzcc209的专栏 647

AI医疗影像诊断工具2025 完整教程

本教程所述工具均为辅助诊断设备,不可替代执业医师判断。部署使用需遵守当地医疗器械管理法规。推荐开源框架组合:代码太多打包上传网盘了 自行下载。2025年的AI医疗影像诊断工具将以。

m0_60084632的博客 2029

比较器和运算放大器-2

今天继续了解输入阻抗问题,观察下图:首先考虑在我们没有接运放时,A点输出电压为6V,当接入如图所示的阻抗时电压还是6V吗?共模电阻和红框内对地电阻并联,阻值变小,相当于5k,通过计算可以求得A点电压变为4V,这样A的值发生了改变,试想一下这样的信号接入到运放的两端是不是相当于比较的两端信号发生了改变,那结果一定会发生偏离。信号源一般内阻是不确定的,一般也不是很小,如果不想改变输入阻抗,那唯一的办法就是改变运放的内阻了,比如内阻改为100K,1M等,越大越好,是不是A点电压就会无限接近6V。

weixin_42855218的博客 1312

C语言struct 函数,C语言结构体史上最详细的讲解

原文链接struct结构体数据类型前言我们知道,在C语言中有一些基本的数据类型,如charintfloatlongdoublestring(c99)等等数据类型,他们可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,这时候C提供了一种自定义数据类型,他可以封装多个基本数据类型,这种数据类型叫结构体,英文名称struct,可以使...

weixin_42200829的博客 1万+

frp内网穿透(socks隧道)

在实验过程中还是遇到了挺多的问题,但好在大多都解决了。不过还是遗留了一些不懂的问题,等以后再慢慢研究了。最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

2301_76227305的博客 1万+

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

struct结构体数据类型前言我们知道,在C语言中有一些基本的数据类型,如charintfloatlongdoublestring(c99)等等数据类型,他们可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,这时候C提供了一种自定义数据类型,他可以封装多个基本数据类型,这种数据类型叫结构体,英文名称struct,可以使用str...

weixin_39980929的博客 322

手把手教你用ObjectCRX进行Caxa二次开发:从零开始的环境搭建教程

本文是一份面向零基础初学者的Caxa二次开发实战指南,重点讲解如何使用ObjectCRX框架从零开始搭建开发环境。内容涵盖Visual Studio 2015版本锁定、ObjectCRX向导集成、项目创建、典型错误解决,并最终实现一个可在Caxa中运行的HelloWorld程序,帮助开发者快速入门并避开常见陷阱。

w3x4y的博客 513

5实践报告撰写

一 项目流程 明确标准 确定分析目标 寻找分析数据 清洗数据 描述性分析 诊断性分析 提出建议 撰写报告 二 确定分析目标 什么是你感兴趣的? 什么是你熟悉的? 什么是你擅长的? 1 电商零售行业 商品销量分析 价格分析 评价分析 ...... 2 自媒体行业 广告投放力度分析 广告投放回报分析 不同类型的产品分析 ...... 3 金融行业 股票价格分析 信贷业务违约分析 客户画像分析 ...... ...

waywardG的博客 2833

c语言在结构体之前定义变量,C语言结构体史上最详细的讲解

struct结构体数据类型前言我们知道,在C语言中有一些基本的数据类型,如charintfloatlongdoublestring(c99)等等数据类型,他们可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,这时候C提供了一种自定义数据类型,他可以封装多个基本数据类型,这种数据类型叫结构体,英文名称struct,可以使用str...

weixin_39956022的博客 325

点云语义分割:RandLANet模型推理C++部署(2)

一、数据读取及预处理 二、模型推理 三、结果保存

zhaoguanhua的博客 3800

c语言饿结构_《C语言结构体史上最详细的讲解》

结构体struct · Issue #40 · shellhub/blog​github.comstruct结构体数据类型前言我们知道,在C语言中有一些基本的数据类型,如 char int float long double string(c99)等等数据类型,他们可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,这时候C提...

weixin_35664081的博客 187

QT+QGIS跨平台编译(基于Qt,采用一套代码、一套框架,完成QGIS第三方库、核心库、应用程序的跨平台编译)

QT+QGIS跨平台编译。 基于Qt,采用一套代码、一套框架,完成QGIS第三方库、核心库、应用程序的跨平台编译。

LuckyHanMo的博客 4379

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C语言:结构体(详细讲解)

位段的声明和结构是类似的,有两个不同:1. 位段的成员必须是 int、unsigned int 或signed int ,在C99中位段成员的类型也可以选择其他类型。2. 位段的成员名后边有⼀个冒号和⼀个数字。int _b : 5;int main()

qq_67578580的博客 1608

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

关于我终于拿捏了C语言结构体那点事 ——超详细的C语言结构体讲解

这里有超详细的C语言结构体讲解,带你轻松拿捏C结构体

这是一个非常有意思的博主 2561

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C语言指针讲解(史上最全面最经典)

前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: int p; //这是一个普通的整型变量 int * p; //首先从P 处开始,先与结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int

weixin_45041038的博客 4236

C语言指针,这可能是史上最干最全的讲解啦(附代码)!!!

点击上方“大鱼机器人”,选择“置顶/星标公众号”福利干货,第一时间送达!指针对于C来说太重要。然而,想要全面理解指针,除了要对C语言有熟练的掌握外,还要有计算机硬件以及操作系统等方方面面...

张巧龙的博客 8814

C语言结构体总结(详细,直观,全面)

新年必看的一篇结构体文章

weixin_73233099的博客 7242

【初始C语言8】详细讲解初阶结构体的知识

💓作者简介: 加油,旭杏,目前大二,正在学习C++数据结构等👀加油,旭杏的主页👀再识C进阶的专栏👀旭日东升 1👀💖。

加油,考上985的研究生 2537

全面讲解 C 语言的结构体(struct),一网打尽

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删结构体的定义结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。结构体和其他类型基础数据类型一样,例如 int 类型,char类型;只不过结构体可以做成你想要的数据类型,以方便日后的使用。在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新...

轻松学C语言 1万+

【C语言】结构体详细讲解

结构体声明、结构体变量定义及初始化、结构体的自引用、结构体内存对齐、结构体传参、修改默认对齐数

2301_79755897的博客 1269

C语言超详细结构体知识

本文主要介绍了结构体的基本使用,包括创建,声明,初始化,访问操作等,以及结构体如何在内存中进行存储,结构体传参方法优劣,结构体实现位段等知识。

2302_79963723的博客 2320

【C语言】结构体

struct — 结构体的关键字。 student —结构体的标签,可以随意的替换看你指向的对象是谁了。 structstudent ——叫做结构体类型。 大括号 { }里面的内容被称作是:成员变量, 注意大括号后面必须要有分号,可以加成员列表,分号前面内容,可以是全局的结构体变量(一般都不会去使用),在代码中我们要尽可能的去少的使用全局变量。 在函数中 mation —— 结构体类型的变量,当然这里我直接student mation;是可以的,因为我用了typedef关键字,当然这个是可 ......

"謓泽"正在路上朝着"攻城狮"方向"前进四"! 4240

【C语言】——结构体

摘要,写什么好呢?

yusjushd的博客 1846
上一篇: Android网易云历史搜索和热门标签
下一篇: C语言switch史上最详细的讲解
ishellhub
博客等级 码龄9年 102粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值