(十二)C语言的结构体

一.结构体

数组:允许定义可存储相同类型数据项的变量,
结构:另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
特点:结构体中的数据成员可以是基本数据类型(如 int、float、char 等),也可以是其他结构体类型、指针类型等。

结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性:

Title

Author

Subject

Book ID

二.结构体的声明与变量定义

结构体定义由关键字 struct 和结构体名组成,结构体名可以根据需要自行定义。

struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

c 复制代码
struct tag { 
    member-list
    member-list 
    member-list  
    ...
} variable-list ;
tag :结构体标签。
member-list :标准的变量定义,比如 int i; 或者 float f;,或者其他有效的变量定义。
variable-list :结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量

三.结构体的大小计算

C 语言中,我们可以使用 sizeof 运算符来计算结构体的大小,sizeof 返回的是给定类型或变量的字节大小。对于结构体,sizeof 将返回结构体的总字节数,包括所有成员变量的大小以及可能的填充字节。

以下实例演示了如何计算结构体的大小:

c 复制代码
#include <stdio.h>

struct Person {
    char name[20];
    int age;
    float height;
};//结构体声明

int main() {
    struct Person person;//结构体的变量定义
    printf("结构体 Person 大小为: %zu 字节\n", sizeof(person));
    return 0;
}
c 复制代码
结构体 Person 大小为: 28 字节

四.结构体的使用

结构体变量的初始化:

c 复制代码
#include <stdio.h>

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book = {"C 语言", "RUNOOB", "编程语言", 123456};//变量初始化

int main()
{
    printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\n", book.title, book.author, book.subject, book.book_id);//变量使用
}
c 复制代码
title : C 语言
author: RUNOOB
subject: 编程语言
book_id: 123456

为了访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。您可以使用 struct 关键字来定义结构类型的变量。下面的实例演示了结构的用法:

c 复制代码
#include <stdio.h>

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];//结构体存放数组成员
   int   book_id;
};
 
int main( )
{
   struct Books Book1 = {"C Programming","Nuha Ali","C Programming Tutorial",6495407};        //结构体的变量1初始化
   struct Books Book2 = {"Telecom Billing","Zara Ali","Telecom Billing Tutorial",6495700};        //结构体的变量2初始化
 
   /* 输出 Book1 信息 */
   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);

   /* 输出 Book2 信息 */
   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;
}
c 复制代码
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

五.结构体数组

结构体数组:数组中每一元素都是结构体。

c 复制代码
#include <stdio.h>
struct test{
  int n1 ;
  float n2;
  char n3;
};
int main()
{
    struct test Arr[3]={ {1,2,3},{4,5,6},{7,8,9} };//相当于定义了三个结构体变量并且初始化
    for(int i = 0; i<3 ; i++)
    {
        printf("Arr[%d].n1=%d\n",i,Arr[i].n1);
        printf("Arr[%d].n2=%.1f\n",i,Arr[i].n2);
        printf("Arr[%d].n3=%d\n",i,Arr[i].n3);
    }
    return 0;
}
c 复制代码
//struct test Arr[0]={1,2,3};
Arr[0].n1=1
Arr[0].n2=2.0
Arr[0].n3=3
//struct test Arr[1]={4,5,6};
Arr[1].n1=4
Arr[1].n2=5.0
Arr[1].n3=6
//struct test Arr[2]={7,8,9};
Arr[2].n1=7
Arr[2].n2=8.0
Arr[2].n3=9

六.结构体指针

结构体指针:一个指针变量指向结构体

c 复制代码
struct 结构体名 *变量名;

结构体变量名与数组名不一样,数组名在表达式中会被转换成数组指针,而结构体变量名不会,无论在任何表达式中标表示的都是整个结构体本身,要取结构体变量的地址,则必须使用取地址符&。
(1)结构体指针获取结构体成员

c 复制代码
通过结构体指针获取结构体成员的方式
1、(*ptr).structMember
2、ptr->structMember
.运算符高于*,所以(*ptr)括号不能少
c 复制代码
#include <stdio.h>
struct test{
    int num;
    char ch;
    double doub;
}t1;
int main()
{
    struct test t1 = {5,'A',5.6};
    struct test *ptr = &t1;
    //解引用和点运算符
    printf("type0:t1.num=%d\n",t1.num);//普通方式获取结构体成员
    printf("type1:(*ptr).num=%d\n",(*ptr).num); //指针方式
    printf("type0:t1.num=%c\n",t1.ch);//普通方式获取结构体成员
    printf("type2:  ptr->ch=%c\n",ptr->ch);//指针方式
    return 0;
}
c 复制代码
type0:t1.num=5
type1:(*ptr).num=5
type0:t1.num=A
type2:  ptr->ch=A

(2)结构体指针作为函数参数

结构体变量名代表整个结构体变量本身,当把结构体变量本身作为参数传递时,结构体内部的结构体成员较多时会造成时间和空间开销大,影响程序的运行效率

使用结构体指针作为参数传递时,因为传递的是地址,会比原本含有较多结构体的结构体变量更加块,但是也会造成结构体变量数据被修改的可能。

c 复制代码
#include <stdio.h>
#include <time.h>
struct test{
    int num;
    char ch;
    double doub;
}t1;

void printA(struct test str)
{
    str.num += 5;
    printf("printA函数的num=%d\n",str.num);
}

void printB(struct test* te)
{
    te->num += 15;
    printf("printB函数的num=%d\n",te->num);
}

int main()
{
    clock_t start, finish,start1,finish1;
    struct test t1 = {5,'A',5.6};
    struct test *ptr = &t1;
    start = clock();
    printA(t1);
    finish = clock();
    double Total_time = (double)(finish - start);
    printf("printA函数之后,main函数的num=%d\n",t1.num);
    printf("printA运行时间=%f\n",Total_time);
    start1 = clock();
    printB(ptr);
    finish1 = clock();
    double Total_time1 = (double)(finish1 - start1);
    printf("printB函数之后,main函数的num=%d\n",t1.num);
    printf("printB运行时间=%f\n",Total_time1);
    return 0;
}
相关推荐
Py小趴几秒前
Python自学之Colormaps指南
开发语言·python·数据可视化
晒足以百八十6 分钟前
基于Python 和 pyecharts 制作招聘数据可视化分析大屏
开发语言·python·信息可视化
敲代码不忘补水25 分钟前
生成式GPT商品推荐:精准满足用户需求
开发语言·python·gpt·产品运营·产品经理
BT-BOX1 小时前
STM32仿真proteus位带操作和keil增加头文件C文件
c语言·stm32·proteus
清风fu杨柳1 小时前
centos7 arm版本编译qt5.6.3详细说明
开发语言·arm开发·qt
醉颜凉1 小时前
【NOIP提高组】潜伏者
java·c语言·开发语言·c++·算法
_小柏_1 小时前
C/C++基础知识复习(20)
开发语言
程序员小明z1 小时前
基于Java的药店管理系统
java·开发语言·spring boot·毕业设计·毕设
我是哈哈hh2 小时前
HTML5和CSS3的进阶_HTML5和CSS3的新增特性
开发语言·前端·css·html·css3·html5·web
Dontla2 小时前
Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须手动添加泛型特征约束?(泛型trait约束)
开发语言·算法·rust