正如你们中的一些人可能知道的那样,我一直在努力通过C程序设计语言(2)。
我最近完成了itoa练习的粗略实现(第3章)。值得注意的是,我们还没有被介绍到任何高级的主题,如指针,动态数组等。
这个练习是根据参数width创建一个数字的字符串表示形式,并使用空格的左填充。在我的例子中,数字是1030,宽度是10,这意味着表示为______1030 (用_替换)。
我还决定尽可能少地使用外部包,这样我就可以更多地了解C,而不是知道如何实现包。这可能有悖于一些最佳实践,因此我认为最好在讨论我的实现之前提及这一点。
我希望得到对解决方案的一般反馈、建设性的批评,特别是帮助找出任何具体的句法错误或潜在的瓶颈。在这个实现中,我决定做一个静态测试,而不是允许用户输入数据。
我特别感兴趣的是如何使循环更有效,因为我真的不喜欢这样,我需要使用第二个语句来划分number。
如果希望格式化,可以在要旨上找到我的解决方案,或者在下面:
/*
itoa.c (i, s, w)
@param i: integer
@param s: char []
@param w: width
@returns a string representation of i with any excess (left) padding
in blankspaces dependant on the width w.
*/
#include <stdio.h>
#include <math.h>
#define MAXLINE 100
unsigned numDigits(const unsigned n) {
if (n < 10) return 1;
return 1 + numDigits(n / 10);
}
void itoa(int number, char string_out [], int width) {
int i = width;
do {
string_out[i] = (number > 0) ? number % 10 + '0' : ' ';
number /= 10;
} while ((i--) != 0);
string_out[width + 1] = '\0';
}
int main () {
char str [MAXLINE];
if (numDigits(1030) > 10) {
printf("Sorry, the number you provided was longer than 10 characters\n");
return 1;
}
itoa(1030, str, 10);
printf("Before: %d\nAfter: %s\n", 1030, str);
return 0;
}发布于 2017-05-27 13:34:02
itoa函数可以很好地解决这个问题,我想不出一种将除法移除10的方法。
更好的错误检查
代码函数中的itoa不能产生负数,所以最好在调用函数中检查负数。
绩效考虑
考虑一下C编程语言的用途,主要使用的是编写操作系统或嵌入式代码的高级汇编语言,因此性能非常重要。
这段代码中真正的性能问题是numDigits()。C确实允许递归,在递归提供最佳解决方案的时候,这个问题不是其中之一。有一个非常简单的测试可以在一行代码中执行。如果数字大于9999999999,则大于10位数。
字符串大小
字符数组的大小不是2的幂。在使用C时,最好根据字号大小使字符数组的幂为2、4或8。如果在结构或更复杂的代码中使用字符数组,则任何其他大小的字符数组可能会导致内存对齐问题。
发布于 2017-05-27 13:32:58
我认为它做得很好,但是我认为如果它是2行的话,这看起来会更好,我的意思是返回到if if (n < 10) return 1;下面。关于number /= 10,我认为你可以在写完数字后结束循环。然后用空格填充数组的其余部分。我的意思是使用另一个循环来编写空白,它将节省您执行不必要的number /= 10和检查数字值的时间。如果不想使用其他函数或使用memset,可以在循环中这样做。
https://codereview.stackexchange.com/questions/164322
复制相似问题