C语言中的结构体

本文详细介绍了C语言中结构体的定义与使用方法,包括结构体变量的定义、成员引用及赋值等,并通过实例展示了结构体数组和结构体指针的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

此为转发原作者的文章,为自己留存所用,

第一部分:https://blog.youkuaiyun.com/qq_29924041/article/details/54427100

第二、三部分:https://blog.youkuaiyun.com/qq_31736627/article/details/52848001 

                        C语言中的结构体——>C语言的实体

一、定义和使用结构体变量

1.结构体概念 
2. 结构体声明 
3. 结构体定义 
5. 结构体变量成员的引用 
6. 结构体变量的赋值 
7. 结构体变量的初始化 
8. 结构体的嵌套

结构体的概念

C语言中引入了一种构造出句类型成为结构体,他是由若干个成员构成,成员本身可以是基本数据类型,也可以是其他构造类型,他相当与高级语言中的记录,类似与java高级语言中的实体类。可以表示一些复杂的数据类型;类似:

struct student{
    char *name;
    int age;
    int num;
    float weight;
    };

结构体的声明

结构体在使用之前,需要先声明结构体 
声明的语法:

struct 结构体名称
{
    类型说明符号 成员名;//成员列表
};

成员表有若干个成员组成,每个成员都是该结构体的一部分,对每个成员必须做出类型说明,成员可以是基本数据类型,也可以是构造数据类型; 
注意:

  1. {}后面是要有分号”;”的
  2. 结构体的声明可以在源文件程序的开头部分中,也可以声明在头文件中,一般在实际的开发过程中,都是定义在头文件中的;
  3. 结构体的名字与其成员是可以重名的,结构体成员和其他变量也可以重名,
  4. 结构体类型的名称必须是”struct 结构体名”,注意struct关键字是不能被省略的;
  5. 结构体需要先声明在去使用
  6. 结构体使用必须要 定义对应的结构体变量
  7. 结构体类型相当与一个模型,声明的时候是不分配内存的,只有定义相应的结构体变量的时候,才会分配实际的内存

结构体变量的定义:

语法1:预先已声明结构体

    struct 结构体名 变量1,变量2,...变量n;

语法2:声明结构体的时候同时定义结构体变量

    struct  结构体名{
        成员列表;
    } 变量名1,变量名2...变量n;

语法3:直接定义结构体变量

    struct {
        成员列表;
    }变量名1,...,变量名n;

注意:结构体变量的定义尽量不要在头文件中,声明结构体的时候放在头文件中,结构体和结构体变量就类似与java中的类和对象之间的关系。

结构体变量成员的引用

C语言中不允许对结构体变量整体进行输入和输出的,对结构体变量的操作都是对结构体变量成员进行操作的。是个体关系,不能整体操作 
引用方式:

结构体变量.成员名
机构体变量成员通过"."来引用
如果成员本身就是属于一个结构体类型的话,那么此时就继续用若干个点运算符号,一级一级的找,直到找到自己操作的那个
class.student.name = "zhangsan";
我们可以引用结构体变量成员的地址,也可以引用结构体变量的地址  

结构体变量的赋值

初始化方法1: 
结构体变量的赋值,就是对结构体变量的各个成员进行赋值 
如:student.xh = 100;

    student.name = "hello";

可以用输入语句来进行赋值:

    scanf("%s %f",&student.sex,&student.score);

允许具有相同类型的结构体变量进行相互赋值:

    student1 = student2;

注意:结构体中成员变量如果是字符数组的话,不能进行赋值,但是可以使用strcpy进行拷贝,如果是字符指针的话,可以直接进行赋值,所以在操作过程中我们尽量使用字符指针来进行操作;

注意:数组名本来就是地址,所以在赋值的时候,不需要加&符号:

char gender[30];
如:scanf("%s",gender);

没有进行赋值初始化的时候,由于结构体变量是局部变量,因此存储在栈中,其初始的值是随机数值;其占用的字节数等于它成员变量占用的总的字节数,成员越多,其占用的字节数也就越多

初始化方法2: 
预先已声明结构体再定义结构体变量并初始化:

struct 结构体名 变量名1 = {成员值类表},...,
               变量名n = {成员值列表};

初始化方法3: 
声明结构体的同时定义结构体变量并且初始化:

    struct 结构体名{
        成员变量;
    }变量名1 = {成员数值列表},变量名2 = {成员数值列表},...,变量名n ={成员值列表};

初始化方式4: 
直接定义结构体变量并且初始化

strcut {
    成员列表;
}变量名1={成员值列表},...,变量名n={成员值列表};

结构体的嵌套

可以将一个结构体放入另外一个结构体内,但是结构体不能嵌套它自身,如果嵌套自身的话,就必须是结构体指针类型

struct address{
    char country[20];
    char city[20];
}
struct student{
    int xh;
    char name[20];
    struct address addr;
};
要访问结构体address中的成员,而address是另外一个结构体student的成员,可以通过点运算符的链式方式访问
如:访问成员country: stu.addr.country
   访问city:stu.addr.city;

下面通过代码来完整的展示下结构体的玩法:

#ifndef __TEACHER_H_
#define __TEACHER_H_
/*定义一个街道结构体,成员变量为国家,城市,和街道*/
struct address{
    char *country;
    char *city;
    char *street;
};

/*定义一个teacher结构体,成员变量为编号,年龄,姓名,工龄,地址*/
struct teacher{
    int num;
    int age;
    char *name;
    int teach_year;
    struct address addr;
};
#endif
  •  

源文件代码

#include<stdio.h>
#include<stdlib.h>
#include"teacher.h"
#include<string.h>

struct score{
    int math_score;
    int chinese_score;
    int english_score;
};

/*定义一个学生类型*/
struct student{
    int xh;//
    char *name;
    int class;
    struct address addr;
    struct score all_score;
}zzf ={1,"zzf",3,{"china","shanghai","yindu_road"},{80,85,90}};//声明的时候直接去定义一个学生zzf,并且初始化。

//打印出学生的信息
void printfStudentInfo(struct student stu);

void printfTeacherInfo(struct teacher tea);

int main(int argc,char *argv[]){

    printfStudentInfo(zzf);
    printf("==========================\n");

    //定义的时候初始化
    struct teacher teacher_zhang = {1,50,"zhang",5,{"china","minhang","yizhong"}};
    printfTeacherInfo(teacher_zhang);

    printf("===============================\n");
    //先定义后初始化
    struct teacher teacher_wang;
    teacher_wang.num = 2;
    teacher_wang.age = 40; 
    teacher_wang.name = "wang";
    teacher_wang.teach_year = 10; 
    teacher_wang.addr.country = "china";
    teacher_wang.addr.city = "shanghai";
    teacher_wang.addr.street ="chunshen_road";
    printfTeacherInfo(teacher_wang);

    printf("=============相同结构体名变量jiegouti赋值======\n");
    struct teacher teacher_other;
    teacher_other = teacher_wang;
    printfTeacherInfo(teacher_wang);

    printf("==============================");
    //不去定义结构体名,然后直接定义结构体变量
    struct{
        char book_name[20];
        int pages;
        int charpter_nums;
    }math_book;
    //如果使用字符数组的话,就必须使用strcpy才能赋值
    strcpy(math_book.book_name,"jihe");
    math_book.pages = 150;
    math_book.charpter_nums = 12; 

    printf("book name:%s,book pages:;%d,book charpter_nums:%d\n",math_book.book_name,math_book.pages,math_book.charpter_nums);

    return 0;
}

void printfStudentInfo(struct student stu){
    printf("stu xh:%d\n",stu.xh);
    printf("stu name:%s\n",stu.name);
    printf("stu class:%d\n",stu.class);
    printf("student country:%s,city:%s,street:%s\n",stu.addr.country,stu.addr.city,stu.addr.street);
    printf("student math:%d,chinese:%d,english:%d\n",stu.all_score.math_score,stu.all_score.chinese_score,stu.all_score.english_score);
}

void printfTeacherInfo(struct teacher tea){
    printf("teacher num:%d\n",tea.num);
    printf("teacher age:%d\n",tea.age);
    printf("teacher name:%s\n",tea.name);
    printf("teacher teacher_year:%d\n",tea.teach_year);
    printf("teacher country:%s,city:%s,street:%s\n",tea.addr.country,tea.addr.city,tea.addr.street);
}

 二、使用结构体数组

 结构数组就是具有相同结构类型的变量集合。假如要定义一个班级40个同学的姓名、性别、年龄和住址, 可以定义成一个结构数组。如下所示: 
     struct{ 
          char name[8]; 
          char sex[2]; 
          int age; 
          char addr[40]; 
     }student[40]; 
   

 也可定义为: 
     struct string{ 
          char name[8]; 
          char sex[2]; 
          int age; 
          char addr[40]; 
     }; 
     struct string student[40]; 
    需要指出的是结构数组成员的访问是以数组元素为结构变量的, 其形式为: 
          结构数组元素.成员名 
    例如: 
      student[0].name 
      student[30].age 
    实际上结构数组相当于一个二维构造, 第一维是结构数组元素, 每个元素是一个结构变量, 第二维是结构成员。 
    注意: 
    结构数组的成员也可以是数组变量。 
    例如: 
     struct a 
     { 
          int m[3][5]; 
          float f; 
          char s[20]; 
     }y[4]; 
    为了访问结构a中结构变量y[2]的这个变量, 可写成 
       y[2].m[1][4] 

三、结构体指针


结构指针是指向结构的指针。它由一个加在结构变量名前的"*" 操作符来定义, 例如用前面已说明的结构定义一个结构指针如下: 
     struct string{ 
          char name[8]; 
          char sex[2]; 
          int age; 
          char addr[40]; 
     }*student; 
   

 也可省略结构指针名只作结构说明, 然后再用下面的语句定义结构指针。 
      struct string *student; 
  

 使用结构指针对结构成员的访问, 与结构变量对结构成员的访问在表达方式上有所不同。结构指针对结构成员的访问表示为: 
       结构指针名->结构成员 
    其中"->"是两个符号"-"和">"的组合, 好象一个箭头指向结构成员。例如要给上面定义的结构中name和age赋值, 可以用下面语句: 
     strcpy(student->name, "Lu G.C"); 
     student->age=18; 
    实际上, student->name就是(*student).name的缩写形式。 


    需要指出的是结构指针是指向结构的一个指针, 即结构中第一个成员的首地址, 因此在使用之前应该对结构指针初始化, 即分配整个结构长度的字节空间, 这可用下面函数完成, 仍以上例来说明如下: 
     student=(struct string*)malloc(size of (struct string)); 
    size of (struct string)自动求取string结构的字节长度, 
malloc() 函数 定义了一个大小为结构长度的内存区域, 然后将其诈地址作为结构指针返回。 
    注意: 
    1. 结构作为一种数据类型,  因此定义的结构变量或结构指针变量同样有局 
部变量和全程变量, 视定义的位置而定。 
    2. 结构变量名不是指向该结构的地址, 这与数组名的含义不同,  因此若需 
要求结构中第一个成员的首地址应该是&[结构变量名]。 
    4. 结构的复杂形式 
--------------------- 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值