一、结构变量可以直接在函数之间传递
#include <stdio.h>
#include <stdbool.h>
//定义函数结构date
struct date{
int month;
int day;
int year;
};
bool isLeap(struct date d);//函数isLeap声明
int numberOfDays(struct date d);//函数numberOfDays声明
int main()
{
struct date today,tomorrow;
//定义date结构类型的结构变量today和tomorrow
printf("输入今天的日期(月月 日日 年年):");
scanf("%i %i %i",&today.month,&today.day,&today.year);
//&today.month中可以看出"."的优先级高于"&"
if(today.day!=numberOfDays(today)){
//如果这一天不是这个月的最后一天那么天数+1月和年保持不变
tomorrow.day=today.day+1;
tomorrow.month=today.month;
tomorrow.year=today.year;
} else if(today.month==12){
//如果月份等于12月那么年份+1天数和月数都变成1
tomorrow.day=1;
tomorrow.month=1;
tomorrow.year=today.year+1;
}else{
//如果经上面判断月份不等于12月,且这一天是这个月的最后一天那么月份+1天数和年份保持不变
tomorrow.day=1;
tomorrow.month=today.month+1;
tomorrow.year=today.year+1;
}
printf("明天的日期是%i-%i-%i.\n",tomorrow.year,tomorrow.month,tomorrow.day);
return 0;
}
int numberOfDays(struct date d)
{
int days;//定义变量天数
const int dayPerMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
//设立固定不变数组内容为每个月天数
if(d.month==2&&isLeap(d)){
//如果结构d中变量month的值是2月并且经过isLeap()函数判断是闰年就将日期改为29天
days=29;
} else{
//如果不是上述结果,那么天数=数组daysPerMonth[]下标为结构d中变量month的值-1的天数(因为数组首位是0)
days=dayPerMonth[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;
}
二、 结构作为函数参数
结构无法直接用scanf或者printf读入输出
结构作为函数参数 int numberOfDays(struct date d)
整个结构可以作为参数的值传入函数,但是此时是在函数的内部新形成一个结构变量,然后复制传入结构变量的值,需注意在此函数内对结构变量的值所做的操作,仅限于此函数内,对原来的结构变量的值没有影响
因为C语言中除指针做参数外其余参数只传值
#include <stdio.h>
//定义point结构类型,point类型内含有两个成员x,y
struct point{
int x;
int y;
};
void getStruct(struct point);
//函数 getStruct声明需要point结构类型变量做参数
void output(struct point);
//函数 output声明需要point结构类型变量做参数
int main()
{
struct point y={0,0};//定义point结构类型变量y赋初值为0
getStruct(y);
//调用 getStruct函数并将point结构类型变量y的值做参数
output(y);
//调用 output函数并将point结构类型变量y的值做参数
}
void getStruct(struct point p)
//函数作用:将读入point结构类型变量p的成员x ,y输出
{
scanf("%d",&p.x);//读入point结构类型变量p的成员x
scanf("%d",&p.y);//读入point结构类型变量p的成员y
printf("%d %d\n",p.x,p.y);
}
void output(struct point p)
//函数作用:将传入的point结构类型变量p的成员x,y原样输出
{
printf("%d %d\n",p.x,p.x);
}
改进方法:
在函数中不接收参数结构,直接创建一个临时结构变量,然后把这个结构返回给调用位置
#include <stdio.h>
//定义point结构类型,point类型内含有两个成员x,y
struct point{
int x;
int y;
};
struct point getStruct(void);
//函数 getStruct声明不接收传入但是返回 point结构变量
void output(struct point);
//函数 output声明需要point结构类型变量做参数
int main()
{
struct point y={0,0};//定义point结构类型变量y赋初值为0
y=getStruct();//将函数getStruc()返回的值赋值给point结构类型变量y
//调用 getStruct函数并将point结构类型变量y的值做参数
output(y);
//调用 output函数并将point结构类型变量y的值做参数
}
struct point getStruct(void)
//函数作用:将读入point结构类型变量p的成员x ,y输出
{
struct point p; //自己定义point结构类型变量p
scanf("%d",&p.x);//读入point结构类型变量p的成员x
scanf("%d",&p.y);//读入point结构类型变量p的成员y
printf("%d %d\n",p.x,p.y);
return p;//返回point类型结构变量给调用位置
}
void output(struct point p)
//函数作用:将传入的point结构类型变量p的成员x,y原样输出
{
printf("%d %d\n",p.x,p.y);
}
三、结构指针做参数
strucr date{
int month;
int day;
int year;
}myday;
//定义date结构类型然后定义date结构类型的变量myday
struct date *p=&myday;
(*p).month=12;
(*p).month是表示指针p所指向的地址所对应的变量成员month即myday.month
//也可以写为p->month,同样表示指针p指向的结构变量成员
改进方法2 :
K&R一书中提到(131页)
如果有较大的结构变量需要传入函数,指针会比较有优势
#include <stdio.h>
//定义point结构类型,point类型内含有两个成员x,y
struct point{
int x;
int y;
};
struct point *getStruct(struct point *);
//函数 getStruct声明需要 point结构类型指针做参数并返回point类型指针
void output(struct point);
//函数 output声明需要point结构类型变量做参数
void print(const struct point *p);
//函数print声明需要point结构类型指针做参数
int main()
{
struct point y={0,0};//定义point结构类型变量y赋初值为0
getStruct(&y);//将point结构类型变量y的地址交给函数getStruc()
//调用 getStruct函数并将point结构类型变量y的地址做参数
output(y);
//调用 output函数并将point结构类型变量y的值做参数
output(*getStruct(&y));
//getStruct(&y)可以得到函数getStruct运算后返回的指针,
//前面加*表示取出此指针对应的值,将此值作为参数直接传给函数output
print(getStruct(&y));
//getStruct(&y)函数调用point结构类型变量y后返回指针类型数据,
//然后将此指针直接作为参数传递给print函数
//下面两句只是尝试这种写法可以运行与实际程序无关
getStruct(&y)->x=0;//令getStruct函数返回的指针指向x,将x赋值为0
*getStruct(&y)=(struct point){1,2};
//*getStruct(&y)取出指针getStruct(&y)对应的值,
//将其强制转换成 struct point类型并赋值1,2
}
struct point *getStruct(struct point *p)
//getStruct函数接收 struct point类型的指针作为参数,并且返回struct point类型的指针
//函数作用:将指针指向的成员进行赋值然后返回指针
{
scanf("%d",&(*p).x);//读入数据给point结构类型指针p指向的成员x
// scanf("%d",&p->x);也可写为此种形式
scanf("%d",&(*p).y);//读入数据给point结构类型指针p指向的成员y
// scanf("%d",&p->y);
printf("%d %d\n",(*p).x,(*p).y);
return p;//返回point类型结构变量给调用位置
}
void output(struct point p)
//函数作用:将传入的point结构类型变量p的成员x,y原样输出
{
printf("%d %d\n",p.x,p.y);
}
void print(const struct point *p)
{
printf("%d,%d\n",(*p).x,(*p).y);
}