当前位置: 首页 > news >正文

C语言---结构体(格式、用法、嵌套、初始化)、共用体、枚举类型、typedef类型

目录

结构体与共用体

1、结构体(struct)

        (1) 格式与用法

        (2) 结构体允许嵌套

 (3) 结构体成员初始化

        (4) 指针替换变量

        (5) 求结构体在内存空间所占字节

2、共用体(union)

        (1) 格式与概念

        (2) 应用

3、枚举类型(enum)

        (1) 格式与概念

         (2) 应用

4、typedef 类型


结构体与共用体

1、结构体(struct)

        (1) 格式与用法

                其中,标识符首字母必须大写(规定),最后一行的花括号后必须加分号“;”。用来定义新的数据类型,存放在声明部分中。

例如,创建一个 struct Student 数据类型:

struct Student
{int id;char name[20];float score;
};

        对新的数据类型定义变量的方法:

        a.  在末行花括号( } )与分号( ;)中间写入所需变量的个数及名称,此时变量为全局变量,存放在静态区;

        b. 在主函数中输入创建数据类型名,在其后输入变量名来定义变量,此时变量为局部变量,存放在栈区。例如:

                         

注意:

        在主函数 main 中,成员类型与 struct 中的成员类型一致。

        “ . ”为结构体成员运算符,是一级运算符,自左至右。

        例如:使用创建的 struct Student 数据类型定义变量 s ,定义类型成员内容,完成 “1,zhangsan,97.500000” 的输出效果

int main(void)
{struct Student s;s.id = 1;strcpy(s.name, "zahngsan");//【1】s.score = 97.5;printf("%d,%s,%f\n", s.id,s.name,s.score);return 0;
}

值得注意的是代码中的【1】位置,不能写为“ s.name = "zhangsan" ”,数组不能直接进行赋值。

        (2) 结构体允许嵌套

创建一个 struct Date 数据类型,结构体成员信息如下:

struct Date
{int year;int month;int day;
};

        使用 struct Student 与 struct Date 两种数据类型,完成" 1, zhangsan, 97.500000, 2002-3-12 "的输出效果

struct Student
{int id;char name[20];float score;struct Date birthday;
};int main(void)
{struct Student s;s.id = 1;strcpy(s.name, "zhangsan");s.score = 97.5;s.birthday.year = 2002;s.birthday.month = 3;s.birthday.day = 12;printf("%d, %s, %f,%d-%d-%d \n", s.id, srname, s.score, s.birthday.year, s.birthday.month, s.birthday.day);return 0;
}

 (3) 结构体成员初始化

        a. 全初始化:结构体初始化与结构体成员声明顺序一致,例如:

struct Student s ={1, "zhangsan", 97.5, {2002,3,12}};

        b. 部分初始化:只对部分成员信息做初始化,要修改的内容之间用逗号隔开

int main(void)
{struct Student s = {.id = 1,.score = 97.5,.birthday = {.year = 2002,.month = 3,}};printf("%d, %s, %f,%d-%d-%d \n", s.id, srname, s.score, s.birthday.year, s.birthday.month, s.birthday.day);return 0;
}

        (4) 指针替换变量

        通过指针可以对成员进行修改,效率更高,否则只是值传递

struct Student *p;
p = &s;
p->id += 10;
printf("%d %f\n", p->id, p->name);
//p->name 也可写为 (*p).id
//推荐 p->name

        (5) 求结构体在内存空间所占字节

        内存对齐:数据总线以数据类型的整数倍都数据(整除)。

        1、默认按照CPU位数对其(8)字节,最终大小必须是8的整数倍;

        2、在结构体成员中找到最长成员,最终按照该成员长度对其;

        3、按照结构体声明的顺序,依次将成员保存到结构体内存中,保存的偏移量 / sizeof(成员类型)。

例如:struct Dome 中的成员数据类型依次为 char(黄)、int(蓝)、short(橙),存储如下,又因为要被最长的整除(int 的4个字节),所有该类型的 sizeof 为12。

        (6) 应用

        对于 struct Student 中的成员信息

struct Student
{int id;char name[20];float score;
};

        eg1. 单项输出(printStudent),全部输出(printStudents)

void printStudent(struct Student *p)
{printf("%d, %s, %f\n", p->id, p->name, p->score);
}void printStudents(struct Student a[], int len)
{int i;for(i = 0;i < len;++i){printStudent(a + i);}
}

        eg2. 交换(swap),逆序(reverseStudents)

void swap(struct Student *a, struct Student *b)
{struct Student t;t = *a;*a = *b;*b = t;
}void revserseStudents(struct Student *a, int len)
{int i;for(i = 0;i < len / 2;++i){swap(a + i, a + len - i - 1);}
}

        eg3. 采用回调函数按名字长度(namecmp)、按成绩(scoreStudent)进行排序(sortStudent)


int namecmp(struct Student *p1, struct Student *p2)
{return strcmp(p1->name, p2->name);
}int scorecmp(struct Student *p1, struct Student *p2)
{if(p1->score > p2->score){return 1;}else if(p1->score == p2->score){return 0;}else{return -1;}
}void sortStudent(struct Student *a, int len, int (*pfn)(struct Student *, struct Student *))
{int i, j;for(i = 0;i < len - 1;++i){for(j = i + 1;j < len;++j){if(pfn(a + i, a + j) > 0){swap(a + i, a + j);}}}
}

        在主函数中的书写格式

int main(void)
{struct Student a[3] = {{1, "zhangsan", 97.5},{2, "lisi", 98},{3, "wanghu", 95}};int len = sizeof(a) / sizeof(*a);sortStudent(a, len, namecmp);printStudents(a, len);return 0;
}

* 结构体之间不能进行比较排序,但结构体成员之间可以进行比较排序。 

2、共用体(union)

        (1) 格式与概念

        其中,共用体名满足标识符要求,且首字母要大写,共用体成员的内存公用,该类型代码存放在声明中,

        创建 union Demo 数据类型,说明共用体成员的内存是共用的

union Demo
{int i;short s;char c;
};
int main(void)
{    union Demo d;d.i = 1000;d.s = 100;d.c = 10;printf("%u\n", sizeof(d));//输出结果为 4printf("%d\n", d.i);//输出结果为 10return 0;
}

         说明:内存共用并且会进行覆盖,i 为int型占4个字节,short占2个字节,char占1个字节,相当于int 先占了第一二三四个格子,short 占第一二个格子,char占第一个格子,覆盖到最后只剩 char 的一个格子,输出。 

        可以运用指针作为类型变量

int main(void)
{union Demo *p;p = &d;printf("%p %p %p\n", &d.i, &d.s, &d.c);	return 0;
}

        (2) 应用

        用来判断程序大小端存取

union Demo
{int i;char c;
};int main(void)
{union Demo d;d.i = 1;if(d.c == 1){puts("little");}else{puts("big");}return 0;
}

3、枚举类型(enum)

        (1) 格式与概念

        枚举类型(enum),用来自定义一个数据类型,并将常参放入其中。

        一般格式为:

       

        其中,标识符首字母依旧要大写,该类型的所有可能取值称为“枚举类型常量”,各取值之间用逗号“,”隔开,最后一个取值后面不需要加任何东西,花括号后的分号“;”不能省略。也可以对其输出变量(eg1. 中的 w )进行偏移(加法)。例如:

        创建 enum Week 类型,并将 Week 的所有可能放入其中,并对 w 的后一项进行输出(可以用 “%d” 进行输出),输出的值为变量 w 在枚举常量的位置,也可以对常量进行赋值,但不能重复(例如下图 Tue=7)

enum Week
{Sun, Mon, Tue = 7, Wes, Thu, Fri, Sat
};int main(void)
{enum Week w;w = Sun;printf("%d\n", w + 1);//输出为 Monreturn 0;
}

         (2) 应用

        该类型可以做 switch 函数后面的表达式,例如:(可自行补充其他 case 情况)

enum Week
{Sun, Mon, Tue, Wes, Thu, Fri, Sat
};int main(void)
{enum Week w;switch(w){case Sun:puts("lol");break;case Mon:case Tue:puts("study");break;default:break;}return 0;
}

4、typedef 类型

        将已有类型的类型名换个名字,在全局区起名,将变量名变为类型的类型名。在全局区起名。可以在数据类型(int、char、short等后加,也可以在struct、union、enum后加),类型名可以是一个标识符,也可以是一个数组,例如:

typedef int INT;
typedef int ARRAY[10];int main(void)
{int i;ARRAY a;printf("%lu\n", sizeof(a));return 0;
}

        也可以运用指针作为类型名,例如:

typedef struct Demo
{int i;short s;char c;
}Demo, *PDEMO;int main(void)
{Demo d;PDEMO p;p = &d;return 0;
}

【END】

http://www.lryc.cn/news/605945.html

相关文章:

  • 舱驾操作系统架构规划
  • 使用的IDE没有内置MCP客户端怎么办?
  • AI 类型的 IDE
  • AI IDE+AI 辅助编程-生成的大纲-一般般
  • 掩码语言模型(MLM)技术解析:理论基础、演进脉络与应用创新
  • 从循环依赖谈 Chromium 模块化设计:编译结构与最佳实践
  • 基于 Amazon Nova Sonic 和 MCP 构建语音交互 Agent
  • 开发避坑短篇(11):Oracle DATE(7)到MySQL时间类型精度冲突解决方案
  • USRP捕获手机/路由器数据传输信号波形(下)
  • 6.苹果ios逆向-过ssl证书检测-安装SSL Kill Switch 3
  • JVM字节码文件结构剖析
  • uniapp Vue3版本使用pinia存储持久化插件pinia-plugin-persistedstate对微信小程序的配置
  • 【生活篇】Ubuntu22.04安装网易云客户端
  • 计数组合学7.9( 标量积)
  • 如何使用 JavaScript 接入实时行情 API
  • esim系统科普
  • ES 工业网关:比德国更适配,比美国更易用
  • 是德科技的BenchVue和纳米软件的ATECLOUD有哪些区别?
  • node.js之Koa框架
  • 25-vue-photo-preview的使用及使用过程中的问题解决方案
  • Hive课后练习题
  • 【Leetcode】2683. 相邻值的按位异或
  • 《Java 程序设计》第 16 章 - JDBC 数据库编程
  • rabbitmq的安装和使用-windows版本
  • MFC CChartCtrl编程
  • Python爬虫07_Requests爬取图片
  • 【Java23种设计模式】:模板方法模式
  • 【C语言】深度剖析指针(三):回调机制、通用排序与数组指针逻辑
  • PostgreSQL面试题及详细答案120道(01-20)
  • 前端方案设计:实现接口缓存