文章目录

  • 9.1 结构体变量定义、引用、初始化
    • 9.1.1 结构体概述
    • 9.1.2 定义结构体类型变量的方法
    • 9.1.3 结构体类型变量的引用
    • 9.1.4 结构体变量的初始化
  • 9.2 结构体数组、结构体指针
    • 9.2.1结构体数组
      • 如何定义结构体数组
    • 9.2.2 结构体指针
    • 9.2.3 用指向结构体的指针做函数参数
  • 9.3 共用体、枚举类型、typedef
    • 9.3.1共用体(联合)
      • 结构体与共用体的区别
    • 9.3.2枚举类型
    • 9.3.3用typedef来定义类型

9.1 结构体变量定义、引用、初始化

9.1.1 结构体概述

类型回顾: int float double char int a[10] float b[100]

结构体概述:

结构体也是一种数据类型,被叫做结构体类型

结构体: 将多种不同类型的数据组到一起。目的是为了表达更丰富的信息。类似于SQL语言中的“记录”。

形式:

#include "stdio.h"
int main(){struct student{int num;            //学号char name[100];     //姓名int sex;            //性别, 0->女, 1->男int age;            //年龄char address[100];  //地址};
}

总结:

结构体类型 定义的一般形式

struct 结构体名
{//成员列表(可以有多个) 各个成员之间都带一个分号;
};  // 不能忘记这个分号;

9.1.2 定义结构体类型变量的方法

二: 定义结构体类型变量的方法

需要将结构体名看成一个类型名就行了,

总共有三种写法

1. 普通写法

struct  结构体名  变量名列表;例如:
struct student s1,s2; //定义两个结构体类型变量

2. 定义结构类型的时候顺便定义了变量。变量位于} 之后 ; 之前多个变量之间使用 , 分割

struct 结构体名
{//成员列表
**}变量名列表;**#include "stdio.h"
int main(){struct student{int num;            //学号char name[100];     //姓名int sex;            //性别, 0->女, 1->男int age;            //年龄char address[100];  //地址**}s1,s2;**
}

1. 直接定义结构类型变量,连结构体名都省略了

struct
{//成员列表
**} 变量名列表;**

说明:

  • 使用结构体,我们一般要先定义一个结构体类型,然后定义某些变量为该类型的变量。
  • 结构体内可以套结构体
struct date
{int month;int day;int year;
};struct student{int num;            //学号char name[100];     //姓名int sex;            //性别, 0->女, 1->男int age;            //年龄char address[100];  //地址**struct date birthday;  //生日,结构体类型变量**};int main()
{struct student s1,s2;
}
  • 结构体内的成员变量,可以与程序中的变量名相同,彼此间不影响

9.1.3 结构体类型变量的引用

三: 结构体类型变量的引用

  • 不能将结构体变量作为一个整体进行引用,比如s1,s2都是结构体变量,但不能拿过来直接用,只能对结构体变量中的各个成员分别引用,

引用方法:

**// 结构体变量名.成员名**
**s1.num = 1; //将1赋值给s1变量中的成员num;  这个 . 叫结构成员运算符
//该 . 运算符的优先级跟()是同级别 还有 ->**
**所以可将s1.num当成一个整体来看待**

如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级成员,只能对最低级别成员进行赋值或者存取。

#include "stdio.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;// }s1,s2;
};
int main() {int num; //这个名字和结构体变量的名字相同,但互不影响.struct student s1,s2;s1.num = 001; //将001赋值为s1结构体变量中的成员num.//**s1.birthday.day = 1; //如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级成员,只能对最低级别成员进行赋值或者存取。**return 0;
}

成员变量

//成员变量,可以像普通变量一样进行各种运算
s1.age = 19;
s2.age = s1.age;
int AgeSum = s1.age + s2.age;
s1.age++; //年龄自加1,因为.的优先级最高,所以s1.age是个整体

9.1.4 结构体变量的初始化

// 成员变量也是有地址的.
//结构体名不可以有地址


// s1++  s1.birthday++  这都是错的
int *p = &s1.num;printf("%d",*p); //也可以使用指针变量来取得其地址//结构体变量的初始化,定义时初始化
struct student s3 = {1003,"网速",1,19,"浦东",10,14,2018};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Aw4VI4cA-1667044997212)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3520ce3c-9115-41d9-abb7-fcc7d3c06369/Untitled.png)]

9.2 结构体数组、结构体指针

9.2.1结构体数组

如何定义结构体数组

a. 单独写成一行定义

struct studeng stu[3];  //可以用的下标 0-2

b. 定义结构的时候顺便定义结构体数组


struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;}stu[3];

c. 定义结构体数组的时候还可以同时进行初始化

一般形式:

struct student stu[] = { {…},{…},{…}};


struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}
};
printf("stu[%d]",stu[1].age);

9.2.2 结构体指针

  • 就是结构体变量的指针,这个指针肯定是指向该结构体变量所占据的内存段的起始地址
  • 结构体变量指针,也可以指向结构体数组中的元素。因为结构体数组中的每个元素就相当于一个结构体变量
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {**//结构体指针//就是结构体变量的指针,这个指针肯定是指向该结构体变量所占据的内存段的起始地址//结构体变量指针,也可以指向结构体数组中的元素。因为结构体数组中的每个元素就相当于一个结构体变量struct  student stu{}; //定义一个结构体变量,struct student *ps; //定义结构体变量的指针ps = &stu;strcpy(stu.name,"小虎");stu.age = 18;//ps已经指向了stu,stu里面的内容若改变了,就等于ps所指向的内容改变了。//如何通过结构体变量的指针来访问结构体变量的成员呢?两种方法://1.(*ps).age=29; //* 与 . 的运算等级不一样, .是最高的,所以这里要用 (*ps).ageps -> num = 2019250119;//2.ps -> sex = 1;  //其中 -> 叫指向结构体成员运算符 .printf("name=%s\n",ps->name);printf("age=%d\n",ps->age);printf("num=%d\n",stu.num);printf("sex=%d\n",stu.sex);return 0;
}**
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}};printf("stu[%d]",stu[1].age);**//演示指向结构体数组的指针****struct student *ps;ps = stu; //数组名代表数组首地址。int i; //随时使用随时定义for(i=0;i<3;i++){printf("num=%d\n",ps->num);printf("name=%s\n",ps->name);printf("age=%d\n",ps->age);ps++; //ps指向了下一个数组元素的开始地址printf("-----------------\n");}int ILen = sizeof(struct student);printf("%d\n",ILen);**
#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}};printf("stu[%d]",stu[1].age);**//演示指向结构体数组的指针struct student *ps;ps = stu; //数组名代表数组首地址。(++ps)->num; //值为2019250119,指针指向了2019250119(ps++)->num; //值为2019250116,指针指向了2019250119
}**

(2)不能让ps指向某一个数组元素中的成员。

错误写法

ps =&stu[0].num; //可以强制转,但没有意思

ps = &stu[0]; //这是对的

9.2.3 用指向结构体的指针做函数参数

#include "stdio.h"
#include "string.h"
struct date {int month;int day;int year;
};
struct student //定义一个结构体类型
{int num; //学号char name[100]; //姓名int sex; //int age; //年龄char address[100]; //地址struct date birthday;};//stu[3];
int main() {struct student stu[3] = { //stu包含的元素程序自己会判断出来,所以可以写成stu[]{2019250116,"zhangsan",1,18,"2401",12,30,2000},{2019250119,"振华",0,22,"小区2401",11,11,1999},{2019250118,"郭襄",0,20,"平凉",9,23,2001}};printf("stu[%d]",stu[1].age);**//演示指向结构体数组的指针struct student *ps;ps = stu; //数组名代表数组首地址。(++ps)->num; //值为2019250119,指针指向了2019250119(ps++)->num; //值为2019250116,指针指向了2019250119
}**

(2)不能让ps指向某一个数组元素中的成员。

错误写法

ps =&stu[0].num; //可以强制转,但灭有意思

ps = &stu[0]; //这是对的

9.3 共用体、枚举类型、typedef

9.3.1共用体(联合)

将几种不同类型的变量存放到同一段内存单元(同一个内存地址开始的单元中)。

几个变量共同占同一段内存的结构,叫共用体

union 共用体名
{//成员列表
} 变量列表;
union myuni
{int carnum;     //车编号,char cartype;   //车的类型char cname[60]; //轿车名
}a,b,c;

结构体与共用体的区别

结构体:

占用的内存是其成员所占内存之和。 如果定义的结构体不能被4整除或被某个数整除的话,系统会多分配几个字节以保证字节对齐

保证字节对齐的目的是为了效率问题。

#include "stdio.h"
#include "string.h"
struct student  //结构体
{int num;char name[101];int sex;
};
int main(){union MyUni a,b,c;int StructLen(sizeof(struct student)); //StructLen=112;
// 4+101+4=109; 112-109=3
//保持的是4k对齐,108/4=27 109-112是4个字节。
printf("StructLen=%d\n",StructLen); // 112

共用体: 所占用内存长度等于最长的成员长度。

#include "stdio.h"
#include "string.h"
union MyUni   //共用体
{int CarNum;     //车编号,char CarType;   //车的类型char name[60]; //轿车名
};int main(){union MyUni a,b,c;
int UnionLen(sizeof(union MyUni));printf("UnionLen=%d\n",UnionLen); // UnionLen=60
//最长的成员类型长度

说明:

a、共用体变量的引用

a.name;
a.CarNum;

b、共用体变量的特点

同一段内存存放几种不同类型的成员,但每一个瞬间只能存放其中一种。也就是说,每个瞬间只能由一个成员起作用,其他成员不起作用,并不是同时存在、都起作用

程序代码中最后给哪个成员赋值,那么哪个成员就起作用

#include "stdio.h"
#include "string.h"
union MyUni   //共用体
{int CarNum;     //车编号,char CarType;   //车的类型char name[60]; //轿车名
};struct student  //结构体
{int num;char name[101];int sex;
};
int main(){union MyUni a,b,c;int StructLen(sizeof(struct student)); //StructLen=112;// 4+101+4=109; 112-109=3 保持的是4k对齐,108/4=27 109-112是4个字节。int UnionLen(sizeof(union MyUni));printf("StructLen=%d\n",StructLen);printf("UnionLen=%d\n",UnionLen);**a.name;a.CarNum = 12; //这个不起作用strcpy(a.name,"ab"); //这是最后一个成员,所以这个才起作用printf("%d\n",a.CarNum); //不确定的值printf("%s\n",a.name);  //ab**

c、共用体变量的地址 和 其他成员地址都相同

&a &a.Carnum &a.name &a.CarType

这三个地址都相同

d、共用体变量不能在定义的时候初始化,而结构体可以初始化

e、不能把共用体变量作为函数参数,也不能让函数带回共用体变量

9.3.2枚举类型

例如:

//四种颜色: 红,绿,蓝,黄

// Red表红色

//Green

//Blue

//Yellow

枚举值当成整型值用就行了

枚举类型关键字

enum

enum color
{Red, //枚举常量,值不能被改变(可以当成一个整形数字)//占用4个字节Green,Blue,Yellow
};

枚举就是将值一一列举出来,那么定义的枚举变量值就只限于列出来的这些值的范围内;

可以直接定义枚举变量,不要枚举名,这就要直接定义枚举变量才行

enum
{Red,Green,Blue,Yellow
}MyColor1,MyColor2;

这些Red,Green,Blue,Yellow叫做枚举常量,这些常量的值不能被改变

//枚举常量,值不能被改变(可以当成一个整形数字),占用4个字节

d、可以直接给 枚举类型变量 赋值

#include "stdio.h"
#include "string.h"
enum color
{Red,    //0,默认从0开始,Green,  //1Blue,   //2Yellow  //3
};int main(){**enum color  MyColor1,MyColor2;**printf("%d\n",Red);printf("%d\n",Yellow);**MyColor1 = Red; // 0Mycolor2 = Yellow; // 3**}

e、定义枚举类型时,直接给枚举常量一个值。

#include "stdio.h"
#include "string.h"
enum color
{
Red= 12,  // 从12开始 往下走每次加1
Green,    //13
Blue,     //14
Yellow    //15
};int main(){enum color  MyColor1,MyColor2;printf("%d\n",Red); //12printf("%d\n",Yellow); //15MyColor1 =Red; //Red当做常量printf("%d\n",MyColor1); //12}

f、枚举值,理解成整型值

枚举值可以做比较

MyColor1 = (enum color)-8;
//强制转换将-8给了Red这个常量
if(MyColor1 == Red // 枚举值可以做比较
{printf("OK");
}
MyColor1 = (enum color)20000
printf("%d\n",MyColor1);
//枚举值其实就是整型值,可以互通

g、枚举值可以赋给一个整形

int abc;
abc = Green;printf("%d\n",Green);  printf("%d\n",abc); //两个的值都是一样的

9.3.3用typedef来定义类型

使用typedef来定义新的类型名,可以用来代替已有的类型名,

#include "stdio.h"
#include "string.h"
enum color
{Red = 12,Green,Blue,Yellow
};int main(){typedef int INTEGER; //可以使用INTEGER来代表int型,那再次定义整形变量时我们//就可以如下定义INTEGER a,b,c; //int a1,a2,a3;  // 这两个都是一样的**//如何定义结构体类型typedef struct date{int month;int day;int year;}DATE;DATE birthday;DATE *p1; //p为指向此结构体类型数据的指针//变形:typedef int NUM[100]; //定义num数组是整形NUM n; // 等价于int n[100];typedef char *RNG; //定义RNG为字符指针类型RNG p,q; // char *p,*q;****//指向函数的指针typedef int (*POINTER)(); //定义pointer为指向函数的指针类型,该函数返回的是整型值POINTER x,y;**
}
//总结: 第一步:先写出常规的整形数组定义方式
int n[100];
//第二步:将变量名替换成自己想用的类型名
int NUM[100];
//第三步:在前面加上typedef
typedef int NUM[100];

说明:

  1. typedef中用的类型别名使用大写
  2. typedef用来定义类型名的,不是定义变量
  3. typedef只是对已存在的类型增加一个类型名,没有创建新的类型
  4. typedef是在编译的时候处理的,是在编译环节进行的

可执行文件需要经过编译(预处理(#define,#include,#ifdef)**,编译(typedef),**汇编),链接,

1. typedef主要作用:

程序的通用性和可移植性

int a,b,c;
typedef int INTEGER;
INTEGER a,b,c;

第九章、结构体与共用体相关推荐

  1. 第九章结构体变量实验报告

    实验项目: 1.结构体变量的应用 2.结构体数组的应用 3.共用体的应用 4.结构体指针的应用 姓名:谢丽萍  实验地点:教学楼514教室  实验时间2019.6.26 一.本章要点 1.对结构体和共 ...

  2. C语言-结构体与共用体

    int 4字节:char 1字节:short 2字节:float 4字节: 1字节bytes=8位bits(2^8): struct date {int month;int day;int year; ...

  3. 数组、结构体和共用体的长度计算?

    数组.结构体和共用体的长度计算? 运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof(char) = 1; sizeof(int) = 4.基本数据类型的大小很好计算,我们来 ...

  4. 结构体与共用体(联合体)

    参考:结构体与共用体 作者:一只青木呀 发布时间: 2020-08-09 08:29:22 网址:https://blog.csdn.net/weixin_45309916/article/detai ...

  5. 结构体与共用体05 - 零基础入门学习C语言57

    第十章:结构体与共用体05 让编程改变世界 Change the world by program 对链表结点的删除操作实现 实现源代码: [codesyntax lang="c" ...

  6. 结构体与共用体07 - 零基础入门学习C语言59

    第十章:结构体与共用体07 让编程改变世界 Change the world by program 用typedef定义类型 用typedef声明新的类型名来代替已有的类型名   声明INTEGER为 ...

  7. C语言之结构体和共用体

    C语言之结构体和共用体 算上这篇笔记加上之前的四篇笔记,C语言基础我们也就告一段落了,对于刚刚接触c语言的童鞋们来说,这些以及足够了,稍后我会发布数据结构,对于想要深入学习的童鞋可以继续关注.本人也算 ...

  8. 结构体、共用体、位操作和枚举类型

    1 引言 ● 结构体(Structure)[在C标准中有时也称为聚合体(Aggregate)]是统一在同一个名字之下的一组相关变量的集合,它可以包含不同类型的变量 ● 结构体通常用来定义储存在文件中的 ...

  9. 【C语言】结构体、共用体、位域

    结构体 1. 结构体的声明方法 struct struct_name {data_type member1;data_type member2;.. }; 这是其中一种声明方式~ 2.定义一个结构体变 ...

最新文章

  1. python多态的例子_Python编程之多态用法实例详解
  2. PyTorch分布式训练
  3. matlab用lism求零输入响应,信号与系统matlab课后作业_北京交通大学讲解.docx
  4. IOS8 Playground介绍
  5. Eclipse Plug-in Hello world
  6. 知识点old1908
  7. C#的COM接口定义细则
  8. uva 1463 - Largest Empty Circle on a Segment(二分+三分+几何)
  9. 牛腩新闻发布系统-发布
  10. 在 Windows 10 中映射网络驱动器
  11. VS2012帮助下载地址
  12. OK插件安装常见问题集锦(PowerPoint版)|OneKeyTools Lite安装说明
  13. 编码:隐匿在计算机软硬件背后的语言
  14. [code] 在ROS上搭建ROVIO节点
  15. 张馨予一幅画拍出几十万,然而范冰冰却一直在向粉丝要画!
  16. PCL——简单点云可视化
  17. 数字电路逻辑设计笔记(3):集成逻辑门电路
  18. Python matplotlib 中填充颜色
  19. 计算机学科专业基础综合科目(408)
  20. VS中怎么实现代码换行

热门文章

  1. php mysql 找回密码_PHP、Mysql、jQuery找回密码的实现代码
  2. Python学习笔记之威虎山武器库
  3. 工业4.0,两年让德国制造业受损500亿美元
  4. 地图可视化组件–folium简单介绍
  5. 别人家的大学,哈工大来了!
  6. 《Python编程:从入门到实践》第七章练习题
  7. c语言折半查找输出坐标,用c语言编写折半查找法
  8. 竞价推广利用二八定律分析
  9. 圆度坐标法MATLAB,基于MATLAB的圆度评定方法
  10. 应还金额和最低还款额有什么区别?