600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > C语言学习笔记11-结构体(struct 结构作为函数参数 结构数组) 联合体/共用体typed

C语言学习笔记11-结构体(struct 结构作为函数参数 结构数组) 联合体/共用体typed

时间:2019-07-27 15:55:04

相关推荐

C语言学习笔记11-结构体(struct 结构作为函数参数 结构数组) 联合体/共用体typed

C语言-结构类型

程序中的数据都需要有类型支撑,当数据很复杂时(不是简单的一个值,如时间信息:年月日时分秒6个数据需要作为一个整体),我们需要声明一个新的结构类型来描述这种复合的数据(可以包含很多不同类型的成员),然后我们可以用这个结构的一个变量来表达复合的数据。(有点类似java的类)

1. 结构体声明与结构变量定义

可参考:

/cprogramming/c-structures.html

/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){,02,02,16, .sec=55};t2 = t1;t2.year = ;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[] = {{"0101", "小明", 23, 1, "计算机科学", 3.89 }, {"0215", "小红", 23, 0, "软件工程", 3.56 }, {"0437", "小军", 25, 1, "大数据", 3.45 }, {"1403", "小芳", 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(大 小端序)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。