gpt4 book ai didi

c - 我的 friend 说我的代码很难阅读,我不明白为什么

转载 作者:行者123 更新时间:2023-11-30 21:47:18 24 4
gpt4 key购买 nike

好的,所以我试图解决这个问题:

https://dmoj.ca/problem/ccc11s2

我的解决方案如下:

#define in(ptr, i) while(i-->0){scanf(" %c", ptr++);} 
#define ans(ptr, i, n) while(i-->0){getchar(); (getchar()!=*(ptr++))?: n++;}
#define rst(ptr, r, i, n) ptr=r;i=n

int main(){

int n, nCorrect = 0, i;
scanf("%d", &n);
i = n;

char r[n];
char* ptr = r;

in(ptr, i);
rst(ptr, r, i, n);
ans(ptr, i, nCorrect);

printf("%d\n", nCorrect);

return 0;
}

我的 friend 一直告诉我我不应该这样写。我的印象是使用 #define让它先运行,因此程序运行得更快。

谢谢!

最佳答案

这是cargo cult programming . #define不会“让事情变得更快”,它内联代码,有时内联代码是更快的做事方式。

您的变量名称完全不透明,您正在做诸如使用三元组之类的事情,除了看起来很酷之外没有其他真正的原因。这段代码是“最小的”,因为它可能有效(没有测试)并且就字符数而言,但除此之外是 完全无法维护 .

我是作为一个写过很多(有时是故意的)不透明 Perl 代码的人说的:不要 .

编写代码时请记住以下几点:

  • 声明 函数和变量用有意义的名字。遵守最小意外原则,即一个名为 is_alive 的函数不应该格式化硬盘驱动器,向你的老板发送愤怒的醉酒电子邮件等,它应该告诉你某些东西是否还活着,以及 就是这样 . rst 的函数是什么?做?这是个惊喜!
  • 首先按照标准方式进行。与过早的优化斗争。你调用这些函数一次,即使你调用它们一百万次,现代硬件上的 C 语言速度也快得离谱,你甚至很难用秒表来衡量这需要多长时间。这将是瞬间的。 不要优化你无法衡量的慢 .
  • 宏需要仔细定义,而不仅仅是草率。它们被插值,这意味着适用不同的规则。 while(i-->0)如果 i 则完全中断是 x+2无论出于何种原因。了解它们的工作原理,然后在您真正需要宏时正确编写它们。 注意语法复杂性 .

  • 编写简单而有效的代码,因为它没有惊喜,所以很无聊,并不总是那么容易,但它总是必要的。当您成熟为开发人员时,您将编写越来越无聊、越来越普通的代码,因为您将能够以一种避免所有不必要的大张旗鼓和虚张声势的解决方案的方式将复杂问题的简单解决方案可视化。

    这里所有的花哨的技巧都没有保存任何东西。当使用优化编译此代码时,编译器将决定内联哪些函数,并且由于涉及 IO,因此 #define 可能会节省任何时间。由于内核必须花费大量时间将数据从内核来回传输到用户空间,因此诡计完全丢失了。您的更改将明显小于统计噪音。

    如果你想让你的程序快速,你需要知道什么样的事情会使它变慢。例如, getch()实际上真的很慢,因为每次调用都需要通过内核进行相当痛苦的游览。再多的优化或宏观魔术都无法解决这个问题。相反,一次将其全部读入缓冲区并使用简单的指针比较对其进行解析:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    int main() {
    // Maximum size of file is:
    // + N to NNNNN (1-5 byte + newline = 6 bytes)
    // + 10,000 entries (letter + newline = 2 bytes each)
    // + Don't care about NUL terminator
    size_t max_size = 10000 * 2 + 6;
    char* raw = malloc(max_size);

    fread(raw, 1, max_size, stdin);

    char* p = raw;

    size_t count = atoi(p);
    while (*(p++) != '\n');

    int score = 0;

    for (int i = 0; i < count; ++i) {
    score += p[i * 2] == p[count * 2 + i * 2];
    }

    printf("%d\n", score);

    free(raw);

    return 0;
    }

    在 Windows 上,您需要调整它以处理 CRLF 而不仅仅是 LF,但同样的想法有效。
    getch()在读取大量数据时是残酷的。如果您不相信我,请编写一个测试程序,在其中使用该方法复制一个大(~1GB)文件,然后与更合理的以~64KB block 读取数据的策略进行比较。

    在一个程序中,您只读取少量数据,而如今 10K 条目无关紧要,这里的性能差异是学术上的,但是将其转储到缓冲区并在那里操作它的方法可以节省大量的麻烦解码不需要解码的东西,将这个问题简化为要点:将字符串的不同部分与其他部分进行比较并计算匹配项。

    关于c - 我的 friend 说我的代码很难阅读,我不明白为什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59366283/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com