提高可读性[关闭]
Posted
技术标签:
【中文标题】提高可读性[关闭]【英文标题】:Improving readability [closed] 【发布时间】:2022-01-22 23:21:50 【问题描述】:我需要找到最小的日期(年、月、日、小时、分钟、秒),我的代码正在运行,但它看起来很糟糕而且很长。我能做些什么来避免这个阶梯使我的代码可读? (我只想使用 stdio.h )
#include <stdio.h>
typedef struct DateTime_s
int year , month , day ;
int hours , minutes , seconds ;
DateTime ;
void DataTime(const DateTime *mas , int x)
int i;
struct DateTime_s min=40000,400000,4000000,400000,400000,4000;
for(i=0;i<x;i++)
if(mas[i].year<min.year)
min=mas[i];
else if(mas[i].year==min.year)
if(mas[i].month<min.month)
min=mas[i];
else if(mas[i].month==min.month)
if(mas[i].day<min.day)
min=mas[i];
else if(mas[i].day==min.day)
if(mas[i].hours<min.hours)
min=mas[i];
else if(mas[i].hours==min.hours)
if(mas[i].minutes<min.minutes)
min=mas[i];
else if(mas[i].minutes==min.minutes)
if(mas[i].seconds<min.seconds)
min=mas[i];
else if(mas[i].seconds==min.seconds)
min=mas[i];
printf("%d %d %d %d %d %d",min.year,min.month,min.day,min.hours,min.minutes,min.seconds);
int main()
int x,i;
struct DateTime_s mas[50001];
scanf("%d",&x);
for(i=0;i<x;i++)
struct DateTime_s b;
scanf("%d %d %d %d %d %d",&b.year, &b.month,&b.day,&b.hours,&b.minutes,&b.seconds);
mas[i]=b;
DataTime(mas,x);
return 0;
【问题讨论】:
如果您的代码工作正常,并且您正在寻找代码审查 cmets,请前往 Code Review 将时间戳转换为纪元时间可能更有意义。这将花费额外的费用,但会将比较链减少为单次检查。但如果你还是要这样做...... 如果你使用一致的缩进,代码会更容易阅读。缩进每个else if
是不习惯的。
我投票结束这个问题,因为它属于代码审查的 "migrated"。
放大 Lundin 的评论:首先要做的是为长 if/else 链的 N 个分支中的每一个使用 same 缩进级别。尽管这可以说是“不一致的”,但几乎每个人都同意这比让它无情地向右移动要好得多。
【参考方案1】:
可以使用continue
来减少阶梯效果。但它是否提高了可读性是一个不同的问题......:
void DataTime(const DateTime* mas, int x)
int i;
struct DateTime_s min = 40000,400000,4000000,400000,400000,4000 ;
for (i = 0; i < x; i++)
if (mas[i].year < min.year)
min = mas[i];
continue;
else if (mas[i].year > min.year) continue;
if (mas[i].month < min.month)
min = mas[i];
continue;
else if (mas[i].month > min.month) continue;
if (mas[i].day < min.day)
min = mas[i];
continue;
else if (mas[i].day == min.day) continue;
if (mas[i].hours < min.hours)
min = mas[i];
continue;
else if (mas[i].hours > min.hours) continue;
if (mas[i].minutes < min.minutes)
min = mas[i];
continue;
else if (mas[i].minutes > min.minutes) continue;
if (mas[i].seconds <= min.seconds)
min = mas[i];
printf("%d %d %d %d %d %d", min.year, min.month, min.day, min.hours, min.minutes, min.seconds);
【讨论】:
哎呀。最好将比较移至函数。然后min = mas[i]; continue;
变成return a;
【参考方案2】:
我建议将其拆分为两个功能。检查一个DateTime
是否小于另一个DateTime
以及循环的函数。
删除大量嵌套的if
s 也有助于提高可读性。
如果您还需要进行排序和搜索,这里有一个函数可以与sort
和bsearch
一起使用:
int compar(const void *Lhs, const void *Rhs)
const DateTime* lhs = Lhs;
const DateTime* rhs = Rhs;
if(lhs->year < rhs->year) return -1;
if(lhs->year > rhs->year) return 1;
if(lhs->month < rhs->month) return -1;
if(lhs->month > rhs->month) return 1;
if(lhs->day < rhs->day) return -1;
if(lhs->day > rhs->day) return 1;
if(lhs->hours < rhs->hours) return -1;
if(lhs->hours > rhs->hours) return 1;
if(lhs->minutes < rhs->minutes) return -1;
if(lhs->minutes > rhs->minutes) return 1;
if(lhs->seconds < rhs->seconds) return -1;
if(lhs->seconds > rhs->seconds) return 1;
return 0;
void DataTime(const DateTime mas[], int x)
struct DateTime_s min = mas[0];
for(int i = 1; i < x; i++)
if(compar(&mas[i], &min) < 0) min = mas[i];
printf("%d %d %d %d %d %d", min.year, min.month, min.day, min.hours,
min.minutes, min.seconds);
【讨论】:
次要备注:如果您可以调整less
以使用返回类型int
和两个const void*
,您也许可以将它与bsearch
一起使用而不是循环。不过,可能只有在有大量排序数据的情况下才有意义。
@TedLyngmo 我正要像 Lundin 一样发表评论;但仅限于 int 的返回类型。另外,我认为将!=
替换为>
可能会更好一些,以反映您尽早退出的“不少于”条件。
@EdwinBuck const void*
参数是必要的。不幸的是,这会降低类型安全性。
@Lundin 我无法摆脱这个想法,所以我把它做成了可以与sort
和bsearch
一起使用的东西。
@Lundin 是的,它们是必要的;但是,我的 cmets 并没有考虑使用 bsearch
,而是将 less
扩展为直接与 DateTime
s 绑定的 compare
功能。如果您不关心使其兼容,则可以使用更强的类型绑定。【参考方案3】:
提高可读性的最有效工具之一是函数!
DateTime *min_dt(const DateTime *a, const DateTime *b)
if ( a->year != b->year ) return (DateTime*)( a->year < b->year ? a : b );
if ( a->month != b->month ) return (DateTime*)( a->month < b->month ? a : b );
if ( a->day != b->day ) return (DateTime*)( a->day < b->day ? a : b );
if ( a->hours != b->hours ) return (DateTime*)( a->hours < b->hours ? a : b );
if ( a->minutes != b->minutes ) return (DateTime*)( a->minutes < b->minutes ? a : b );
if ( a->seconds != b->seconds ) return (DateTime*)( a->seconds < b->seconds ? a : b );
return a;
void DataTime(const DateTime *mas, size_t n)
if (n == 0)
return; // Or whatever
const DateTime *min = &mas[0];
for (size_t i=1; i<n; ++i)
min = min_dt(min, &mas[i]);
printf("%d %d %d %d %d %d",
min->year, min->month, min->day,
min->hours, min->minutes, min->seconds
);
不幸的是,const
的删除使这条线有点长。但是函数需要同时使用指向常量的指针和指向非常量的指针。这个问题可以通过返回一个布尔值来避免。
【讨论】:
最后一次检查,还需要检查if ( a->seconds != b->seconds )
吗?如果它通过minute
过滤器,如果我没有完全关闭,你可以只使用return (DateTime*)( a->seconds < b->seconds ? a : b );
。
@Ted Lyngmo,我知道。我追求统一 :) 我希望优化器能解决这个问题。【参考方案4】:
/**
* Compares to DateTimes.
*
* @return -1 when the first is earlier
* 0 when they are equal
* 1 when the seconde is earlier
*/
int DateTime_compare(const DateTime* lhs, const DateTime* rhs)
if (lhs->year < rhs->year) return -1;
if (lhs->year > rhs->year) return 1;
if (lhs->month < rhs->month) return -1;
if (lhs->month > rhs->month) return 1;
if (lhs->day < rhs->day) return -1;
if (lhs->day > rhs->day) return 1;
if (lhs->hours < rhs->hours) return -1;
if (lhs->hours > rhs->hours) return 1;
if (lhs->minutes < rhs->minutes) return -1;
if (lhs->minutes > rhs->minutes) return 1;
if (lhs->seconds < rhs->seconds) return -1;
if (lhs->seconde > rhs->seconds) return 1;
return 0;
/** Find the minimum */
void DataTime(const DateTime mas[], int x)
struct DateTime_s min = 40000, 400000, 4000000, 400000, 400000, 4000;
for (int i = 0; i < x; i++)
min = (DateTime_compare( &mas[i], &min ) < 0) ? mas[i] : min;
printf("%d %d %d %d %d %d", min.year, min.month, min.day, min.hours,
min.minutes, min.seconds);
【讨论】:
【参考方案5】:您可以转换为浮动类型:
double min_fltime = 99999.9*9999999, fltime;
int i, xmin;
for(i=0;i<x;i++)
fltime = mas[i].seconds
+ mas[i].minutes * 60
+ mas[i].hours * 3600
+ mas[i].day * 24*3600
+ mas[i].month * 365.25*24*3600
+ mas[i].year * 12* 365.25*24*3600;
if (fltime < min_fltime)
min_fltime = fltime;
xmin = i;
#define M mas[i]
printf("%d %d %d %d %d %d %f\n",M.year,M.month,M.day,M.hours,M.minutes,M.seconds, fltime);
#define MM mas[xmin]
printf("min\n%d %d %d %d %d %d %f", MM.year,MM.month,MM.day,MM.hours,MM.minutes,MM.seconds, min_fltime);
fltime
赋值应该是一个函数,并且从第一个日期开始。
输出:
1999 12 31 12 45 7 757385124307.000000
999 6 17 10 59 59 378503362799.000000
999 6 18 10 59 59 378503449199.000000
999 6 17 10 59 58 378503362798.000000
min
999 6 17 10 59 58 378503362798.000000
对于该地区的有效日期,它似乎有效。
【讨论】:
以上是关于提高可读性[关闭]的主要内容,如果未能解决你的问题,请参考以下文章