my_itoa,还有什么意见? [英] my_itoa, any comments?

查看:56
本文介绍了my_itoa,还有什么意见?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我从K& R拿起了itoa示例代码,我正在尝试根据这些条件对它进行修改



1)输入整数总是+ ve

2)不能假设整数参数的长度


以下是修改后的代码,请评论。


谢谢,

ceo


#include< stdio.h>

#include< stdlib.h>

#include< string.h>


/ * my_itoa:将n转换为字符串* /

char * my_itoa(unsigned int n){

int i = 0,c = 0,j = 0;

char * s = NULL;

do {

s =(char *)realloc(s,(i + 1)* sizeof(char));

s [ i ++] = n%10 +''0'';

} while((n / = 10)> 0);

s =(char *)realloc( s,i * sizeof(char));

s [i] =''\ 0'';

for(i = 0,j = strlen(s) - 1;我< j; i ++,j--){

c = s [i];

s [i] = s [j];

s [j] = c;

}

返回s;

}


int main(int agrv,char * argv){


char * p = NULL;

p = my_itoa(23456);

printf("(%s)\ n",p);

如果(!p)免费(p);

返回0;

}

Hi,

I picked up the itoa example code from K&R and am trying to modify it
to as per these conditions:
1) input integer is always +ve
2) cannot assume the length of the integer parameter

Following is the modified code, please comment.

Thanks,
ceo

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

/* my_itoa: convert n to string */
char* my_itoa(unsigned int n) {
int i=0,c=0,j=0;
char *s = NULL;
do {
s = (char *) realloc(s, (i+1)*sizeof( char));
s[i++] = n % 10 + ''0'';
} while ((n /= 10) > 0);
s = (char *) realloc(s, i*sizeof( char));
s[i] = ''\0'';
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
return s;
}

int main(int agrv, char *argv) {

char *p = NULL;
p = my_itoa(23456);
printf("(%s)\n", p);
if(!p) free(p);
return 0;
}

推荐答案

> int main(int agrv,char * argv){

应该是:

int main(int agrv,char * argv []){

> int main(int agrv, char *argv) {
that should be:
int main(int agrv, char *argv[]) {


问候,

ceo写道:
Greetings,

ceo wrote:


我选择了来自K& R的itoa示例代码我正在尝试修改它按照以下条件:
1)输入整数总是+ ve
2)不能假设整数的长度参数

以下是修改后的代码,请评论。

谢谢,
ceo

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

/ * my_itoa:将n转换为字符串* /
char * my_itoa(unsigned int n){
int i = 0,c = 0,j = 0;


i& j是一个数组的索引,所以应该是size_t


因为s是一个char数组,c应该是char

char * s = NULL;


realloc''()会让内存变得更加激烈,而且需要耗费时间。这里的一个malloc会很好。类似的东西:


s = malloc(CHAR_BIT * sizeof(n)/ 2.3 + 1);


你也应该在这里检查NULL。


do {
s =(char *)realloc(s,(i + 1)* sizeof(char));


一些问题:

*不要从realloc投出回报,它可以隐藏错误

*如果realloc失败了,你已经泄露了记忆,因为你已经失去了原来的价值。

* sizeof(char)总是1.

s [i ++] = n%10 +''0'';


这是否假设为ASCII?我不知道数字是否保证是连续的。

} while((n / = 10)> 0);


n是无符号的,所以''> 0''位是多余的

s =(char *)realloc(s,i * sizeof(char));


关于realloc的相同评论。此外,它应该是(i + 1),而不是我b $ [b] [i] =''\ 0'';
for(i = 0,j = strlen(s) - 1; i< j; i ++,j--){


你已经知道了s的长度 - 它是(i)所以你可以反转

i / j定义或更改for语句


for(j = i,i = 0; ...

c = s [i];
s [i] = s [j];
s [j] = c;
}
返回s;
}

int main(int agrv,char * argv){

char * p = NULL;


因为你在下一个语句中设置了p ,这一点是不必要的

p = my_itoa(23456);
printf("(%s)\ n",p);


p可以为null。是printf()保证处理它吗?

if(!p)free(p);


这应该是`` if(p)free(p)''''或者更紧凑'free(p)''

因为free(NULL)定义得很好。

返回0 ;


re转换值必须是EXIT_SUCCESS或EXIT_FAILURE

}
Hi,

I picked up the itoa example code from K&R and am trying to modify it
to as per these conditions:
1) input integer is always +ve
2) cannot assume the length of the integer parameter

Following is the modified code, please comment.

Thanks,
ceo

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

/* my_itoa: convert n to string */
char* my_itoa(unsigned int n) {
int i=0,c=0,j=0;
i & j are indices into an array so should be size_t

since s is an array of char, c should be char
char *s = NULL;
The realloc''s() are going to fragement memory something fierce, as well
as be time consuming. A single malloc here would be good. Something like:

s = malloc(CHAR_BIT * sizeof(n) / 2.3 + 1);

You should also check for NULL here.

do {
s = (char *) realloc(s, (i+1)*sizeof( char));
A few problems:
* don''t cast the return from realloc, it can hide errors
* if realloc fails, you''ve leaked memory because you''ve lost the
original value of s
* sizeof(char) is 1. always.
s[i++] = n % 10 + ''0'';
Does this assume ASCII? I don''t know if the digits are guarenteed to be
contiguous.
} while ((n /= 10) > 0);
n is unsigned, so the ''> 0'' bit is superfluous
s = (char *) realloc(s, i*sizeof( char));
Same comments about realloc. Also, it should be (i+1), not i
s[i] = ''\0'';
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
You already know the length of s -- it''s (i) so you can either reverse
the i/j definitions or change the for statement do

for (j = i, i = 0; ...
c = s[i];
s[i] = s[j];
s[j] = c;
}
return s;
}

int main(int agrv, char *argv) {

char *p = NULL;
since you set p in the next statement, this bit is unnecessary
p = my_itoa(23456);
printf("(%s)\n", p);
p could be null. is printf() guarenteed to handle that?
if(!p) free(p);
this should either be ``if (p) free (p)'''' or, more compactly `free(p)''
since free(NULL) is well defined.
return 0;
the returned value must either be EXIT_SUCCESS or EXIT_FAILURE
}



-

Kyle A. York

Sr. Subordinate Grunt


--
Kyle A. York
Sr. Subordinate Grunt




ceo写道:


ceo wrote:


我从K& R中获取了itoa示例代码,并尝试根据这些条件对其进行修改:
1)输入整数总是+ ve
2)不能假设整数参数的长度

以下是修改后的代码,请评论。

谢谢,
ceo

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

/ * my_itoa:将n转换为字符串* /
char * my_itoa(unsigned int n){
int i = 0,c = 0,j = 0;


为什么要初始化`c''和`j'?你永远不会想要使用初始值;你实际用它们做的第一个

事情是将它们设置为不同的

值。

char * s = NULL;
do {
s =(char *)realloc(s,(i + 1)* sizeof(char));


你不需要`(char *)''演员。另外,用'sizeof(char)''乘以
是不必要的,因为`sizeof(char)''按照定义是

- 但是,这不是令人反感

作为演员。


最令人反感的是,realloc()

可能会失败,如果它确实你没有发现失败:你会按下's'等于NULL,然后你的程序会大胆地将你的程序按下来b
太多的节目已经消失了,那就是b $ b,进入外太空。超级干净的方式是


做{

char * new_s = realloc(s,...);

if(new_s == NULL){

free(s);

返回NULL;

}

s = new_s;

...


在某些程序中,你可以快速而肮脏地逃脱


做{

s = realloc(s,...);

if(s == NULL)

die_horribly();


然而,*错误*的方式是


做{

s = realloc(s,...) ;

if(s == NULL)

返回s;


你能明白为什么吗? (提示:在realloc()失败之前指向内存的''

发生了什么?)

s [i ++] = n%10 +''0 '(;
} while((n / = 10)> 0);
s =(char *)realloc(s,i * sizeof(char));


这个realloc()调用的重点是什么?除非我已经错过了某些东西,否则它要求将's''调整为它已经具有的尺寸。

s [i ] =''\''';
for(i = 0,j = strlen(s) - 1; i< j; i ++,j--){
c = s [i ];
s [i] = s [j];
s [j] = c;
}
返回s;
}

int main(int agrv,char * argv){


您在后续行动中对此进行了更正。

char * p = NULL;


为什么当你要用
用另一个值覆盖它时,将'p''设置为NULL?

p = my_itoa(23456);
printf("(%s)\ n",p);
if(!p)free(p);


奇怪的是你对于函数内部的b / b $ realloc()失败的可能性如此傲慢,但又要小心

在这里测试它。 Odder仍然认为测试是在printf()而不是之前进行的,它可能会有所帮助。

最奇怪的是:所写的测试是不必要的,因为

免费(NULL)完全合法(并且什么都不做)!

返回0;
}
Hi,

I picked up the itoa example code from K&R and am trying to modify it
to as per these conditions:
1) input integer is always +ve
2) cannot assume the length of the integer parameter

Following is the modified code, please comment.

Thanks,
ceo

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

/* my_itoa: convert n to string */
char* my_itoa(unsigned int n) {
int i=0,c=0,j=0;
Why bother to initialize `c'' and `j''? You''re never
going to make any use of the initial values; the first
thing you actually do with them is set them to different
values altogether.
char *s = NULL;
do {
s = (char *) realloc(s, (i+1)*sizeof( char));
You do not need the `(char*)'' cast. Also, multiplying
by `sizeof(char)'' is unnecessary because `sizeof(char)'' is
one by definition -- however, this isn''t as objectionable
as the cast.

The most objectionable thing, though, is that realloc()
can fail and if it does you won''t detect the failure: you''ll
press on with `s'' equal to NULL, and your program will boldly
go where altogether too many programs have gone before, that
is, into outer space. The super-clean way to do this is

do {
char *new_s = realloc(s, ...);
if (new_s == NULL) {
free (s);
return NULL;
}
s = new_s;
...

In some programs you can get away with the quick and dirty

do {
s = realloc(s, ...);
if (s == NULL)
die_horribly();

However, the *wrong* way to is

do {
s = realloc(s, ...);
if (s == NULL)
return s;

Can you see why? (Hint: What has happened to the memory `s''
pointed to before the realloc() failed?)
s[i++] = n % 10 + ''0'';
} while ((n /= 10) > 0);
s = (char *) realloc(s, i*sizeof( char));
What''s the point of this realloc() call? Unless I''ve
missed something, it requests that `s'' be resized to the
size it already has.
s[i] = ''\0'';
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
return s;
}

int main(int agrv, char *argv) {
You corrected this in a follow-up.

char *p = NULL;
Why bother setting `p'' to NULL when you''re about to
overwrite it with another value?
p = my_itoa(23456);
printf("(%s)\n", p);
if(!p) free(p);
Odd that you''re so cavalier about the possibility of
realloc() failure inside the function, and yet are careful
to test for it here. Odder still that the test comes after
the printf() rather than before, where it might do some good.
Oddest of all: the test as written is unnecessary, because
free(NULL) is entirely legal (and does nothing)!
return 0;
}




如果你知道最大可能数字需要多少位数,那么你可以通过使用适当大小的数组来摆脱所有那些realloc()调用

char的代替。怎么

你能知道这个数量吗?有一个方便的标题叫

< limits.h>除其他外,它定义了一个名为

CHAR_BIT的宏,它给出了一个字节中的位数。二进制

表示最大可能的'unsigned int''值

不能超过`CHAR_BIT * sizeof(unsigned int)''二进制

位数,对吗?并且八进制表示不需要比thbit计数除以3(向上舍入)更多

,对吧?并且

十进制表示不能超过八进制;还有

和我在一起?所以:如果你计算'n'中的位数,将

除以3并向上舍入,然后为''\ 0'添加一个点'

你会有足够的字符表示最长的小数

数。这里是:


char buff [(CHAR_BIT * sizeof(n)+ 2)/ 3 + 1];


现在你可以得到摆脱所有重新realloc()''只需

存入buff []中的数字生成它们,自信

知道那里有足够的空间。然后只需要调用malloc()来获取实际需要的内存量,将生成的数字复制到其中,然后将其返回。


只需更加聪明一点,你甚至可以摆脱数字反转循环的
。 为读者锻炼,他们说是




注1:十进制是不长于八进制的计算

可能是做得更精确。另一种看待它的方法是

你使用3作为lg(10)= 3.3219+的近似值,并且

你可以使用更精确的公式喜欢


char buff [(CHAR_BIT * sizeof(n)* 10 + 32)/ 33 + 1];


近似log( 10)〜= 33/10 = 3.3。只要

近似值小于真值(因此数字

计数超过而不是低估),一切都会好的。

就个人而言,我认为不值得这么麻烦。


注2:理论上可能有n可能

的值位数小于`CHAR_BIT * sizeof n'; C标准

允许填充位。在变量中占据空间但是没有贡献价值。再一次,这可能会导致
轻微高估并使buff []几个字符更长

而不是绝对需要 - 但同样,我不会认为这是值得担心的事情。


注3:有人提倡初始化变量 -

特别是指针 - 当你声明它们时,按顺序(所以它们是b / b
)确保永远不会冒使用

未初始化变量的风险。对我来说,这种做法似乎是错误的。

如果程序有一个执行路径导致它使用

变量而没有先在其中存储一个值,那么

该值是已知的鉴于它是b $ b错误,这是一种小小的安慰。此外,一些编译器可以分析执行路径

并警告在确定他们已经写入b $ b之前使用的变量;如果你沉迷于批发初始化你

压制那些有用的警告。不是一个好的交易,恕我直言:给编译器每个机会都有帮助。


-
Er ********* @ sun.com



If you knew how many digits the largest possible number
would require, you could get rid of all those realloc() calls
by using an appropriately-sized array of `char'' instead. How
can you know this quantity? There''s a handy header called
<limits.h> that defines, among other things, a macro named
CHAR_BIT that gives the number of bits in a byte. The binary
representation of the largest possible `unsigned int'' value
cannot need more than `CHAR_BIT * sizeof(unsigned int)'' binary
digits, right? And the octal representation can''t require more
than thbit count divided by three (rounded up), right? And the
decimal representation cannot be longer than the octal; still
with me? So: if you calculate the number of bits in `n'', divide
by three and round up, and then add one more spot for the ''\0''
you''ll have enough characters for the longest possible decimal
number. Here goes:

char buff[(CHAR_BIT * sizeof(n) + 2) / 3 + 1];

Now you can get rid of all that re-re-realloc()''ing: just
deposit the digits in buff[] as you generate them, confident
in the knowledge that there''s enough space. Then make just
one call to malloc() to obtain the amount of memory actually
needed, copy the generated digits into it, and return it.

With just a tiny bit more cleverness you can even get rid
of the digit-reversing loop. "Exercise for the reader," as
they say.

Note 1: The decimal-is-no-longer-than-octal calculation
could be made more precise. Another way to look at it is that
you''re using 3 as an approximation to lg(10) = 3.3219+, and
you could use a more exact formula like

char buff[(CHAR_BIT * sizeof(n) * 10 + 32) / 33 + 1];

which approximates log(10) ~= 33/10 = 3.3. As long as the
approximation is smaller than the true value (so the digit
count is over- rather than under-estimated), all will be well.
Personally, I don''t think it''s worth the trouble.

Note 2: There''s a theoretical possibility that `n'' might
have fewer than `CHAR_BIT * sizeof n'' value bits; the C Standard
allows for "padding bits" that occupy space in the variable but
don''t contribute to the value. Again, this could lead to a
slight overestimate and make buff[] a couple characters longer
than it absolutely needs to be -- but again, I don''t think it''s
anything to worry about.

Note 3: Some people advocate initializing variables --
especially pointers -- when you declare them, in order (so they
say) to make sure of never running the risk of using an
uninitialized variable. To me, the practice seems wrong-headed.
If the program has an execution path that causes it to use a
variable without first storing a value in it, the fact that
the value is "known" is little consolation given that it is
"wrong." Also, some compilers can analyze the execution paths
and warn about variables that are used before it''s sure they''ve
been written to; if you indulge in wholesale initialization you
suppress those helpful warnings. Not a good trade, IMHO: give
the compiler every opportunity to be helpful.

--
Er*********@sun.com


这篇关于my_itoa,还有什么意见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆