首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单串逆变程序

简单串逆变程序
EN

Code Review用户
提问于 2016-01-22 17:16:30
回答 8查看 1.6K关注 0票数 14

我目前正在学习c编程,但我处于一个非常基本的水平。因此,作为练习,我做了一个程序,读取一个字符串,并反转它。我想知道这些代码是否可读,以及如何改进它。

代码语言:javascript
复制
/* 
* Goal: Given a string, invert it, then print the result.
* Author: Lúcio Cardoso
*/

#include <stdio.h>
#include <string.h>

/*This is the size of the arrays in this program. It's better to use a          
constant, because makes easier to modify the arrays' size, if needed.*/
#define NUM 200


void invert(char *s) //Fucntion responsible for inverting the string.
{
    char aux[NUM];
    int i, j, n; //These variables are all used to control the for loops.

    /*This loop will read the size of the array's string, that's why
    strlen(s) - 1 is used. We don't need to read all contents
    from the array, just the string. As we read the s[] backwards,
    its content is stored in aux[n]. In this case, from zero to the
    size of s[]'s string - 1. Minus 1 is used because we read it from ZERO,
    not i. */
    for (i = strlen(s) - 1, n = 0; n < strlen(s), i >= 0; i--, n++) {
        aux[n] = s[i];
    }

    printf("Included with the super mojo from the string inverter, ");
    printf("this is the result: ");

    //This for loop reads all the content from the aux array, and print it.
    for (j = 0; j < strlen(s); j++) {
        printf("%c", aux[j]);
    }
}

int main(void)
{
    char string[NUM];

    printf("\nWelcome to the super, duper string inverter!\n");
    printf("If you want to see some magic, enter a string:\n>");
    gets(string); //Reads the string.

    //Now, we only need to call the function with string[] as a parameter.
    invert(string);

    return 0;
}
EN

回答 8

Code Review用户

回答已采纳

发布于 2016-01-22 18:15:48

对于初学者来说,这是一个很好的小软件。以下是我的评论:

const**-修饰符**

由于不修改char *s的内容,所以可以安全地将函数签名更改为void invert(const char *s)

太多的strlen()调用

您可以执行strlen(s)每个for-loop迭代。这对性能非常不利(特别是对于大型字符串),因为每次调用都会通过strlen循环整个字符串。如果您的字符串长度为100个字符(在NULL-character旁边),则结束于100*100 = 10000次迭代。

作为一种快速解决方案,您只需创建一个变量length并存储字符串的长度一次。从那时起,您将与length而不是strlen(x)进行比较,并将得到相同的结果(因为,s在执行时不会更改)。

比较未使用的n < strlen(s)在您的第一个for-loop中仍未使用。我认为您希望将这两种比较与&&联系起来:

代码语言:javascript
复制
for (i = strlen(s) - 1, n = 0; n < strlen(s) && i >= 0; i--, n++)

为什么还要倒过来?

因为您的函数打印反向字符串,但不返回任何内容。你真的不需要逆转它。您可以从末尾开始循环输入字符串(就像在第一个循环中所做的那样),打印所有字符。如果返回指向该数组的指针以供以后使用,则额外的数组才有意义。

票数 10
EN

Code Review用户

发布于 2016-01-22 20:54:31

可用性

你的功能不太灵活。如果另一段代码需要使用它,它将不得不将它用于一个单一的用途,并且这个目的是给出一个字符串,并以相反的顺序打印出该字符串。

以下是一些可以使其更加灵活的方法:

用户提供的输出缓冲区

现在,反向字符串直接打印到STDOUT。为了使其更灵活,并使其遵循单一责任原则,您可以让函数接受一个输出缓冲区,将反向字符串插入:

代码语言:javascript
复制
void reverse(char *s, char *out) {

这样,您还应该删除函数中的printf调用。

注意:一个更好的替代方案是覆盖原始字符串。与接受输出缓冲区不同,您可以在函数中创建一个临时输出缓冲区(就像使用aux一样)。然后,简单地将临时输出缓冲区复制到函数末尾的输入字符串中。正如200_success所说,

我确实建议把S作为一个输入输出参数,并将字符串反转到位.如果调用者想要保留原件的副本,那么他们可以自己先复制。将缓冲区分配的责任放在调用者身上可以减少C中内存管理方面的麻烦。

基本上,通过让输出转到输入字符串,内存管理就变得不那么复杂了,而且对调用者来说也更容易。

用户提供的长度

如果使用此函数的代码不希望反转整个字符串,怎么办?如果他们只想让字符串的第一部分反转呢?为了允许这样做,函数应该接受要反转的字符数量:

代码语言:javascript
复制
void reverse(char *s, char *out, size_t len) {

然后,您只需在循环中使用len,就像您已经使用的那样。

您的代码

够了;是时候回顾一下您已经提交的代码了。

打印出字符串

对于(j = 0;j< strlen(s);j++) { printf("%c",auxJ);}

在这里,您正在循环遍历aux“数组”并打印出每个字符。然而,你把它复杂化了;为什么不直接打印aux呢?

代码语言:javascript
复制
printf("%s", aux);
票数 10
EN

Code Review用户

发布于 2016-01-23 00:18:57

  • 您正在使用printf打印单个char:printf("%c",auxJ);printf是一个非常方便的格式化输出的工具,但是它会带来相当大的开销--这不是您想要一次又一次调用的东西,没有一个很好的理由。将单个char打印到stdout的一个更有效的方法是: putchar(auxJ);或者,不需要遍历字符串逐个字符地打印它,只需使用一个函数调用就可以打印整个事件:put(Aux);(注意,puts会在字符串末尾再打印一个换行符。如果您想避免这种情况,请使用fputs(aux, stdout)。) putsfputs要求字符串(aux)以NUL-字符('\0')结尾,而它不在您的程序中。如果要打印一个已知长度的字符序列(但可能没有这样的终止符字符),可以使用: fwrite(aux,1,strlen(n),stdout);
  • 您还可以使用putsfputs打印程序中的所有字符串文字,并且开销更小,例如puts(“\n欢迎来到超级字符串转换器!”);而不是printf(“\n欢迎来到超级字符串转换器!\n”);现在您甚至不需要担心%字符被解释为格式描述符。
  • 您可以将相互打印的字符串文字连在一起,以避免额外的缓冲、I/O锁定和解锁的开销:fput(“包含在来自字符串转换器的超级mojo中,这就是结果:",stdout);如果您不喜欢长字符串文本,可以将它们分解为多个部分:fput(”包含在字符串转换器的超级mojo中“、”这是结果:“、stdout);生成与前面的源代码完全相同的语法树和二进制代码。
票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/117608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档