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