提高可读性[关闭]

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 以及循环的函数。

删除大量嵌套的ifs 也有助于提高可读性。

如果您还需要进行排序和搜索,这里有一个函数可以与sortbsearch 一起使用:

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 的返回类型。另外,我认为将!= 替换为&gt; 可能会更好一些,以反映您尽早退出的“不少于”条件。 @EdwinBuck const void* 参数是必要的。不幸的是,这会降低类型安全性。 @Lundin 我无法摆脱这个想法,所以我把它做成了可以与sortbsearch 一起使用的东西。 @Lundin 是的,它们是必要的;但是,我的 cmets 并没有考虑使用 bsearch,而是将 less 扩展为直接与 DateTimes 绑定的 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-&gt;seconds != b-&gt;seconds )吗?如果它通过minute 过滤器,如果我没有完全关闭,你可以只使用return (DateTime*)( a-&gt;seconds &lt; b-&gt;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

对于该地区的有效日期,它似乎有效。

【讨论】:

以上是关于提高可读性[关闭]的主要内容,如果未能解决你的问题,请参考以下文章