结构作为函数参数
int numberOfDays(struct date d);
- 整个结构可以作为参数的值传入函数
- 这时候是在函数内新建一个结构变量,并复制调用者的结构的值
- 也可以返回一个结构
- 这与数组完全不同
#include<stdio.h>
#include<stdbool.h>
struct date{
int month;
int day;
int year;
};
bool isLeap(struct date d);//是否是闰年 是 返回 true;否 返回 false
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;
}
ptintf("Tomorrow's date is %i-%i-%i.\n",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 = 20;
}
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;
}
输入结构
- 没有直接的方式可以一次scanf一个结构
- 如果我们打算写一个函数来读入结构
#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){
scanf("%d",&p.x);
scanf("%d",&p.y);
printf("%d,%d\n",p.x,p.y);
}
void output(struct point p){
printf("%d,%d",p.x,p.y);
}
5 5
getStruct 5,5
output 0,0
- 但是读入的结构如何送回来呢?
- 所以记住C语言在函数调用时是传值的
- 所以函数中的p与main中的y是不同的
- 在函数读入了p的数值之后,没有任何东西回到main,所以y还是{0,0}
- 所以函数中的p与main中的y是不同的
- 在函数读入了p的数值之后,没有任何东西回到main,所以y还是{0,0}
解决的方案
- 之前的方案,把一个结构传入了函数,然后在函数中操作,但是没有返回回去
- 问题在于传入函数的是外面那个结构的克隆体,而不是指针
- 传入结构和传入数组是不同的
- 在这个输入函数中,完全可以创建一个临时的结构变量,然后把这个结构返回给调用者
#include<stdio.h>
struct point{
int x;
int y;
};
struct point getStruct(void);
void output(struct point);
void main(){
struct point y = {0,0};
y = getStruct();
output(y);
}
struct point getStruct(void){
struct point p;
scanf("%d",&p.x);
scanf("%d",&p.y);
printf("getStruct\t%d,%d\n",p.x,p.y);
return p;
}
void output(struct point p){
printf("output\t%d,%d",p.x,p.y);
}
5 5
getStruct 5,5
output 5,5
结构指针作为参数
- K & R说过(p.131)
“if a large structure is to be passed to a function,
it is generally more efficient to pass a pointer
than to copy the whole structure”
指向结构的指针
struct date{
int month;
int day;
int year;
}myday;
struct date *p = &myday;
(*p).month = 12;
p->month = 12;
- 用->表示指针所指的结构变量中的成员
void main(){
struct point y = {0,0};
inputPoint(&y);
output(y);
}
struct point* inputPoint(struct point *p){
scanf("%d",&(p->x));
scanf("%d",&(p->y));
return p;
}
struct point{
int x;
int y;
};
struct point* getStruct(struct point*);
void output(struct point);
void print(const struct point *p);
int main(void){
struct point y = {0,0};
printf("请输入1\n");
getStruct(&y);
output(y);
printf("请输入2\n");
output(*getStruct(&y));
print(getStruct(&y));
return 0;
}
struct point* getStruct(struct point *p){
scanf("%d",&p->x);
scanf("%d",&p->y);
printf("getStruct\t%d,%d\n",p->x,p->y);
return p;
}
void output(struct point p){
printf("output\t%d,%d\n",p.x,p.y);
}
void print(const struct point *p){
printf("print\t%d,%d\n",p->x,p->y);
}
请输入1
5 4
getStruct 5,4
output 5,4
请输入2
5 4
getStruct 5,4
output 5,4
甚至
*getStruct(&y) = (struct point){1,2};
也是可行的,它表示 *(取)getStruct()函数的返回值,即 那个 结构point,
*getStruct(&y) --> point p*getStruct(&y) = (struct point){1,2} --> point p = (struct point){1,2}