(十二)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;
}
相关推荐
yuanbenshidiaos3 分钟前
c++------------------函数
开发语言·c++
程序员_三木15 分钟前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
唐宋元明清218816 分钟前
Windows 记录开机后应用启动慢的问题
windows·系统异常
是小崔啊25 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama31 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全34 分钟前
Java的基础概念(一)
java·开发语言·python
liwulin050635 分钟前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc39 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob44 分钟前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言
羚羊角uou1 小时前
【C++】优先级队列以及仿函数
开发语言·c++