» »

C++ vs. C

C++ vs. C

1
2
»

rokpok ::

Da ne bom odpiral nove teme. Napisal sem en simple program, pa me zanima če sem na dobri poti. Naloga programa je, da prebere (iz tipkovnice) besedilo in vse tabulatorje zamenja z ustreznim številom presledkov (primer: 1 tab je 5 presledkov).

ps.: Do zdaj sem se naučil samo osnove (kakšne string funkcije odpadejo).

Koda
Rad bi bil pingvin.

Zgodovina sprememb…

  • spremenil: rokpok ()

hatch ::

Emm.. ne.

Slabo je da beres vsak znak posebaj. Ker tako nimas nobenga bufferinga.. Uporabi raje "gets" funkcijo, ki ti iz stdin-a pobere celo vrstico.

Drug problem.. char Line[1000];... kaj pa ce je output string daljsi od toliko.. nikjer niti ne preveris ce nisi sel cez... malo daljsi sestavek in imas buffer overflow.

Coding Style je pa tudi slab. Preberi si coding style thread.

CCfly ::

Kaj pa scanf ? Tudi ta bi moral pobirati iz bufferja, pa še več kot 999 znakov ne bi prebral.

hatch ::

Tudi scanf je uredu.

rokpok ::

hmmm. Ta primer je iz knjige in do zdaj v knjigi ni bilo omenjenega nič drugega kot getchar() (scanf in podobne funkcije pridejo kasneje), tako da mora program biti napisan z to funkcijo. Dolžino vnosa pa sem res pozabil preveriti...

Torej program mora biti napisan z getchar() funkcijo. Biti ali ne biti?

Lp
Rad bi bil pingvin.

CCfly ::

No zdaj si raje poglej scanf, sscanf in fscanf, potem pa beri naprej.

rokpok ::

CCfly hvala za predlog vendar sem se odločil da bom šel lepo povrsti po knjigi, ker bo tako še najboljše. Vseeno hvala za nasvet.

ps.: zanimalo me je samo, kako je napisana koda glede na to, da lahko uporabim samo getchar()

Lp
Rad bi bil pingvin.

jype ::

sleepy_net: to je cist narobe.

Ne jit po vrsti po knjigi. Dobi si problem in potem poskusaj najti najboljso resitev. Recimo ta tvoj program je fajn zacetniski problem, getchar() je pa najbolj neprimeren nacin za to rec pocet.

Tudi gets je slab:
SECURITY CONSIDERATIONS
The gets() function cannot be used securely. Because of its lack of
bounds checking, and the inability for the calling program to reliably
determine the length of the next incoming line, the use of this function
enables malicious users to arbitrarily change a running program's func-
tionality through a buffer overflow attack. It is strongly suggested
that the fgets() function be used in all cases. (See the FSA.)

64202 ::

Malo mimo, ampak vseeno: ni res, da get/putchar nima bufferinga. Vsaj linux (glibc?) to optimizira, in 100MB putchar vzame samo 5x vec casa kot ce pises po 1K blok. Ce vzames za razliko write(stdout, "a", 1), porabi neprimerno vec casa kot putchar. Primerjava:

100MB - komanda dd, bs=1024, 6 sekund
100MB - putchar, 35 sekund
10MB - write(), 3 minute

Aja, pa ne vem zakaj ste tako navduseni nad scanf. Vsaj v tem primeru je tezko kaj krajsega napisat kot tole:


#include <stdio.h>

int main() {
int c;
while((c = getchar()) != EOF) {
if(c == '\t')
printf(" ");
else
putchar(c);
}

return 0;
}

Zgodovina sprememb…

  • spremenilo: 64202 ()

rokpok ::

64202 -> Zgornji program ti po vsakem enter-u izpiše stvarco. Besedilo se mora izpisat na koncu in v enem kosu:D .
Rad bi bil pingvin.

hatch ::

jype.. my bad.. fgets it is.

Glede bufferinga pa mislim da je ena druga fora..za getchar je direkt interrupt.. zato dela hitreje. Bufferinga kot ga pa naredis ce preberes 1kb hkrati pa ni.

hash ::

Kot receno funkcije kot so gets(), strcat(), strcpy(), sprintf(), vsprintf()... ne delajo bound-checkinga kar lahko rezultira v buffer-overflowu, tako da previdno pri uporabi teh funkcij oziroma je bolje uporabljati kaksne alternative...

64202 ::

sleepy_net: Ce pa hoces tako, potem pa moras uporabljat malloc (realloc?), ni druge. Welcome to C hell :)

CCfly ::

You call it hell, I call it power divine.

rokpok ::

64202 -> ne me sedaj strašit, ko sem zbral pogum in začel :O :D

No imam pa en problem. Sedaj sem prišel do signed in unsigned zadev. Piše vse lepo in prav, pač da če je recimo integer unsigned potem je vedno pozitiven oziroma enak nič ..., ampak to je samo teorija. Mene pa zanima predvsem praksa. Torej kako se te zadeve uporabljajo v programih? Mogoče, če bi bil kdo tako dober in bi mi na kakšnem primeru pokazal.

Hvala in Lp
Rad bi bil pingvin.

Zgodovina sprememb…

  • spremenil: rokpok ()

Vesoljc ::

signed, unsigned?

vzememo recimo int, po default-u je ta signed, torej ima predznak in vanj lahko zapisemo tako -1000 kot 1000. ce recemo unsigned int, potem ta nima predznaka, njegovo obmocje pa je od 0 do 2^32.

uporaba? recimo polja nimajo nikoli negativnih indeksov, torej je za to primeren unsigned int. ce pa ves, da vrednost lahko postane negativna, potem uporabi signed int oziroma samo int.

se malo o prekoracitvi. char je velik en byte, torej 2^8 = 256 razlicnih stanj. ce vzamemo noramlen (signed) char se to obmocje razdeli med pozitivne ter negativne cifre. v osnovni cahr tako lahko zapisemo vrednsoti od -128 do 127. ce postane char unsigned, potem vanj lahko zapisemo od 0 do 255. kaj se pa zgodi ce poskusamo prirediti charu vecjo vrednost? biti se preprosto povedano zavrtijo. ce recemo:
char a = 300;
bo vrednost a-ja postala 300-256 = 44.
naredi par primerov, pa ti bo koj jasno kako se vrti ;)
Abnormal behavior of abnormal brain makes me normal...

64202 ::

Glede arrayev pa unsigned inta pa pazi. Mimogrede se zajebes:


int a[10];
unsigned int i;
for(i = 9; i >= 0; --i)
a[i] = 5;


Nagradno vprasanje: kaj je tukaj narobe? :)

BigWhale ::

Narobe? Nic. to je tak sofisticiran endless loop.. No ja, ce mas sreco potem samega sebe povozis... ;)

64202 ::

To je kar za coding style: nikoli ne uporabljaj unsigned int za indekse. Najbolje kar nikoli, ce se da. Bolje je javiti napako, da negativna stevila niso veljaven input za funkcijo, kot pa da potiho -5 spremenis v 2^32-5. Kar poglejte si ta primer:


#include <stdio.h>
unsigned int x(unsigned int a) { printf("%u\n", a); return a; }
int main() { int y = x(-1); printf("%d\n", y); return 0; }


Gcc ne javi nobenega warninga/napake, tudi pri -Wall. Izpis je pa:
4294967295
-1

Po mojem je to izredno grdo in nevarno.

Pa se recimo, za dolzine podatkov tudi ne uporabljaj intov, ker si omejen na 2gb/4gb. Uporabljaj long long, ki je 2^63 ali unsigned verzija 2^64. V resnici obstaja (mrezni) softver, ki krepne, ce mu das velikost podatkov 2gb. Danes 2gb fajli niso vec tako redki.

trs ::

64202: long long ni portabilen. Najbolje je da se definira nek svoj 64 biten tip ali pa da se uporablja C99 uint64_t tipe....

lp,
trs

64202 ::

long long je v C99. Podpirata ga vsaj gcc in vc++ 2003.

hatch ::

Quote: To je kar za coding style: nikoli ne uporabljaj unsigned int za indekse. Najbolje kar nikoli, ce se da. Bolje je javiti napako, da negativna stevila niso veljaven input za funkcijo, kot pa da potiho -5 spremenis v 2^32-5. Kar poglejte si ta primer:

Ubistvu je cist isti drek a so za indexe unsigned ali signed spremenljivke. Ker je efekt popolnoma isti.

INT16 iIndex1; UINT16 iIndex2;
iIndex1 = -5; in iIndex2 = -5;

Ce imas array dovolj velik (se pravi 2^16..) bos pri obeh dobil isti rezultat. Ce pa nimas dovolj velikega.. bos pa pri obeh dobil error. (ampak to se meni ne dogaja, ker imam dovolj velikega)

64202 ::

Kaj pa ce bi rad imel 100000 elementov, pa nocem alocirat 16gb rama? Hm, mogoce je pa to najbolje, linux zares alocira page-e, sele ko jih zacnes uporabljati. :D

rokpok ::

Nova težava. Bitwise operaratorji, recimo & (AND). Vem naslednje:

1) Tabela:
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1
x AND 0 = 0
x AND 1 = x

2) Primer uporabe pri 32 bitnih barvah, ki sem ga prebral nekje na netu:

a) AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB (A.... pomeni transparentnost)
b) Iz tega niza bi radi dobili vrednost rdeče barve
c) Če nekemu bitu dodamo (&) 1 dobimo originalno vrednost, če pa nekemu bitu dodamo (&) 0 pa dobimo 0
d) Naredimo mask:
0000 0000 1111 1111 0000 0000 0000 0000
e) Rezultat:
0000 0000 RRRR RRRR 0000 0000 0000 0000
f) Stvar shiftamo za 16 v desno:
0000 0000 0000 0000 0000 0000 RRRR RRRR = RRRR RRRR

Stvari, ki sem jih navedel zgoraj so mi jasne. Primer, ki pa mi ni jasen pa je naslednji:

n = n & 0177;

Kaj za >:D naredi?

Lp
Rad bi bil pingvin.

64202 ::

-

Zgodovina sprememb…

  • spremenilo: 64202 ()

64202 ::

0177 je v osmiskem. Zgleda da je sedem enk?

rokpok ::

Mater sem zabit :8) . Nisem vedel kam bi dal tisto ničlo spredaj. Hvala
Rad bi bil pingvin.
1
2
»


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

začetki programiranja

Oddelek: Programiranje
357147 (5222) Mavrik
»

Visual Basic, C#, C++, razlike... (strani: 1 2 3 )

Oddelek: Programiranje
12212560 (10231) 64202
»

Java

Oddelek: Programiranje
323487 (3045) Nerdor
»

mene me pa čista osnova zanima

Oddelek: Programiranje
191849 (1639) NoUse4AName
»

Kateri jezik je bolji?

Oddelek: Programiranje
462202 (1739) Monster

Več podobnih tem