结构指针

ぐ巨炮叔叔 提交于 2020-02-27 13:14:03

1.结构作为函数参数
int numberOfDays(struct date d)
整个结构可以作为参数的值传入函数
这时候是在函数内新建一个结构变量,并复制调用这个结构的值
也可以返回一个结构
这与数组完全不同

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

bool isLeap(struct date d);//判断这一天所在的年份是不是闰年   #include <stdbool.h>
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.\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=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.输入结构
没有直接的方式可以一次scanf一个结构
如果我们打算写一个函数来读入结构?

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){//结构p作为参数,接收到的是y这个变量的值,所以现在p是一个和y具有相同值的另外一个结构变量
    scanf("%d",&p.x);//y里的值还是0,0,并没有动它  12
    scanf("%d",&p.y);//23
    printf("%d.%d\n",p.x,p.y);//12.23
}
void output(struct point p){
    printf("%d.%d\n",p.x,p.y);//0.0
}

y的值并没有改变

但是读入的结构如何送回来呢?
记住C在函数调用时是传值的
所以函数中的p与main中的y是不同的
在函数读入了p的数值之后,没有任何东西回到main,所以y还是{0,0}

3.解决的方案
之前的方案,把一个结构传入了函数,然后在函数中操作,但是没有返回回去
问题在于传入函数的是外面那个结构的克隆体,而不是指针
传入结构和传入数组是不同的
解决方案一:
在这个输入函数中,完全可以创建一个临时的结构变量,然后把这个结构返回给调用者

struct point{
    int x;
    int y;
};
struct point getStruct(void);
void output(struct point);

int main(int argc,char const *argv[])
{
    struct point y={0,0};
    y=getStruct();//让getStruct返回一个结构变量,把这个结构变量赋值赋给了y,此时y就能够得到你在getStruct里传进去的值
    output(y);
}
struct point getStruct(void){
    struct point p;//本地变量p,在离开这个函数时会消失掉
    scanf("%d",&p.x);//12
    scanf("%d",&p.y);//23
    printf("%d.%d\n",p.x,p.y);//12.23
    return p;
}
void output(struct point p){
    printf("%d.%d\n",p.x,p.y);//12.23
}

4.结构指针作为参数
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
如果你有一个大的结构变量要传进一个函数,通常更为有效地方式,是传指针,而不是拷贝整个结构

5.指向结构的指针
struct date{
int month;
int day;
int year;
}myday;

struct date *p=&myday;

(*p).month=12;
p->month=12;
用->表示指针所指的结构变量中的成员

struct point{
    int x;
    int y;
};
struct point* getStruct(struct point*);
void output(struct point);
void print(const struct point *p);

int main(int argc,char const *argv[])
{
    struct point y={0,0};
    getStruct(&y);//2.调用getStruct时,给了它这个指针&y
    output(y);
    output(*getStruct(&y));//*运算符用来取出它右边的那个指针所指的那个变量,现在它右边的指针是getStruct(&y)这个函数的返回值
    print(getStruct(&y));//5.getStruct函数得到的那个指针,就拿来传给print,getStruct就作为了print的一个参数
    //理解这句*getStruct(&y)=(struct point){1,2};//在这个赋值号的左边出现的是*一个函数的返回结果,没有问题,在赋值号的左边不是变量
}
struct point* getStruct(struct point* p){//1.getStruct函数,要一个指针*p
    scanf("%d",&p->x);
    scanf("%d",&p->y);
    printf("%d.%d\n",p->x,p->y);
    return p;//3.传进来一个指针,对它进行操作后,再把它返回出去,这样的好处是:将来可以把它串在其它函数的调用当中
}
void output(struct point p){//output函数要结构本身,而不是指针
    printf("%d,%d\n",p.x,p.y);
}
void print(const struct point *p)//4.如print函数也要一个指针
{
    printf("%d,%d",p->x,p->y);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!