结构与函数

结构作为函数参数

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}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值