C语言学习笔记11-结构体(struct、结构作为函数参数、结构数组)、联合体/共用体typedef; union(大、小端序)
C语言-结构类型
程序中的数据都需要有类型支撑,当数据很复杂时(不是简单的一个值,如时间信息:年月日时分秒6个数据需要作为一个整体),我们需要声明一个新的结构类型来描述这种复合的数据(可以包含很多不同类型的成员),然后我们可以用这个结构的一个变量来表达复合的数据。(有点类似java的类)
1. 结构体声明与结构变量定义
可参考:
https://www.runoob.com/cprogramming/c-structures.html
https://www.runoob.com/cprogramming/c-typedef.html
我的学习笔记:
声明在函数内/外的规则和本地变量一样,一般在函数外声明结构类型,这样可以被多个函数使用。
声明好后,千万别忘记{}后加上; 。
声明结构体的形式(可以在struct前加typedef关键字重定义类型)并定义可以使用的变量 —— 3种方式
t1和t2都是time结构类型的变量:
同时做了声明和定义(main并列 全局):
如下,t1和t2是无名结构变量(程序只需要用到少量确定的结构变量)
结构变量的初始化:
集成初始化只能在定义时同步做,定义好后不支持这样初始化了,但可以强制类型转换重新赋值。【如果结构中还有数组,数组的初始化需要集成初始化时一并做好或者for/while循环,再或者逐个赋值】
对结构赋值:
struct time {int year;int month;int date;int hour;int min;int sec;
} t1, t2;t1 = (struct time){2023,02,02,16, .sec=55};t2 = t1;t2.year = 2022;printf("#t1 = %i-%i-%i %i:%i:%i#\n",t1.year, t1.month, t1.date, t1.hour, t1.min, t1.sec);printf("#t2 = %i-%i-%i %i:%i:%i#\n",t2.year, t2.month, t2.date, t2.hour, t2.min, t2.sec);
关于C语言 结构体和数组 的说明:
结构变量初始化和数组类似,顺次赋值、缺省默认0等;
但是,1. 数组单元必须同类型,结构体成员可以不同类型;2. 数组访问单元用[],结构体访问成员用. ,访问一个结构直接用结构变量名;3. 结构变量相互可以直接做赋值、取地址等运算(结构变量名不代表地址-需要结构指针 取地址&)。
2. 结构作为函数参数(返回指针 无限套娃)
首先,scanf接收和printf输出结构体都无法一次性对结构变量整体操作,只能对一个一个成员操作,如果每次都要写很多这种输入输出太麻烦了,我们一般写两个函数来操作。
然而注意当结构变量直接传入函数时,和数组和指针不同,传入的是拷贝值。基础的解决方案如下:结构类型的函数中定义临时结构变量回传给调用者(两个结构变量可以相互直接赋值) ——
但这种操作既费时间又费空间,我们更好的办法使用结构指针完成这个功能 ——
参考下面这个案例(明天的日期是?)
【( * p).mon = 12; 等价于 p -> mon = 12;】
#include "test1.h"/*
* ***程序入口 Main Empty项目***
*/
int main(int argc, char const *argv[])
{struct date tomorrow;struct date *p = &today;printf("Enter today's date(yyyy mm dd):");//scanf("%i %i %i", &today.year, &today.mon, &today.day);output(*inputDate(p)); //无限套娃 可以做很多有趣的表达式if ( today.day != numberOfDays(today) ) {tomorrow.day = today.day + 1;tomorrow.mon = today.mon;tomorrow.year = today.year;}else if ( today.mon == 12 ) {tomorrow.day = 1;tomorrow.mon = 1;tomorrow.year = today.year + 1;}else {tomorrow.day = 1;tomorrow.mon = today.mon + 1;tomorrow.year = today.year;}printf("And Tomorrow is:");output(tomorrow);return 0;
}#include "test1.h"//结构体参数函数
bool isLeap(struct date d) { //C99bool leap = false;if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0) {leap = true;}return leap;
}
int numberOfDays(struct date d) {int day; //每月月底const int daysPerMonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};if (d.mon == 2 && isLeap(d)) {day = 29;}else {day = daysPerMonth[d.mon-1];}return day;
}
struct date * inputDate(struct date *p) {scanf("%d %d %d", &p->year, &p->mon, &p->day); //p->year等价于(*p).yearreturn p;
}
void output(struct date d) {printf("%i-%i-%i.\n", //%i和%d类似,但%i可以区分八进制和十六进制 printf中通用d.year, d.mon, d.day);
}#ifndef _TEST1_H //定义预处理变量,使用大写文件名 实际可以随意命名(不重复)
#define _TEST1_H#include <stdio.h>
#include <stdbool.h>struct date {int year;int mon;int day;
} today;bool isLeap(struct date d);
int numberOfDays(struct date d);
struct date * inputDate(struct date *p);
void output(struct date d);#endif
3. 结构数组( 初始化{{}} )
#include <stdio.h>typedef struct student {char stuID[10]; //学号char name[10]; //姓名int age; //年龄int gender; //性别 male1 female0char major[20]; //学科专业double grade_point; //学分绩点 0~5
} Stu;int main() {Stu stuForm[] = {{ "20200101", "小明", 23, 1, "计算机科学", 3.89 }, { "20200215", "小红", 23, 0, "软件工程", 3.56 }, { "20180437", "小军", 25, 1, "大数据", 3.45 }, { "20191403", "小芳", 24, 0, "数字媒体技术", 3.67 }, };int i;for ( i = 0; i < sizeof(stuForm)/sizeof(stuForm[0]); i ++ ) {printf("%d: %s %s %d %d %s %4.2f\n", //%4.2f 宽度4中小数点占1i+1, stuForm[i].stuID, stuForm[i].name, stuForm[i].age, stuForm[i].gender, stuForm[i].major, stuForm[i].grade_point);}return 0;
}
#include <stdio.h>#define int long longtypedef long long ll;struct point{int x;int y;
};
struct rectangle {struct point pt1; //不是指针,是变量struct point pt2;
};void printRect(struct rectangle r);signed main() {int i;struct rectangle rects[2] = {{{1,2}, {3,4}}, {{5,6}, {7,8}} }; //2 rectanglesfor ( i = 0; i < 2; i ++ ) {printRect(rects[i]);}// struct rectangle r, *rp;
// rp = &r;
// r.pt1.x //rp->pt1.x (r.pt1).x (rp->pt1).x
// r.pt2.yreturn 0;
}void printRect(struct rectangle r) {printf("<%lld,%lld> to <%lld,%lld>\n", r.pt1.x, r.pt1.y, r.pt2.x, r.pt2.y);
}
构中构:数组里是结构,结构里有数组,结构里有结构,结构的数组里是结构……
4. 联合 typedef union
typedef 已有类型的名字 重新定义的简化名字;
用途:改善了程序可读性
union 类似于 struct ,区别在于 union 的成员变量共用同一份空间(大小最大的成员)【在同一时间内只有一个成员是有效的】
union的使用场景:得到一个类型内部字节,对文件操作中常用
#include <stdio.h>typedef union {int i;char ch[sizeof(int)];
} CHI;int main() {CHI chi;int i;chi.i = 1234; //0x04D2for ( i = 0; i < sizeof(int); i ++ ) {printf("%02hhX", chi.ch[i]);//(X)显示16进制数的一种方式:位数不足自动补0,hh表示就是一个字节不扩展,显示2个16进制数字}putchar(10);return 0;
}
x86CPU是一种小端机器,小端序( 数据 低位在前)
大端:数据低位保存在内存地址高位,数据高位保存在地址低位【地址从小到大递增,数据从高位排到低位】
小端:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
C语言学习笔记11-结构体(struct、结构作为函数参数、结构数组)、联合体/共用体typedef; union(大、小端序)相关推荐
- C语言学习笔记(1)--基本概念和函数用法
最近开始重新学习C语言,所谓"好记性不如烂笔头",把一些要记住的基本概念和一些函数用法,无论是书上看到的,或者是在别人的博客和论坛上帖子看到的,都归纳到这篇文章中: 2014-10 ...
- C语言学习笔记06-占位符格式、C基本类型及逃逸字符一些细节(附介绍BCD码)
主要整理有关占位符格式与逃逸字符的一些细节 朋友们,看栗子--"BCD解码" (文末附BCD码介绍) 一个BCD数的十六进制是0x12(对应二进制表示:0001 0010),它表达 ...
- c语言学习笔记【结构体02】结构体指针变量与结构体变量的函数参数,C语言学习笔记结构体02结构体指针变量与结构体变量的函数参数.docx...
C 语言学习笔记[结构体02]结构体指针变量与结构体变量 的函数参数 C 语言学习笔记之结构体指针变量一提指针,那可 是 C 语言的核心了,有多少学子曾拜倒在指针的脚下.单纯的说指针,其实并不难,但是 ...
- c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体
枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...
- C语言学习笔记之动态内存分配结构体——辣鸡版学生管理系统
@[C语言学习笔记] 小辣鸡自学C语言中,好多视频教程都有这个案例,小辣鸡自己边学边记,下边是代码. 如有错误,感谢告知!!! #include<stdio.h> #include< ...
- Lawliet|C语言学习笔记5——循环结构
C语言学习笔记--循环结构 1.求1+2+3+-+100 #include<stdio.h> int main() {int i=1,sum=0; //定义变量i的初值为1,sum的初值为 ...
- Lawliet|C语言学习笔记3——顺序结构
C语言学习笔记--顺序结构 计算a+b #include<stdio.h> int main() {int a,b,sum;scanf("%d%d",&a,&a ...
- Lawliet|C语言学习笔记4——选择结构
C语言学习笔记--选择结构 求一元二次方程的根 简约版 #include<stdio.h> #include<math.h> //程序中要调用求平方根函数sqrt int ma ...
- go get 拉取指定版本_go语言学习笔记-基础知识-3
相关文档 go语言学习笔记-目录 1.简介 1.1 什么是GO Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易.Go是从2007年末由Robert Griesemer, Rob ...
最新文章
- 这就是奇客文化?简直太有才了!
- MySQL下备份和恢复简单介绍
- java矩形碰撞检测_旋转矩形的Java碰撞检测?
- tensorrt 低精度推理
- UML-2-迭代、进化和敏捷
- Shell编程之变量赋值和引用
- 在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想
- C/C++后端-服务端开发技术博文分类汇总
- 清空VS2003/VS2005最近打开解决方案记录
- iPhone 12系列终于将配高刷屏:120Hz恐怕还得等两年
- linux怎么创建牡蛎_Linux文件也有快捷方式?有的,你会用吗?
- ubuntu下vlc-android编译
- js去掉字符串的空格
- java我行我素购物系统_用java怎么编写 我行我素shopping购物管理体统
- 【错误解决】Ubuntu20.04安装输入法遇到的问题
- ML面试1000题系列(71-80)
- 主流HTML5游戏开发引擎的分析和对比
- SSL-ZYC 2405 巧克力
- proxmox的安装
- 手动搭建一个https服务器,并颁发证书