Dalsi zahada v C -> Prevod long int na string

Milan B. milan na bastl.sk
Pondělí Červenec 25 23:06:38 CEST 2011


On 25.7.2011 19:46, Petr Tošovský wrote:
> Mam dotaz k radku
> s[i++] = "0123456789ABCDEF"[n % radix];
> Jestli to dobre chapu, tak na jednom radku definujete pole primym zapisem a indexem z polehned vyberete vhodny prvek podle zbytku deleni. To je korektni zapis? C znam jen na urovni beznych zakladu. Mate zkusenost jak se to pak implemenuje? Neni lepsi mit retezec v datove pameti jako promennou primo? Ma to nejake vyhody/nevyhody?
> Diky za peknou ukazku.
>

Neviem, ktora cast normy o tom pojednava, resp. tento zapis pripusta (a 
nemienim to sialenstvo teraz studovat). Niekde som ho videl a zapacil sa 
mi. Kompilator (ani pri obmedzeni na ANSI alebo C90) a ani splint 
neprotestuju..., takze asi bude OK.

Ale o co ide: - retazcova konstanta je interpretovana ako pole znakov, 
co v C znamena ze je to smernik na pole znakov umiestnenych v pamati 
konstant. Podobne ako pri zapise:

char *s="12345";

sa ten retazec musi niekam ulozit a dalej pracujeme len s jeho adresou.

Zapis som pouzil z dovodu kompaktnosti prikladov, ktore som uvadzal.

Implementuje sa to jednoducho - vytvori sa konstantna retazcova premenna 
a pracuje sa s nou. GCC aj s vypnutou optimalizaciou tuto premennu 
vytvori iba raz, aj ked sa retazec vyskytne na viac miestach.

-m-


.

> Tosa
>
> "Milan B."<milan na bastl.sk>  napsal(a):
>
>> On 24.7.2011 11:37, Michal Gregor wrote:
>>> Tak jsem program upravil na funkce itoa() a utoa().
>>> Kompilator ale hlasi chybu. Tyto funkce nezna.
>>> Koukam do navodu - jsou tam.
>>> Divam se do knihoven, nic takoveho tam neni. Ht-Soft je sice napsal
>> do
>>> navodu, ale do knihoven je zapomnel dat.
>>>
>> Netreba z toho robit tragediu. Su to jednoduchucke funkcie a a daju sa
>> spichnut za par minut. Napriklad (vsetko bolo kompilovane a testovane v
>>
>> gcc, kontrola (radix>0&&  radix<= 16) je umyselne vynechana):
>>
>> char *utoa(char *s, unsigned n, int radix)
>> {
>>      int i,j;
>>      unsigned char c;
>>
>>      i=0;
>>      do {
>>          s[i++] = "0123456789ABCDEF"[n % radix];
>>      } while ((n /= radix)>  0);
>>
>>      s[i]='\0';
>>
>>      for (j = 0, i--; j<i; i--, j++) {
>>          c = s[i];
>>          s[i] = s[j];
>>          s[j] = c;
>>      }
>>     return s;
>> }
>>
>> char *itoa(char *s,int n, int radix)
>> {
>>      if (n<0) {
>>          s[0]='-';
>>          utoa(s+1,(unsigned)(-n),radix);
>>      } else {
>>          utoa(s,(unsigned)n,radix);
>>     }
>>     return s;
>> }
>>
>> Ak staci len do desiatkovej sustavy, tak sa to moze (bezvyznamne)
>> zjednodusit:
>>
>> char *utoa(char *s, unsigned n)
>> {
>>       int i,j;
>>       unsigned char c;
>>
>>       i=0;
>>       do {
>>           s[i++] = n % 10 + '0';
>>       } while ((n /= 10)>  0);
>>
>>       s[i]='\0';
>>
>>       for (j = 0, i--; j<i; i--, j++) {
>>           c = s[i];
>>           s[i] = s[j];
>>           s[j] = c;
>>       }
>>     return s;
>> }
>>
>> char *itoa(char *s,int n)
>> {
>>      if (n<0) {
>>          s[0]='-';
>>          utoa(s+1,(unsigned)(-n));
>>      } else {
>>          utoa(s,(unsigned)n);
>>     }
>>     return s;
>> }
>>
>> Poznamka pre uplnost: takato itoa nefunguje s najzapornejsim cislom pre
>>
>> rozsah int, pretoze napr. pri 16-bitovom int  pre najzapornejsie cislo
>> -32768  neexistuje kladne 32768 (max. je 32767).
>>
>> Napriklad pre 16-bitovy integer by bolo vhodne osetrenie trebars takto
>> (vo funkcii itoa):
>>
>> if (n==-32768) {
>>    strcpy(s,"-32768");
>> } else {
>> ...
>> }
>>
>> utoa je v poriadku pre cely rozsah.
>>
>> -m-



Další informace o konferenci Hw-list