Jump to content
M2G

RSTA 1/1 Intebari - Raspunsuri

Recommended Posts

Probabil cartea respectiva a fost scrisa inainte de implementarea in standard al tipului functiei main.

Ideea de baza e ca degeaba scrie in nu stiu ce carte ca functia main returneaza void, compilatoarele sunt facute dupa standard si standardul este cel care dicteaza care cod este valid.

Desigur, functioneaza si cu void dar nu este cod standard. Daca ai lucra intr-o companie, la code review/verification, codul iti va fi respins.

Scrie clar in standard (C99)

If the return type is not compatible with int, the

termination status returned to the host environment is unspecified.

Cum trateaza asta un sistem de operare, nu stiu. Dar SO-ul nu stie implicit cum s-a incheiat programul.

Standardul dicteaza codul valid, nu cartea X.

Conteaza cum scrii mai mult decat crezi. Daca nu scrii cod valid cu standardul codul tau este mai vulnerabil pentru ca intre timp se pot schimba compilatoarele sau modul in care un program este tratat de catre sistemul de operare iar codul tau nerespectand aceste reguli, o sa crape sau o sa produca undefined behaviour.

Link to comment
Share on other sites

If the return type is not compatible with int, the

termination status returned to the host environment is unspecified.

Sigur ca da, insa standardele C90/C99 sunt implementate in compilator deci nu prea ai de ce sa-ti faci probleme.Pana la a activa intr-o companie sa iti fie verificat codul.. e cale lunga.Eu folosesc IDE-ul de la microsoft si sincer n-am avut erori la vreun program sau sa se comporte ciudat folosind sintaxa respectiva, ceea ce adevereste faptul ca toate 3 standarde sunt perfect functionabile.Indemn sa folositi 'int main()' , aceasta a fost doar o discutie vizavi de sintaxa folosita la scrierea functiei 'main'.

Link to comment
Share on other sites

FOLOSITI "int main" !

Pe Linux e strict necesar acel cod returnat

Sa presupunem ca ai un program: "adu_o_bere" si ca daca e executat ca root, o sa iti aduca o bere, daca nu, o apa plata.

Iar tu, ca autor al programului:

1. returnezi 0 daca a fost rulat ca root si iti poate aduce o bere (0 == actiune indeplinita cu succes!)

2. returnezi 1 sau un alt cod daca nu a fost executat ca root, caz de eroare, nu poate aduce berea

Cand executi programul pe Linux, vrei sa stii si tu daca a adus cu succes berea sau nu. Aici conteaza acel cod returnat!

./adu_o_bere && echo "A adus berea" # Va afisa acel mesaj doar daca "./adu_o_bere" a RETURNAT 0 (SUCCES adica). In acest caz va returna un cod de eroare, 1 sau altceva (nu esti root)

sudo ./adu_o_bere && echo "A adus berea" # Doar in acest caz va afisa acel mesaj, deoarece pentru acest caz, executat ca root (presupunem ca nu esti implicit root), programul a returnat 0

Pe scurt, cand dai o comanda: "./exploit", "./sparge_nasa" sau orice altceva, uneori cel putin, ai nevoie sa stii daca programul a facut ceea ce trebuie sau a intervenit o eroare. Pentru asta, ai nevoie de acel cod de eroare.

Link to comment
Share on other sites

@ sebo, vezi ca atunci cand instalezi codeblocks din softul de administrare al linux, nu iti instaleaza si compilatorul/compilatoarele, totusi gcc ar trebui sa existe default.

Instaleaza si g++ dupa care uita-te la settings->Compiler->GNU GCC COmpiler Toolchain si vezi daca ai acolo la toate campurile path. Eventual poti sa ii dai un auto-detect si vezi daca iti seteaza toate campurile.

Link to comment
Share on other sites

@nedo;

Am rezolvat-o, aveam compilatorul bine pus, numai ca nu mergea debugging (Era o problema de kernel, toate distro'urile dupa 11.10 Ubuntu based au problema asta );

Mersi oricum :)

Pentru cei care mai au probleme la debug pe linux :

-Solutie temporara ( echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope ) ; Nu rezista la reboot

-Solutie permanenta (Se poate schimba la loc) (sudo gedit /etc/sysctl.d/10-ptrace.conf) , Se schimba 0 cu 1 pe last-line;

^ E default 0 pentru security reasons, daca il ai pe 1 se poate atasa o alta aplicatie la proces, etc

Link to comment
Share on other sites

Pe scurt, cand dai o comanda: "./exploit", "./sparge_nasa" sau orice altceva, uneori cel putin, ai nevoie sa stii daca programul a facut ceea ce trebuie sau a intervenit o eroare. Pentru asta, ai nevoie de acel cod de eroare.

Exemplul acesta nu este chiar bun, avem cod pentru a intercepta eroarea in caz ca exista una.Singura explicatie pentru a folosi 'int main()' in loc de 'void main()' din punctul meu de vedere (si probabil al altor persoane) este doar pentru a fi in pas cu standardul C11.Daca ai nevoie sa stii exact daca un cod a fost rulat (exemplul tau: adu_o_bere() sau ./exploit) exista buclele if/else/elseif care se pot folosi impreuna cu functia 'stderr' pentru care se pot defini anumite constante dupa erorile pe care crezi ca programul le poate returna.

@Matt, nu inteleg de unde acel raspuns(noi discutam despre altceva) si cred ca toata lumea de aici cunoaste acel lucru.

Edited by Erase
Link to comment
Share on other sites

Am si eu o problema.Cand dau sa compilez un program ,nu imi apare acea consola :

Va las prog.mai jos:

#include <stdio.h>;

#include <conio.h>;

float a,b,ma,mg,marm;

void main()

{

clrscr();

printf("\n dati a ");

scanf("\n %f",&a);

printf("\n dati b ");

scanf("\n %f",&B);

printf("\n media aritmetica= %f",(a+b)/2);

printf("\n media armonica= %2.1f",2*a*b/(a+B));

getch();

}

Link to comment
Share on other sites

Am si eu o problema.Cand dau sa compilez un program ,nu imi apare acea consola :

Va las prog.mai jos:

#include <stdio.h>;

#include <conio.h>;

float a,b,ma,mg,marm;

void main()

{

clrscr();

printf("\n dati a ");

scanf("\n %f",&a);

printf("\n dati b ");

scanf("\n %f",&B);

printf("\n media aritmetica= %f",(a+b)/2);

printf("\n media armonica= %2.1f",2*a*b/(a+B));

getch();

}

Vezi ca ai niste greseli.

Incearca totusi asta:

#include <stdio.h>

#include <conio.h>

float a,b;

void main()

{

system("cls");

printf("\n dati a ");

scanf("%f",&a);

printf("\n dati b ");

scanf("%f",&B);

printf("\n media aritmetica= %f",(a+b)/2);

printf("\n media armonica= %2.1f",2*a*b/(a+B));

getch();

}

PS: Cred ca intai de toate userii ar trebui invatati cum sa foloseasca modul pas cu pas pentru a vedea unde au gresit si unde sa caute cand nu vor sti sa foloseasca/ce face o functie.

Link to comment
Share on other sites

@curiosul daca tot ii dai o informatie incearca sa o faci eficient, in modul acesta poate intelege si el ce vrei sa spui.

@qwerty12, banuiesc ca folosesti compilatorul de la Borland(care are activa functia in fisierul antet conio.h) dar te sfatuiesc sa compilezi cu compilatoare mai moderne pentru ca acea functie nu este in standardul C/C++.Codul pe care l-ai scris este in regula mai putin acele variabile (ma,mg,marm) care nu sunt initializate si bineinteles motivul pentru care nu ti se compileaza este cauza functiei 'clrscr()' care este neidentificata, insa nu te opreste nimeni sa iti creezi tu functia respectiva.

void clrscr()

{

// system("clear"); pe Unix

system("cls"); //pe Windows

}

Edited by Erase
Link to comment
Share on other sites

#include <ceva.h> = este o directiva catre preprocesor care indica includerea fisierului respectiv in program si implicit functiile cu care vin acestea.(fisierele se afla in directorul 'include')

; = defineste sfarsitul unei instructiuni.

de ce printf returneaza numarul de caractere ?

Cred ca cea mai eligibila explicatie ar fi ca functia 'printf' returneaza la iesire numarul caracterelor afisate cand este initializata de o variabila.(printf fiind o functie de tip int);

Acelasi lucru se aplica si in cazul in care vei initializa o variabila de tip char(nu neaparat int) cu valoarea atribuita functiei printf.

void main()

{

char whatever = printf("test\n");

printf("%d", whatever);

getchar();

}

Edited by Erase
Link to comment
Share on other sites

Ca sa subliniez si eu spusele lui Erase:

Return Value

On success, the total number of characters written is returned.

If a writing error occurs, the error indicator (ferror) is set and a negative number is returned.

If a multibyte character encoding error occurs while writing wide characters, errno is set to EILSEQ and a negative number is returned.

Link: printf - C++ Reference

Link to comment
Share on other sites

Mersi Erase & silvadark pentru raspunsuri. Dar mai am intrebari :)

If a writing error occurs, the error indicator (ferror) is set and a negative number is returned.

Incerc sa inteleg ce e writing error .... writing on what ?

If a multibyte character encoding error occurs while writing wide characters, errno is set to EILSEQ and a negative number is returned.

Daca setul de caractere ASCII poate fi reprezentat pe 1 octet sa inteleg ca folosirea multibyte character encoding va returna negativ ?

Nu inteleg writing wide characters


#include<stdio.h>

int main()
{
char z = 0;

z = printf("?");
printf("\n%d\n",z);

return 0;
}

Link to comment
Share on other sites

Referitor la acest "curs" ca sa-i spun asa, am avut foarte mari asteptari, eu credeam ca o sa se desfasoare in genul cursurilor de la liceu ... facultate, adica cineva mai experimentat in acest limbaj sa incerce in limita timpului disponibil sa ia fiecare capitol si subcapitol si sa incerce sa explice mai pe intelesul tuturor(adica mai mult decat este in carte), ce inseamna,... ce face si cu ce se "mananca" chestiile de acolo.

Eu asa am crezut ca va fi si chiar m-am bucurat cand am vazut ca exista o astfel de initiativa.Eu vreu sa invat acest limbaj, dar in felul cum a fost pana acum nu ma ajutat foarte mult.

Sper sa nu fiu inteles gresit, dar astea erau asteptarile mele(ca incepator in acest limbaj).

Oricum eu personal va multumesc pentru initiativa.

Link to comment
Share on other sites

Scorpion, felul in care decurge este in regula.Tu trebuie sa citesti capitolele respective si in caz ca nu ai inteles ceva postezi in acest topic.Daca nu intelegi limba engleza cel putin la nivel mediu ia si citeste din cartea 'Totul despre C/C++'.Dupa parerea mea este o carte din care poti invata multe si daca nu vrei sa dai 75 lei (cat face in librarie in momentul de fata) o poti gasi pe internet in format pdf.

Link to comment
Share on other sites

Acest thread este de intrebari si raspunsuri.

O sa fac unul in seara asta cu review pentru primele 3 capitole unde scriem ce am invatat de acolo.

De ce zici ca nu te-a ajutat foarte mult? E topic de intrebari. Daca nu intelegi ceva, de ce nu intrebi?

Cu mentalitatea asta nu o sa faci nimic in domeniul asta. Nu o sa stea nimeni sa te invete ca la gradinita.

Ia si citeste primele 3 capitole si exerseaza. Cand nu intelegi ceva, intrebi aici sau cauti pe internet.

Daca intrebi, ti se va raspunde dupa cum ai vazut.

Trebuia sa fac topicul de review ieri seara dar nu am avut timp pentru ca am fost ocupat cu alte chestii din viata personala.

Stau la calculator peste 14 ore pe zi in fata codului si testelor si multe altele. Suntem oameni si noi asa ca puneti osu daca vreti sa invatati.

Aveti tot sprijinul nostru si va raspunde la intrebari, ba mai mult facem si un review despre ce s-a invatat in capitolele precedente.

Mai mult nu avem ce face. Nu poti sa stai pe scaun si sa iti bage cineva cunostiinte in cap. Trebuie sa citesti si tu si sa exersezi.

Ne vedem diseara cu threadul de review si incerc sa mai raspund de aici la intrebari la care nu s-a raspuns.(daca sunt)

Link to comment
Share on other sites

Scorpion, felul in care decurge este in regula.Tu trebuie sa citesti capitolele respective si in caz ca nu ai inteles ceva postezi in acest topic.Daca nu intelegi limba engleza cel putin la nivel mediu ia si citeste din cartea 'Totul despre C/C++'.Dupa parerea mea este o carte din care poti invata multe si daca nu vrei sa dai 75 lei (cat face in librarie in momentul de fata) o poti gasi pe internet in format pdf.

Inteleg limba engleza cel putin la nivel mediu, dar cand esti incepator la un limbaj de programare, in cazul nostru C , care nu este foarte greu , dar nici prea usor de invatat, cel putin pentru mine este putin mai greu sa invat(acest limbaj) fara sa imi explice cineva mai pe larg, adica la un moment dat nu mai inteleg nimic.

Ca sa fiu mai explicit,... crezi ca la scoala ai putea sa inveti daca nu ti-ar explica profesorul lectia?

Cam asa sunt eu acum.

Inca o data cer sa nu fiu inteles gresit, nu vreau sa aduc critici, doar spuneam parerea mea.

Link to comment
Share on other sites

Nu este nici o problema.Cand nu intelegi ceva postezi, astepti raspuns, si nu treci mai departe pana nu iti raspunde cineva ca sa intelegi in detaliu ce ai citit.Nu cred ca este vreo problema numarul posturilor acumulate in acest topic si oricum e prea putin probabil sa pui o intrebare la fiecare 10 randuri citite(in cazul acesta e destul de greu sa inveti in acest mod).

Edited by Erase
Link to comment
Share on other sites

Nu-i problema cat se posteaza in threadurile astea.

Parerea mea e ca daca sunt mai multe intrebari, cu atat mai bine. O sa inteleaga toata lumea mai bine.

Deci chiar incurajez lumea sa posteze intrebari.

Sa nu mai continuam cu asta ca murdarim threadul.

Continuati dar cu intrebari din carte, nu altceva.

Intrebarile si sugestiile de genu va rog sa le puneti aici: https://rstforums.com/forum/72777-rst-academy.rst

Link to comment
Share on other sites

Mersi Erase & silvadark pentru raspunsuri. Dar mai am intrebari :)

Incerc sa inteleg ce e writing error .... writing on what ?

Daca setul de caractere ASCII poate fi reprezentat pe 1 octet sa inteleg ca folosirea multibyte character encoding va returna negativ ?

Nu inteleg writing wide characters


#include<stdio.h>

int main()
{
char z = 0;

z = printf("?");
printf("\n%d\n",z);

return 0;
}

In mod normal un char este reprezentat pe 1 byte. Totusi wide char's pot fi reprezentati pe 2 sau mai multi bytes, in functie de implementare. In general se folosesc 2 bytes. Problema e felul in care aceste caractere sunt reprezentate in cei 2 bytes. Windows foloseste un anumit charachter set(UTF16 parca). Pe cand linux foloseste Unicode(UTF-8). Poti citi ceva mai multe aici. Motivul pentru care functia esueaza in cazul in care se ofera un character wide functiei printf este urmatorul. Functia trebuie sa citeasca caracter cu caracter dintr-un array.

Gandeste-te in felul urmator: "TEST" va ocupa in ascii, modul standard 4 bytes. In fiecare byte va exista una din litere.

Daca in schimb tu folosesti caractere wide fiecare litera va ocupa cate 2 bytes dar functia va citi cate 1, si nu va sti sa il interpreteze.

E ca atunci cand citesti doar cateva litere dintr-un cuvant. Nu stii sigur ce reprezinta acele litere. Asa si aici.

Link to comment
Share on other sites

Se da secventa urmatoare:

int c;

c = getchar();

while (c != EOF)

{

putchar©;

c = getchar();

}

Nu inteleg o chestie. La momentul executiei codului, eu introduc de ex. un sir de 50 de caractere (deci 50 bytes) si apas Enter, moment in care ce am introdus eu se memoreaza in variabila c si apoi se compara cu EOF.

Dar c are tip intreg si e stocata pe doar 4 bytes. Cum e posibil sa-mi returneze intreg sirul? Ce anume imi scapa?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...