您的位置:首页 > 运维架构

1641 OOP in C (Date class)

2017-05-28 15:15 253 查看

Task

学习如何用C模仿C++的类:

How do you implement a class in C?

根据给出的文件实现C中的“Date class”。

Hints

先认真阅读上面的链接。

void DestroyDate(Date** p);
中,传入Date**的作用是避免“野指针”问题,细节请自己思考。

One more step

试试在client代码中直接访问或修改Date的year等变量,跟C++版本有何不同?这会违背OOP吗?

仔细辨别
void SetDate(Date* date, int year, int month, int day)
void Date::setDate(int year, int month, int day);
两者的异同,

包括参数数量,参数类型,命名大小写等(关于命名风格可参照前面提到的《Google C++ Style Guide》)。

大胆猜想早期C++编译器是如何把C++程序转换为C程序的。另外,本题只是C中OOP的一种思路,有兴趣可以进一步了解

“OOP in C”有必要吗?请查阅资料了解其应用场景。

如果
void DestroyDate(Date** p);
传入Date*,可行吗?可能会导致什么问题?

为什么要把free()封装到Destroy()里?直接让client代码调用free()合适吗?

内存资源释放的责任在client身上,可能会有什么问题?有兴趣的同学可以了解C++的解决方案(需要超前学习,选做)。

如果client写出
date2 = date1
这种代码,即两个指针指向同个“对象”,在内存资源释放上会有问题吗?有兴趣的同学可以了解C++的解决方案(需要超前学习,选做)。

Links

编辑器推荐:vscode

Provided Codes

date_client.c

#include "date.h"
#include <stdio.h>
#include <assert.h>

void TestDate(Date* date, int after, int before) {
printf("Year: %d\n", GetYear(date));
printf("Month: %d\n", GetMonth(date));
printf("Day: %d\n", GetDay(date));

char* date_string = GetDateString(date);
printf("Formatted: %s\n", date_string);

DestroyDateString(&date_string);
assert(date_string == NULL);
DestroyDateString(&date_string);

IncreaseDate(date);
date_string = GetDateString(date);
printf("1 day later: %s\n", date_string);
DestroyDateString(&date_string);

int i;
for (i = 0; i < after; ++i) {
IncreaseDate(date);
}
date_string = GetDateString(date);
printf("Another %d day(s) later: %s\n", after, date_string);
DestroyDateString(&date_string);

for (i = 0; i < before; ++i) {
DecreaseDate(date);
}
date_string = GetDateString(date);
printf("Another %d day(s) earlier: %s\n", before, date_string);
DestroyDateString(&date_string);
}

int main() {
int year, month, day;
int after, before;
scanf("%d%d%d%d%d", &year, &month, &day, &after, &before);

Date* date1 = CreateDate(year, month, day);
assert(sizeof(*date1) == sizeof(Date));

Date* date2 = CopyDate(date1);
assert(date1 != date2);
assert(date1->month == date2->month);

SetDate(date1, year + 1, month, day);
SetYear(date1, year);
SetMonth(date1, month);
SetDay(date1, day);

TestDate(date1, after, before);

DestroyDate(&date1);
DestroyDate(&date2);

assert(date1 == NULL);
DestroyDate(&date2);

return 0;
}

/*
One probable test case:

1900 2 28 365 366
Year: 1900
Month: 2
Day: 28
Formatted: 1900-02-28
1 day later: 1900-03-01
Another 365 day(s) later: 1901-03-01
Another 366 day(s) earlier: 1900-02-28

*/


date.h

#ifndef DATE_H_
#define DATE_H_

typedef struct {
int year, month, day;
} Date;

Date* CreateDate(int year, int month, int day);
void DestroyDate(Date** p);
Date* CopyDate(const Date* date);

int GetYear(const Date* date);
int GetMonth(const Date* date);
int GetDay(const Date* date);
void SetYear(Date* date, int
4000
year);
void SetMonth(Date* date, int month);
void SetDay(Date* date, int day);
void SetDate(Date* date, int year, int month, int day);

char* GetDateString(const Date* date);
void DestroyDateString(char** p);

void IncreaseDate(Date* date);
void DecreaseDate(Date* date);

#endif


Submission

date.c

#include<stdlib.h>
#include<stdio.h>
#include "date.h"

Date* CreateDate(int year, int month, int day) {
Date* ppp = (Date*)malloc(sizeof(Date));
ppp->year = year;
ppp->month= month;
ppp->day = day;
return ppp;
}

void DestroyDate(Date** ppp) {
free(*ppp);
*ppp=NULL;
}

Date* CopyDate(const Date* date) {
return CreateDate(date->year, date->month, date->day);
}

int GetYear(const Date* date) {
return date->year;
}

int GetMonth(const Date* date) {
return date->month;
}

int GetDay(const Date* date) {
return date->day;
}

void SetYear(Date* date, int year) {
date->year = year;
}

void SetMonth(Date* date, int month) {
date->month = month;
}

void SetDay(Date* date, int day) {
date->day = day;
}

void SetDate(Date* date, int year, int month, int day) {
date->year = year;
date->month = month;
date->day = day;
}

char* GetDateString(const Date* date) {
char* str = (char*)calloc(11, sizeof(char));
sprintf(str, "%04d-%02d-%02d", date->year, date->month, date->day);
return str;
}

void DestroyDateString(char** ppp) {
free(*ppp);
*ppp=NULL;
}

int Day(int month,int year){
if(month==2){
if(year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
return 29;
return 28;
}
else if(month>0&&month<8){
if(month%2==0)
return 30;
return 31;
}
if(month%2==0)
return 31;
return 30;
}

void IncreaseDate(Date* date) {
date->day++;
if (date->day > Day(date->month,date->year)) {
date->day = 1;
date->month++;
}
if (date->month > 12) {
date->month = 1;
date->year++;
}

}

void DecreaseDate(Date* date) {
date->day--;
if (date->day < 1&&date->month==1) {
date->month=12;
date->year--;
date->day=31;
}
else if(date->day < 1){
date->month--;
date->day = Day(date->month,date->year);
}
}


Standard Answer

date.c

#include "date.h"
#include <stdlib.h>
#include <stdio.h>

Date* CreateDate(int year, int month, int day) {
Date* date = (Date*)malloc(sizeof(Date));
date->year = year;
date->month = month;
date->day = day;
return date;
}

void DestroyDate(Date** p) {
if (*p) {
free(*p);
*p = NULL;
}
}

Date* CopyDate(const Date* date) {
Date* new_date = (Date*)malloc(sizeof(Date));
new_date->year = GetYear(date);
new_date->month = GetMonth(date);
new_date->day = GetDay(date);
return new_date;
}

int GetYear(const Date* date) { return date->year; }
int GetMonth(const Date* date) { return date->month; }
int GetDay(const Date* date) { return date->day; }
void SetYear(Date* date, int year) { date->year = year; }
void SetMonth(Date* date, int month) { date->month = month; }
void SetDay(Date* date, int day) { date->day = day; }
void SetDate(Date* date, int year, int month, int day) {
date->year = year;
date->month = month;
date->day = day;
}

char* GetDateString(const Date* date) {
const int length_of_date_string = 10;
char* date_string = (char*)malloc(sizeof(char)*(length_of_date_string + 1));
snprintf(date_string,
length_of_date_string + 1,
"%04d-%02d-%02d",
GetYear(date), GetMonth(date), GetDay(date));
return date_string;
}

void DestroyDateString(char** p) {
if (*p) {
free(*p);
*p = NULL;
}
}

int GetDaysOfMonth(int year, int month) {
if (month == 2) {
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 29 : 28;
} else {
int daysOfMonth[13] = { -1, 31, -1, 31, 30,
31, 30, 31, 31,
30, 31, 30, 31 };
return daysOfMonth[month];
}
}

void IncreaseDate(Date* date) {
++date->day;
if (date->day > GetDaysOfMonth(date->year, date->month)) {
date->day = 1;
++date->month;
if (date->month > 12) {
date->month = 1;
++date->year;
}
}
}

void DecreaseDate(Date* date) {
--date->day;
if (date->day < 1) {
--date->month;
if (date->month < 1) {
date->month = 12;
--date->year;
}
date->day = GetDaysOfMonth(date->year, date->month);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++