我是否在updateDate函数中正确使用了指针?

问题描述:

我正在使用更新输入日期并更新它的程序。考虑到天的月份和它是否是闰年等我是否在updateDate函数中正确使用了指针?

我试图在“C程序”的指针章节练习:

“给定date结构的定义,定义在本章中,编写一个名为dateUpdate()的函数,它将一个指向date结构的指针作为它的参数,并将结构更新到第二天(参见程序8.4)。“

你可以告诉我,如果我已经做了什么被问了吗?

这是原来的代码:

#include <stdio.h> 
#include <stdbool.h> 

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


struct date dateUpdate (struct date today); 
int numberOfDays (struct date d); 
bool isLeapYear(struct date d); 

int main (void) 
{ 
    struct date thisDay, nextDay; 

    printf("Enter today's date (mm dd yyyy) : "); 
    scanf("%i%i%i", &thisDay.month, &thisDay.day, &thisDay.year); 

    nextDay = dateUpdate(thisDay); 

    printf("Tomorrow's date is %i/%i/%.2i.\n", nextDay.month, nextDay.day, nextDay.year % 100); 

    return 0; 
} 


struct date dateUpdate (struct date today) 
{ 
    struct date tomorrow; 
    int numberOfDays (struct date d); 

    if(today.day != numberOfDays (today)) 
    { 
     tomorrow = (struct date) {today.month, today.day + 1, today.year}; 
    } 
    else if(today.month == 12) 
    { 
     tomorrow = (struct date) {1, 1, today.year + 1}; 
    } 
    else 
    { 
     tomorrow = (struct date) {today.month + 1, 1, today.year}; 
    } 

    return tomorrow; 
} 

int numberOfDays (struct date d) 
{ 
    int days; 
    bool isLeapYear (struct date d); 
    const int daysPerMonth[12] = 
     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

    if(isLeapYear (d) && d.month == 2) 
    { 
     days = 29; 
    } 
    else 
    { 
     days = daysPerMonth[d.month - 1]; 
    } 

    return days; 
} 

bool isLeapYear(struct date d) 
{ 
    bool leapYearFlag; 

    if ((d.year % 4 == 0 && d.year % d.year % 100 != 0) || d.year % 400 == 0) 
    { 
     leapYearFlag = true; 
    } 
    else 
    { 
     leapYearFlag = false; 
    } 

    return leapYearFlag; 
} 

这里是我试图利用在updateFunction指针:

#include <stdio.h> 
#include <stdbool.h> 

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


struct date dateUpdate (struct date* today); 
int numberOfDays (struct date d); 
bool isLeapYear(struct date d); 

int main (void) 
{ 
    struct date thisDay, nextDay, *datePtr; 

    printf("Enter today's date (mm dd yyyy) : "); 
    scanf("%i%i%i", &thisDay.month, &thisDay.day, &thisDay.year); 

    datePtr = &thisDay; 

    nextDay = dateUpdate(datePtr); 

    printf("Tomorrow's date is %i/%i/%.2i.\n", nextDay.month, nextDay.day, nextDay.year % 100); 

    return 0; 
} 


struct date dateUpdate (struct date* today) 
{ 
    struct date tomorrow; 
    int numberOfDays (struct date d); 

    if(today->day != numberOfDays (*today)) 
    { 
     tomorrow = (struct date) {today->month, today->day + 1, today->year}; 
    } 
    else if(today->month == 12) 
    { 
     tomorrow = (struct date) {1, 1, today->year + 1}; 
    } 
    else 
    { 
     tomorrow = (struct date) {today->month + 1, 1, today->year}; 
    } 

    return tomorrow; 
} 

int numberOfDays (struct date d) 
{ 
    int days; 
    bool isLeapYear (struct date d); 
    const int daysPerMonth[12] = 
     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

    if(isLeapYear (d) && d.month == 2) 
    { 
     days = 29; 
    } 
    else 
    { 
     days = daysPerMonth[d.month - 1]; 
    } 

    return days; 
} 

bool isLeapYear(struct date d) 
{ 
    bool leapYearFlag; 

    if ((d.year % 4 == 0 && d.year % d.year % 100 != 0) || d.year % 400 == 0) 
    { 
     leapYearFlag = true; 
    } 
    else 
    { 
     leapYearFlag = false; 
    } 

    return leapYearFlag; 
} 

现在这两个程序编译,似乎运行正常。

+0

我不完全理解你的问题。但是为了制作一个指向结构体的指针,你可以在明天做struct data *无论你在哪里,点运算符都可以进入箭头运算符 - >。例如:明天 - 而不是明天 - >日; –

+0

我的错,让我改写这个问题的车祸。 – gloopit

+0

你试过了吗? –

为了扩大Omid CompSCI的评论:它几乎是一样简单。几乎。

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 

// ALL TESTS OMMITTED! 

struct date { 
    int month; 
    int day; 
    int year; 
}; 
// add the pointer mark (asterix) 
struct date *dateUpdate(struct date *today); 
int numberOfDays(struct date *d); 
bool isLeapYear(struct date *d); 

int main(void) 
{ 
    // again ,just add the pointer marks 
    struct date *thisDay, *nextDay; 
    // using a pointer means that all you have is a pointer 
    // but you need some memory to store the content 
    thisDay = malloc(sizeof(struct date)); 

    printf("Enter today's date (mm dd yyyy) : "); 
    // use the "->" notation to get to the respective storages 
    scanf("%i%i%i", &thisDay->month, &thisDay->day, &thisDay->year); 

    // dateUpdate() has been changed to accept and return a pointer, 
    // so no change in notations here 
    nextDay = dateUpdate(thisDay); 
    // again: use the "->" notation to get to the respective storages 
    printf("Tomorrow's date is %i/%i/%.2i.\n", nextDay->month, nextDay->day, 
    nextDay->year % 100); 

    // memory allocated by 'alloc() needs to be free'd, too 
    free(nextDay); 
    free(thisDay); 

    return 0; 
} 

// just added pointer markings 
struct date *dateUpdate(struct date *today) 
{ 
    struct date *tomorrow; 
    // again, we need to allocated some memory 
    // not only to get storage but also to be able to return it 
    tomorrow = malloc(sizeof(struct date)); 
    // again: use the "->" notation to get to the respective storages 
    if (today->day != numberOfDays(today)) { 
    // the notation of the cast does not change, the target does 
    *tomorrow = (struct date) { 
    today->month, today->day + 1, today->year}; 
    } else if (today->month == 12) { 
    *tomorrow = (struct date) { 
    1, 1, today->year + 1}; 
    } else { 
    *tomorrow = (struct date) { 
    today->month + 1, 1, today->year}; 
    } 
    return tomorrow; 
} 

int numberOfDays(struct date *d) 
{ 
    int days; 
    const int daysPerMonth[12] = 
     { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 

    if (isLeapYear(d) && d->month == 2) { 
    days = 29; 
    } else { 
    days = daysPerMonth[d->month - 1]; 
    } 

    return days; 
} 

bool isLeapYear(struct date * d) 
{ 
    bool leapYearFlag; 
    // you have one "d.year %" too much in your code 
    if ((d->year % 4 == 0 && d->year % 100 != 0) || d->year % 400 == 0) { 
    leapYearFlag = true; 
    } else { 
    leapYearFlag = false; 
    } 

    return leapYearFlag; 
} 

我希望能让它更清楚一点。

+0

非常感谢! 如果首先声明非指针结构及其大小,然后分配一个指针,那么我可以避免使用malloc,对吗? – gloopit

+0

Malloc是不是我还没有覆盖,并在我正在学习的书进一步。 – gloopit

+0

如果你看到我上面的尝试,我没有使用指针语法的其他功能,如'isLeapYear'或'numberOfDays'。将它改为指针有什么好处吗?我认为只是增加了一个'*'并将'.'换成了' - >' 我承认我喜欢你的一致性:) – gloopit

此代码可以很容易地转换为使用指针。指针是有用的,因为它们提供了一种替代方法来在每次调用函数时复制结构体的数据。您仍然可以在其他地方使用正常的通过价值机制。重写代码非常简单,只需要很少的更改。例如,您的struct date dateUpdate();函数可以重新用于接受指针,方法是在类型之后添加*符号,例如, intint *。 函数struct date dateUpdate的定义将更改为struct date *dateUpdate (struct date *today);,这意味着正在传递日期结构的指针或内存地址。您的代码也必须在声明中更改。例如,在bool isLeapYear()中,代码行 if ((d.year % 4 == 0 && d.year % d.year % 100 != 0) || d.year % 400 == 0) 必须更改为 if ((d->year % 4 == 0 && d->year % d->year % 100 != 0) || d->year % 400 == 0)->运算符是(*pointer).variable的简写,因为必须通知编译器获取结构的成员地址,而不是指针的实际位置。 现在传入的类型已更改,调用也不同。调用bool isLeapYear()现在不是bool isLeapYear (d);,而是 bool isLeapYear (&d);,因为&运营商获取的地址为struct。 使用这些信息,这里是您的程序的转换版本:link. 然而,一个很大的问题是,你的大部分代码不起作用,但这超出了你的问题的范围。 编辑:这个答案是在你编辑问题之前做出的,但仍然有帮助。

+0

现在所有修正,非常感谢! – gloopit

下面是我对这个练习的看法,我认为这个练习旨在使用指针更新第二天的日期的单个日期结构。

/* Exercise 10.11 

    Given the definition of a date structure as defined in this chapter, write 
    a function called dateUpdate() that takes a pointer to a date structure as 
    its argument and that updates the structure to the following day. 
*/ 

#include <stdio.h> 
#include <stdbool.h> 

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

void dateUpdate (struct date *ptr) 
{ 
    int numberOfDays (struct date d); 

    if (ptr->day != numberOfDays (*ptr)) 
     ++ptr->day; 
    else if (ptr->month == 12) {     // end of year 
     ptr->day = 1; 
     ptr->month = 1; 
     ++ptr->year; 
    } 
    else {           // end of month 
     ptr->day = 1; 
     ++ptr->month; 
    } 
} 

int numberOfDays (struct date d) 
{ 
    bool isLeapYear (struct date d); 

    int days; 
    const int daysPerMonth[12] = 
     { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 

    if (isLeapYear (d) && d.month == 2) 
     days = 29; 
    else 
     days = daysPerMonth[d.month - 1]; 

    return days;   
} 

bool isLeapYear (struct date d) 
{ 
    bool leapYearFlag; 

    if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0) 
     leapYearFlag = true;      // leap year 
    else 
     leapYearFlag = false;      // not a leap year 

    return leapYearFlag;   
} 

int main (void) 
{ 
    void dateUpdate (struct date *ptr); 

    struct date calendar; 

    printf ("Enter a day's date (mm dd yyyy): "); 
    scanf ("%i%i%i", &calendar.month, &calendar.day, &calendar.year); 

    dateUpdate (&calendar); 

    printf ("The next day's date is %i/%i/%.2i.\n", calendar.month, 
      calendar.day, calendar.year % 100); 

    return 0; 
}