原文链接

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

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

}

输出结果

8

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

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

    struct结构体数据类型 前言 我们知道,在C语言中有一些基本的数据类型,如char int float long double string(c99) 等等数据类型,他们可以表示一些事物的基本属性 ...

  2. C语言中函数如何返回结构体?

    //#include "stdafx.h"//If the vc++6.0, with this line. #include "stdio.h" #inclu ...

  3. C语言struct关键字详解—结构体

    struct 是个神奇的关键字,它将一些相关联的数据打包成一个整体,方便使用. 在网络协议.通信控制.嵌入式系统.驱动开发等地方,我们经常要传送的不是简单的字节流(char 型数组),而是多种数据组合 ...

  4. C语言struct 函数,c语言struct的用法

    C语言中先申明结构体,也就是定义结构体具体形式,而后可以把它当做普通数据类型来修饰变量,也可以在定义类型时后面直接跟着定义几个变量,下面小编就为你介绍c语言struct的用法. 基本定义:结构体,通俗 ...

  5. C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐,结构体对齐)offsetof()函数 ( (struct X*)0 ) -> Y)语法(匿名结构体)

    示例: typedef struct _user {char name[20];char sex[20];int age;struct list_head mylist;//自定义结构体里保存双向循环 ...

  6. 【☀️C语言函数传参の结构体数组篇☀️】

    背景介绍 C语言中函数参数传递的两种方式("引用传递做函数参数"是C++的特性,C语言不支持.) (1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个 ...

  7. 【RTOS训练营】课程学习方法和C语言知识(指针、结构体、函数指针、链表)和学员问题

    一.课程学习方法 因为有些学员是刚进群,所以这里再把学习方法讲一下. 1. 预习 我们会在每一节晚课之后会通知要预习的章节,学员需要按如下操作观看相关视频. 1.1 打开百问网官网 ​1.2 点击首页 ...

  8. C语言试题五十二之学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun,它的功能时:按分数的高低排列学生的记录,高分在前。

    1. 题目 请编写一个函数void function(Student a[], int n),其功能时:学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun, ...

  9. 三菱R系列PLC程序 全部采用ST语言编写,内部使用函数块和结构体,程序思路清晰

    三菱R系列PLC程序 全部采用ST语言编写,内部使用函数块和结构体,程序思路清晰,简洁明了. 通过结构体和函数块的使用,可以使您在程序编写水平得到很大提高. ST语言是PLC后续的主流语言,是日后编程 ...

  10. c语言 由函数组成的数组,学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun(),它的_考题宝...

    学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun(),它的功能是按分数的高低排列学生的记录,低分在前. 注意:部分源程序给出如下. 请勿改动主函数main和其 ...

最新文章

  1. 请求的站点不可用或找不到_80%的500强用企业微信,企业越来越找不到拒绝用它的理由...
  2. Hadoop实战项目之网站数据点击流分析(转载分析)
  3. 年终总结系列6:借与贷,科普LTV指标
  4. mysql 备库同步_MYSQL主从库同步配置过程
  5. 管理感悟:谈谈用户和需求
  6. 无线串口服务器规模,无线串口服务器
  7. github提交代码出现remote: Support for password authentication was removed on August 13, 2021.?
  8. MySQL SUM() 带条件的求和方法与多条件的求和方法
  9. 那些看过一次后,就令人心里一动的美好词汇
  10. google colab使用入门
  11. 简单构建新闻数据对股票的情绪因子(大盘因子)
  12. git 解决冲突之 theirs ours
  13. Postman是什么?
  14. php session超时时间_php怎么设置session超时时间
  15. 一对一直播的市场行情分析,潜力非常可观
  16. 如何登录及使用FTP站点上传数据下载数据
  17. 高数-导数-反函数的导数
  18. 优思学院:解答一位想学习六西格玛的学生的几个疑惑
  19. linux shell编程面试题 字符串截取排序 当前连接的ip地址
  20. VirtualBox安装Mac系统

热门文章

  1. MATLAB对数坐标图和统计图(semilogy/loglog)
  2. Matlab中对坐标轴的对数转化,loglog,semilogx与semilogy
  3. unity学习笔记-相对位置和绝对位置
  4. java mis_关于使用java开发Mis系统的相关内容。
  5. 东南亚电商lazadashopee平台怎么开店,需要什么条件?
  6. Mysql中select into from用法
  7. 前端基础之HTML特殊字符集和表情集
  8. 新媒体文章标题怎么写?
  9. 内存核心频率、工作频率,等效频率、总线频率
  10. 图像特征:HOG特征