gloopit - 1 year ago 108
C Question

# Have I utilized pointers properly in the updateDate function?

I am working with a program that updates an inputted date and updates it. Taking into account days in the month and whether it's a leap year etc.

I'm attempting an exercise in the pointers chapter of 'Programming in C':

"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(see Program 8.4)."

Can you please tell me if I have done what was asked?

This is the original 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};
}

}

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

And here is my attempt to utilize pointers in the
`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};
}

}

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

Right now both programs compile and seem to run properly.

To expand on Omid CompSCI's comment: it is almost just as simple. Almost.

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

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

I hope that makes it a bit clearer.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download