AutoLeaders——翁恺老师的结构的笔记

本文详细介绍了C语言中的结构体,包括结构体的声明、初始化、成员访问、结构体与函数的交互、嵌套结构及typedef的使用。通过实例解析了结构体在实际编程中的应用,如作为函数参数传递、结构体指针的操作等。
摘要由CSDN通过智能技术生成

一,结构的类型

1,声明结构类型

#include<stdio.h>
int main(int argc,char const *argv[])
{
struct date
{
int month;
int day;
int year;
}
struct date today;
today.month=07;
today.day=31;
today.year=2014;
printf("Today's date is %i-%i-%i.\n,today.year,today.month,today.day);
return 0;
}

2,在函数内/外?

1)和本地变量一样,在函数内部声明的结构类型只能在函数内部使用
2)所以通常在函数外部声明结构类型,这样就可以被多个函数所使用了。

3,声明结构的形式

1)

struct point
{
int x;
int y;
};
struct point p1,p2;

p1和p2都是point里面有x和y的值。
2)

struct
{
int x;
int y;
}p1,p2;

p1和p2都是一直无名结构,里面有x和y。
3)

struct point
{
int x;
int y;
}p1,p2;

p1和p2都是point里面有x和y的值t;
对于第一种和第三种形式,都声明了结构point。都是第二种形式没有声明point,只是定义了两个变量

4,结构的初始化

struct date today = {07312014};
struct date thismonth = {.month=7,.year=2014};

5,结构成员

1,结构和数组有点像。
2,数组用[ ]运算符和下标访问其他成员。
如,a[0]=10;
3,结构用运算符和名字访问其成员。
·today.day
·student.firstNam
·p1.x
·p1.y

6,结构运算

1,要访问整个结构,直接用结构变量的名字
2,对于整个结构,可以做赋值,取地址,也可以传递给函数参数。
如,p1 = (struct point){5,10}; //相当于p1.x=5,p1.y=10;
3,p1=p2; //相当于p1.x=p1.x;p1.y=p2.y;

注意:数组无法做这样的运算!

7,结构指针

1,和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符。
2,struct date *pDate = &today;

二,结构与函数

1,结构作为函数参数

int numberOfDays(stuct date d};

1,整个结构可以作为参数的值传入函数。
2,这时候是在函数内新建一个结构变量,并复制调用这的结构的值。
3,也可以返回一个结构。
4,这与数组完全不同。
例如:

#include<stdio.h>
#include<stdbool.h>

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

bool isleap(struct date d);
int numberofdays(struct date d);

int main(int argc,char const *argv[])
{
	struct date today,tomorrow;
	
	printf("Enter today's date(mm dd yyyy):");
	scanf("%i %i %i",&today.month,&today.day,&today.year);
	
	if(today.day != numberofdays(today))
	{
		tomorrow.day=today.day+1;
		tomorrow.month=today.month;
		tomorrow.year=today.year;
	}
	else if(today.month==12)
	{
		tomorrow.day=1;
		tomorrow.month=1;
		tomorrow.year=today.year+1;
	}
	else
	{
		tomorrow.day=1;
		tomorrow.month=today.month+1;
		tomorrow.year=today.year; 
	}
	printf("Tomorrow's date is %i-%i-%i",tomorrow.year,tomorrow.month,tomorrow.day);
	
	return 0;
}

int numberofdays(struct date d)
{
	int days;
	
	const int dayspermonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
	
	if(d.month==2 && isleap(d) )
	    days=29;
	else 
	    days=dayspermonth[d.month-1];
	
	return days; 
}

bool isleap(struct date d)
{
	bool leap = false;
	
	if( (d.year %4==0 && d.year %100 !=0)||d.year%400==0)
	    leap=true;
	    
	return leap;
}

2,输入结构

#include<stdio.h>
struct point 
{
int x;
int y;
};
void getStruct(struct point);
void output(struct point);
void main()
{
struct point y={0,0};
getStruct(y);
output(y);
}
void getStruct(struct point p);
{
sacnf("%d",&p.x);
scanf("%d",&p.y);
printf("%d,%d",p.x,p.y);
}

void output(struct point p)
{
printf("%d,%d",p.x,p.y);
}

1,没有直接的方式可以一次scanf一个结构。
2,如果我们打算写一个函数来读入结构,则如上代码。
3,但是读入的结构如何让送出来呢?
1),记住C在函数调用时是传值的
所以函数中p与main中的y是不同的,在函数读入了p的数值之后,没有任何大小回到main,所以y还是{0,0}
2) 解决的方案
之前的方案,把一个结构传入了函数,然后在函数中操作,但是没有返回回去。
问题在于传入函数的是外面的那个结构的克隆体,而不是指针
传入结构和传入数组是不同的。
在这个输入函数中,完全可以创建一个临时的结构变量,然后把这个结构返回给调用者。

void main()
{
struct point y = {0};
y = inputPoint();
output(y);
}
struct point intputPoint()
{
struct point temp;
scanf("%d",&temp.x};
scanf("%d",&temp.y);
return temp;
}

3,指向结构的指针

struct date
{
int month;
int day;
int year;
}myday;
struct date *p = &myday;
(*p).month=12;
p->month=12;

用->表示指针所指的结构变量中的成员

4,结构指针参数

void main()
{
struct point y={0,0};
intputPoint(&y);
output(y);
}

变为

struct point* intputPoint(struct point *p)
{
scanf("%d",&(p->x));
scanf("%d",&(p->y));
return p;
}

5,结构数组

struct date dates[100];
struct date dates[]={{4,5,2005},{2,4,2005}};

三,结构中的结构

1,嵌套的结构

struct point;
{
int x; 
int y;
};
struct rectangle
{
struct point pt1;
struct point pt2;
};
//如果有变量
struct rectangle r;
就可以有:
r.pt1.x 、r.pt1,y;
r.pt2.x 、r.pt2.y;
//如果有变量定义:
struct rectangle r,*rp;
rp = &r;
//那么下面的四种形式是等价的:
r.pt1.x;
rp->pt.x;
(r.py1).x;
(rp->pt1).x;
但是没有rp->pt1->x;(因为pt1不是指针)。

2,结构中的结构的数组

#include<stdio.h>
struct point 
{
int x;
int y;
};
struct rectangle
{
struct point p1;
struct point p2;
};
void printRect(struct rectangle r);
{
printf("<%d,%d> to <%d,%d>\n",r.p1.x,r.p1.y,r.p2.x,r.p2.y);

int main(int argc,char const *argv[])
{
int i;
struct rectangle rects[]={{{1,2},{3,4}},{{5,6},{7,8}}};
//2 rectangles
for(i=0;i<2;i++) printRect(rects[i]);
}

四,类型的定义

1,自定义数据类型(typedef)

1,C语言提供了一个叫typedef的功能来声明一个已有的数据类型的新名字。比如:
typedef int Length;
使得Length成为int类型的别名。
2,这样Length这个名字就可以代替int出现在变量定义和参数声明的地方了:

typedef int Length;
Length a,b,len;
Length numbers[10];

3,声明新的类型的名字
1),新的名字是某种类型的别名。
2),改善了程序的可读性。

好处:
a,重载已有的类型名字,新名字的含义更清晰,既有可移植性。
b,简化了复杂的名字。

typedef int Length; //Length就等价于int类型。

typedef *char[10] Strings;  //Strings是10个字符串的数组的类型

typedef struct node
{
int data;
struct node *next;
}aNode;
//或

typedef struct node aNode ;//这样用aNode就可以代替struct node

版权声明:本笔记为MOOC翁恺老师的课堂笔记,如有侵权,联系删除。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值