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
编辑器推荐:vscodeProvided 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); } }
相关文章推荐
- Class撑起了OOP世界的天。Class类是OO的基本单元,OO的世界都是通过一个一个的类协作完成的,提高软件的重用性、灵活性和扩展性(转)
- 【C#】16. IMM (Date class 更新)
- OOP Basic--what's the diff between struct & class?
- IOS笔记 this class is not key value coding-compliant for the key datePicker
- class-2 积累应用 echo、date命令
- OOP Basic--Is the class declaration right?[const]
- python3.6.1环境配置出现Requirement already up-to-date: pip in c:\python36\lib\site-packages决解方案
- ssm时间参数报错Could not instantiate bean class [java.util.Date]
- [C++] OOP - Access Control and Class Scope
- android-Date.class
- OOP Class具体解释
- java.text Class SimpleDateFormat 格式详细介绍
- C++ MyClass Date
- error C2629: unexpected \'class Date (\'
- Java学习之路 第四篇 oop和class (面向对象和类)
- Date class
- C++ class Date
- SpringMVC 页面传Date类型值提示Could not instantiate bean class [java.util.Date]: Constructor threw exception
- UseGuessDateClass
- Oracle date 和 timestamp 区别 原文出处: http://www.cnblogs.com/java-class/