结构与函数

一、结构变量可以直接在函数之间传递

#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);
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值