2016-07-28 10 views
2

Ich arbeite mit einem Programm, das ein eingegebenes Datum aktualisiert und aktualisiert. Unter Berücksichtigung Tage im Monat und ob es sich um ein Schaltjahr usw.Habe ich in der Funktion updateDate Zeiger richtig verwendet?

Ich bin eine Übung in den Zeiger Kapitel ‚Programmieren in C‘ Versuch:

„die Definition eines date Struktur Da gemäß der Definition Schreiben Sie in diesem Kapitel eine Funktion namens dateUpdate(), die einen Zeiger auf eine date Struktur als Argument verwendet und die Struktur auf den nächsten Tag aktualisiert (siehe Programm 8.4). "

Können Sie mir bitte sagen, ob ich getan habe, was gefragt wurde?

Dies ist der ursprüngliche Code:

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

Und hier ist mein Versuch, Zeiger in der updateFunction zu nutzen:

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

Gerade jetzt beide Programme kompilieren und scheinen richtig zu laufen.

+0

Ich verstehe Ihre Frage nicht vollständig.Aber um einen Zeiger auf die Struktur zu machen, würden Sie struct Daten * morgen machen; Und überall, wo Sie den Punktoperator haben, machen Sie es einfach in den Pfeiloperator ->. Beispiel: Anstatt morgen zu haben. Tag mach es morgen-> Tag; –

+0

Meine Schuld, lassen Sie mich diesen Autounfall einer Frage umschreiben. – gloopit

+0

Haben Sie es versucht? –

Antwort

1

Um auf Omid CompSCI Kommentar zu erweitern: es ist fast genauso einfach. Fast.

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

Ich hoffe, dass es ein bisschen klarer macht.

+0

Vielen Dank! Wenn die Non-Pointer-Strukturen zuerst deklariert werden, zusammen mit ihrer Größe und DANN einen Zeiger zuweisen, kann ich vermeiden, malloc zu verwenden, oder? – gloopit

+0

Malloc ist nicht etwas, das ich noch nicht behandelt habe und ist weiter in dem Buch, das ich studiere. – gloopit

+0

Wenn Sie meinen obigen Versuch sehen, habe ich die Pointer-Syntax für die anderen Funktionen wie 'isLeapYear' oder' numberOfDays' nicht verwendet. Hat es Vorteile, sie in Zeiger umzuwandeln? Das einzige, was geändert wurde, war das Hinzufügen eines '*' und das Wechseln von '.' für ein' -> ' Ich gebe zu, ich mag deine Uniformität aber :) – gloopit

0

Dieser Code kann leicht umgewandelt werden, um Zeiger zu verwenden. Zeiger sind nützlich, da sie eine Alternative zum Kopieren der Daten Ihrer Strukturen bei jedem Aufruf einer Funktion bieten. Sie können die normale Pass-by-Value-Funktion auch an anderer Stelle verwenden. Das Umschreiben des Codes ist sehr einfach und erfordert nur wenige Änderungen. Zum Beispiel kann Ihre struct date dateUpdate();-Funktion zweckentsprechend zum Akzeptieren von Zeigern durch Hinzufügen des *-Symbols nach dem Typ, z. int bis int *. Die Definition Ihrer Funktion struct date dateUpdate würde in struct date *dateUpdate (struct date *today); geändert werden, was bedeutet, dass ein Zeiger oder die Speicheradresse einer Datums-Struktur übergeben wird. Ihr Code muss auch in der Deklaration geändert werden. Zum Beispiel müsste in bool isLeapYear() die Zeile des Codes if ((d.year % 4 == 0 && d.year % d.year % 100 != 0) || d.year % 400 == 0) zu if ((d->year % 4 == 0 && d->year % d->year % 100 != 0) || d->year % 400 == 0) geändert werden. Der Operator -> ist eine Abkürzung für (*pointer).variable, da der Compiler angewiesen werden muss, das Element der Struktur an der Adresse, nicht die tatsächliche Position von, den Zeiger zu erhalten. Nachdem der übergebene Typ geändert wurde, ist auch der Aufruf anders. Der Aufruf bool isLeapYear() ist jetzt nicht bool isLeapYear (d);, aber bool isLeapYear (&d);, da der & Operator die Adresse struct erhält. Verwenden Sie diese Informationen, hier ist eine konvertierte Version Ihres Programms: link. Ein großes Problem ist jedoch, dass viel von Ihrem Code nicht funktioniert, aber das ist außerhalb des Umfangs Ihrer Frage. EDIT: Diese Antwort wurde vor der Bearbeitung der Frage gemacht, ist aber immer noch hilfreich.

+0

Alle jetzt behoben, vielen Dank! – gloopit

0

Hier ist meine Meinung zu dieser Übung, von der ich denke, dass sie einen Zeiger verwendet, um eine einzelne Datumsstruktur mit dem Datum des nächsten Tages zu aktualisieren.

/* 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; 
}