
Forumul dedicat sistemului de operare Ubuntu în România
Forumul Ubuntu România
Forumul de discuții și asistență al comunității Ubuntu din România
Forumul dedicat sistemului de operare Ubuntu în România
Forumul de discuții și asistență al comunității Ubuntu din România
Neautentificat.
Buna-ziua! Sunt incepator in ale c++'ului si am o problema la urmatorul cod:
#include <iostream> using namespace std; int main() { int st,sn,a,n; st=0; sn=0; cout<<"Introduceti numarul de valori "<<endl; cin>>n; for (int i = 1; i <= n; i++){ cout<<"Introduceti valoare "; cin>>a; } while(a!=0){ st=st+1; if(a<0){ sn=sn+1; } } if(st==sn){ cout<<"Toate numerele sunt negative" << endl; } else { cout<<"Nu sunt toate numerele negative" << endl;} return 0; }
Enuntul problemei este urmatorul: se citesc n numere pana la 0. Sa se afiseze daca toate numerele sunt negative.
Eroarea este ca dupa ce dau run si introduc numarul de valori cat si valorile, programul imi afiseaza direct "toate numerele sunt negative", nu ia in considerare si instructiunea "while". Am incercat sa inchid acoladele de la "for" dupa while pentru a-l "cuprinde" dar daca fac acest lucru dupa ce dau run procesul decurge in acest mod:
Introduceti numarul de valori: 5
Introduceti valorile: 1
---------
Se blocheaza iar doar ca la liniile de deasupra structurii "while".
Va rog ajuti-ma! Multumesc anticipat!
*Si o poza cu programul:
Editat ultima oară de Prolifer (10 Mar 2016 11:40:44)
Offline
hmm.... codeblocks pe windows daca nu gresesc si c++. cumva tema de acasa ? care e macar legatura cu forumul Ubuntu ?
Editat ultima oară de geosoft1 (09 Mar 2016 20:59:15)
Offline
Credeam ca am gasit un forum in care se pot intreba chestii legate de c++, nu stiam ca trebuie sa aiba neaparat legatura cu Ubuntu Imi cer scuze de deranj. Imi puteti recomanda macar un site de pasionati in ale programarii?
Offline
nu stiam ca trebuie sa aiba neaparat legatura cu Ubuntu
nu-i nimic, revin-o cand treci pe Ubuntu ca si sistem de operare si vei avea dificultati in scrierea de programe in C++ utile pentru comunitate.
atunci voi fi primul care te voi ajuta
Editat ultima oară de geosoft1 (09 Mar 2016 21:29:29)
Offline
@geosoft1 Exista o categorie care se numeste programare, sti la ce se refera?
Offline
Prolifer a scris:
Imi puteti recomanda macar un site de pasionati in ale programarii?
Da StackOverFlow.
Eu te-as ajuta, dar nu ma duce mintea sa imi dau seama ce intelegi tu prin:
Sa se afiseze daca toate numerele negative sunt 0
Adica sa fiu sincer, cum poate [b]0[/b] sa fie negativ?
Editat ultima oară de TARA24. (09 Mar 2016 22:16:18)
Offline
Prolifer a scris:
Imi puteti recomanda macar un site de pasionati in ale programarii?
Da StackOverFlow.
Eu te-as ajuta, dar nu ma duce mintea sa imi dau seama ce intelegi tu prin:
Sa se afiseze daca toate numerele negative sunt 0
Adica sa fiu sincer, cum poate 0 sa fie negativ
Incearca sa intelegi urmatorul program:
#include<stdio.h> int main(void){ int arr[5]; int i,j; int positiv; for (i=0; i<5 ; i++){ if((scanf("%d",&arr[i])) != 1 ){ printf("Eroare scanf\n"); } } printf("Numerele da-te de tine sunt\n"); for(j=0; j<5;j++){ printf("%d ",arr[j]); } printf("\n"); for(j=0; j<5;j++){ if(arr[j] >= 0){ positiv = 1; }else{ positiv = 0; break; } } if(positiv == 1){ printf("Toate numerele sunt Pozitive"); }else{ printf("Toate numerele nu sunt Pozitive"); } }
Este scris in C dar nu cred ca nu il intelegi.
Editat ultima oară de TARA24. (09 Mar 2016 22:43:53)
Offline
Observația nr. 1
Trebuie să prelucrezi fiecare valoare citită, deci while trebuie să fie în acolada de la for. PS: nu înțeleg de ce ai pus while.
Observația nr. 2
while(a!=0){ st=st+1; if(a<0){ sn=sn+1; } }
while este o structură repetitivă: instrucțiunile din acoladă se repetă cât timp condiția a!=0 este adevărată. Acolo variabila a nu se modifica de loc, deci se obține o buclă infinită - după ce citești primul număr rulează la infinit și nu-l poți introduce pe al doilea. Repet, nu înțeleg de ce ai pus while. Cred că ai vrut să pui if.
Observația nr. 3
Această problemă nu este pentru "pasionații de C++", ci este evident o temă acasă, dar să-ți fie de folos!
Observația nr. 4
Cred, uitându-mă la ce ai scris tu acolo, că problema cere să verifici dacă toate numerele nenule sunt pozitive.
Offline
@TARA24 multumesc pentru raspuns dar din pacate incerc sa invat limbajul "comun", abia ma descurc in C++. Imi cer scuze, am dat enuntul gresit, enuntul corect era:
Se citesc n numere pana la intalnirea numerelor cu 0. Sa se afiseze daca toate numerele sunt negative.
@csilviu am folosit while pentru ca urma sa introduc un sir de valori, dintre care una din valori urma sa fie 0. Cand il intalnea pe 0, programul trebuia sa se opreasca si sa-mi afiseze daca restul valorilor introduse sunt toate negative sau nu. Eroarea mea este ca dupa ce dau run si introduc valorile imi afiseaza direct "Toate numerele sunt negative", sare peste instructiunea while. Daca inchid acolada de la "for" dupa "while", imi cere sa introduc numarul de valori, o valoare, iar dupa aceea se blocheaza.
*Nu este tema de acasa intrucat la scoala nu fac informatica inca. Multumesc pentru raspuns!
Acum imi dau seama ca as putea sa fac problema si fara structura while, dar vreau sa invat cum functioneaza si acest while.
Editat ultima oară de Prolifer (10 Mar 2016 11:53:40)
Offline
@Profiler: Citirea trebuie facuta in ciclul while. For se foloseste cand stii deja cate elemente vor fi citite.
Offline
hritcucos a scris:
@Profiler: Citirea trebuie facuta in ciclul while. For se foloseste cand stii deja cate elemente vor fi citite.
Hmm acum am inteles, dar daca fac citirea in while cum o sa mai pot seta programul sa permita introducerea a mai multe valori?
Offline
@Profiler:
cout<<"introduceti valoare";cin>>a;
while (a!=0){
st=st+1;
if (a<0) sn=sn+1;
cout<<"introduceti valoare";cin>>a;
}
cam asa ceva zic eu
Offline
Prolifer a scris:
@TARA24 multumesc pentru raspuns dar din pacate incerc sa invat limbajul "comun", abia ma descurc in C++. Imi cer scuze, am dat enuntul gresit, enuntul corect era:
Se citesc n numere pana la intalnirea numerelor cu 0. Sa se afiseze daca toate numerele sunt negative.
Repet, nu stiu C++ dar o sa rog pe cineva sa il rescrie in C++:
Incearca te rog sa il intelegi, daca nu reusesti revin-o cu intrebari:
#include<stdio.h> #include<stdlib.h> int main(void){ int n,i,j,negativ=0,zero=0; printf("Cate numere doresti sa testezi?:> "); if((scanf("%d", &n)) != 1){ printf("Eroare citire\n"); exit(1); }else if(n < 1){ printf("Numarul dat de tine trebuie sa fie mai mare de 0\n"); exit(1); } int arr[n]; printf("Introdu %d numere\n",n); for (i=0; i<n ; i++){ if((scanf("%d",&arr[i])) == 1 ){ if(arr[i] != 0){ zero++; }else{ break; } }else{ printf("Eroare scanf\n"); exit(2); } } printf("\n\n"); printf("Numerele da-te de tine sunt\n"); for(j=0; j<zero;j++){ printf("%d ",arr[j]); } printf("\n\n"); for(j=0 ; j<zero ; j++){ if(arr[j] == 0){ break; }else if(arr[j] < 0){ printf("%d ",arr[j]); negativ = 1; } } if(negativ == 0){ printf("\n"); printf("Nu exista numere negative\n"); } printf("\n"); return 0; }
Scenariul 1:
Cate numere doresti sa testezi?:> -4
Numarul dat de tine trebuie sa fie mai mare de 0
Scenariul 2:
Cate numere doresti sa testezi?:> 5
Introdu 5 numere
1
2
3
4
5
Numerele da-te de tine sunt
1 2 3 4 5
Nu exista numere negative
Scenariul 3:
./program
Cate numere doresti sa testezi?:> 5
Introdu 5 numere
1
-2
3
0
Numerele da-te de tine sunt
1 -2 3
-2
Scenariul 4:
./program
Cate numere doresti sa testezi?:> 5
Introdu 5 numere
-1
4
-2
6
-15
Numerele da-te de tine sunt
-1 4 -2 6 -15
-1 -2 -15
Offline
@Tara24 multumesc mult pentru ajutor! Am inteles programul, chiar daca nu sunt in stare sa-l rescriu, am inteles cum functioneaza
Offline
Nu stiu cum sta treaba cu C++ insa in C nu este usor sa lucrezi. Acesta este si motivul pentru care aproape toti trec la C++ pentru ca este o imbunatatire a lui C, insa nu inseamna, ca este mai bun decat C, dar limbajul C pe cat este de mic pe atat este de greu.
Eu nu am facut-o si nici nu o fac din motive clare pe partea Hardware (drivere, OS) unde C++ nu isi are locul.
Acum cateva idei despre program:
1) Trebuie sa sti ce vrei sa faci
2) trebuie sa te asiguri ca programul face cea ce trebuie
3) Trebuie sa te asiguri ca utilizatorul va rula programul tau asa cum l-ai gandit tu.
4) Nu te baza pe utilizatorul care va rula programul tau, ca v-a rula programul asa cum l-ai gandit tu.
Astfel spuse, trebuie sa fortezi utilizatorul sa tasteze o cifra, daca nu o face programul trebuie sa se opreasca s-au sa faci un LOOP.
Indiferent de decizie utilizatorul trebuie informat de ce greseste.
Se trece apoi la citerea acelor N numere si la fel si aici, se face verificarile necesare pentru a "forta" utilizatorul sa ruleze programul cum vrei tu si nu aiurea cum vrea el, pentru ca nu il sie sau accidental apasa o alta tasta, A inloc de 5...etc.
In timp ce se citesc acele numere se va compara fiecare citire cu cifra zero, daca nu este egala se va actualiza variabila care eu am numit-o tot zero, pentru a putea rula acel LOOP cu maximul Legal in acel ARRAY, fara a acccesa illegal memorie care nu ne apartine.
De asta in acel for:
for(j=0 ; j<zero ; j++)
avem ZERO in loc de N deoarece N == 5, insa noi nu stim daca sunt tastate 5 cifre > decat ZERO.
Cu timpul ai sa vezi ca nu este asa complicat, insa tu te vei complica daca nu citesti atent cand inveti ceva si daca nu incerci sa scrii singur coduri.
Chiar daca nu iti iese ce-a ce vrei, sa sti, ca munca ta va fi apreciata si lumea te va ajuta sa vezi unde gresesti.
Nu cere cod niciodata deoarece nu vei fi niciodata suficient de pregatit.
Nu te apuca sa scrii algoritmii pana nu esti in clar cu limbajul.
Mare atentie ca do while while si for tot ce au in comun este ca sunt LOOP-uri, insa toate sunt diferite. Ai sa vezi asta cand o sa ai NESTED LOOP's.
Uite aici un exemplu unde este nasol, daca crezi ca for si while fac acelasi lucru:
Exemplu 1:
#include<stdio.h> #include<string.h> int main(void){ const char *str = "Mississippi"; char tmp[15] = {0}; size_t i=0,j=0,k=1; int found=0; tmp[0] = str[0]; printf("Before = %s\n",str); while(str[i] != '\0'){ for(j=0;tmp[j] != '\0';j++){ if(tmp[j] == str[i]){ found++; } } if(found==0){ tmp[k]=str[i]; k++; } found=0; i++; } tmp[strlen(tmp)] = '\0'; printf("After = %s\n",tmp); return 0; }
Output:
Before = Mississippi
After = Misp
Exemplul 2:
#include<stdio.h> #include<string.h> int main(void){ const char *str = "Mississippi"; char tmp[15] = {0}; size_t i=0,j=0,k=1; int found=0; tmp[0] = str[0]; printf("Before = %s\n",str); while(str[i] != '\0'){ while(tmp[j] != '\0'){ if(tmp[j] == str[i]){ found++; } j++; } if(found==0){ tmp[k]=str[i]; k++; } found=0; i++; } tmp[strlen(tmp)] = '\0'; printf("After = %s\n",tmp); return 0; }
Output:
Before = Mississippi
After = Misisipi
Te las pe tine sa te gandesti, care din cele 2 exemple este gresit.
Bafta.
Offline
Exista o categorie care se numeste programare, sti la ce se refera?
oarecum, dar daca vrei dat fiind faptul ca enuntul era usor neclar eu il scriam asa:
#include <stdio.h> int main() { int n, p = 0; printf ("Introduceti numere "); do { scanf("%d", &n); if (n > 0) p++; } while (n != 0); printf ("Numerele%s sunt negative\n", p ? " nu" : "" ); }
sau in c++:
#include <iostream> using namespace std; int main() { int n, p = 0; cout << "Introduceti numere "; do { cin >> n; if (n > 0) p++; } while (n != 0); cout << "Numerele" << (p ? " nu" : "") << " sunt negative" << endl; }
Offline
geosoft1 a scris:
eu il scriam asa:
Cod:
#include <stdio.h> int main() { int n, p = 0; printf ("Introduceti numere "); do { scanf("%d", &n); if (n > 0) p++; } while (n != 0); printf ("Numerele%s sunt negative\n", p ? " nu" : "" ); }
Sintaxa corecta dupa noul standard este:
int main(void){}
sau
int main(int argc, char *argv[])
Defapt inca din C99 este asa:
C99 5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent; or in some other implementation-defined manner.
cea ce inseamna ca:
return type of int and with no parameters:
trebuie sa fie explicit void. In curand apare GCC-6 si o sa fie default la fel cum in GCC-5, C11 este deja implicit.
Acum nu cred, ca are rost sa facem polemica aici desi este un aspect important.
Marea problema o ai la scanf pe care observ ca il folosesti fara sa il verifici de erori:
./program
Introduceti numere f
Numerele sunt negative
Daca vine vorba de valgrind treaba este si mai clara:
==4082== Command: ./program
==4082==
Introduceti numere f
==4082== Conditional jump or move depends on uninitialised value(s)
==4082== at 0x4005D6: main (program.c:8)
==4082== Uninitialised value was created by a stack allocation
==4082== at 0x40059D: main (program.c:3)
==4082==
==4082== Conditional jump or move depends on uninitialised value(s)
==4082== at 0x4005E1: main (program.c:9)
==4082== Uninitialised value was created by a stack allocation
==4082== at 0x40059D: main (program.c:3)
==4082==
Numerele sunt negative
==4082==
==4082== HEAP SUMMARY:
==4082== in use at exit: 0 bytes in 0 blocks
==4082== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4082==
==4082== All heap blocks were freed -- no leaks are possible
==4082==
==4082== For counts of detected and suppressed errors, rerun with: -v
==4082== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0
Iar ca parere personala nu cred ca Operatorul Ternar este exact o solutie pentru un incepator, dar repet parerea este personala.
In cea ce priveste codul tau, nu imi doresc sa ajung vre-odata, sa trebuiasca sa developez mai departe cod dupa tine:
#include <stdio.h> #include <stdlib.h> int main(void) { int n, p = 0; printf ("Introduceti numere "); do { if((scanf("%d", &n)) != 1){ printf("Eroare scanf"); exit(1); } if (n > 0){ p++; } } while (n != 0); printf ("Numerele%s sunt negative\n", p ? " nu" : "" ); }
Asa se procedeaza codect in C ,daca vrei ca cineva sa iti developeze codul mai departe si nu ce-a ce ai COD-at tu acolo.
==4139== Command: ./program
==4139==
Introduceti numere f
Eroare scanf==4139==
==4139== HEAP SUMMARY:
==4139== in use at exit: 0 bytes in 0 blocks
==4139== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4139==
==4139== All heap blocks were freed -- no leaks are possible
==4139==
==4139== For counts of detected and suppressed errors, rerun with: -v
==4139== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Si sa rezolvat si problema cu n fiind neinitializat.
Offline
nu vreau sa iti tai avantul dar...
int main(void){} si int main(){}
inseamna exact acelasi lucru. la fel ca si
if (n > 0){
p++;
}
si
if (n > 0) p++;
cat despre argumente (int main(int argc, char *argv[])) nu e cazul ca nu folosim.
Marea problema o ai la scanf pe care observ ca il folosesti fara sa il verifici de erori
exact. care erori ?
problema cu n fiind neinitializat
da. n este neinitializat. dar, de ce oare l-am pus asa ?
dar exista si o eroarea acolo... aici ma gandeam ca te uiti, daca dai direct 0 iti spune gresit ca numerele sunt negative
deci mai corect ar putea fi:
#include <stdio.h> int main() { int n, p = 0, m = 0; // aici m trebuie initializat printf ("Introduceti numere "); do { m += scanf("%d", &n); if (n > 0) p++; } while (n != 0); if (m>1) printf ("Numerele%s sunt negative\n", p ? " nu" : "" ); else printf ("Introduceti cel putin un numar!"); }
totusi, hai sa nu facem o polemica chiar din nimic...
Editat ultima oară de geosoft1 (13 Mar 2016 19:21:09)
Offline
In primul rand programul tau nu este portabil citeste mai mult despre Hosted Environment.
In al-2-lea rand te invit pe StackOverFlow si putem discuta acolo.
Faptul ca sunt anumite implementatii unde este permis acest lucru, ca tu, sa declari main fara argumente (int main(){}) este chestie de implementation-defined.
Noul standard (C11) specifica ca este "obsolete", te rog sa citesti Standard C11 eu nu mai fac referire la el di nou doar ca tu esti de Old fashion.
Acum legat de ultima ta tentativa de program am sa te rog sa folosesti Valgrind inainte sa te apuci de programe in C sau sa dai sfaturi:
valgrind --leak-check=full --track-origins=yes --leak-check=full
Bafta:
==4820== Memcheck, a memory error detector
==4820== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4820== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4820== Command: ./program
==4820==
Introduceti numere g
==4820== Conditional jump or move depends on uninitialised value(s)
==4820== at 0x4005E0: main (program.c:8)
==4820== Uninitialised value was created by a stack allocation
==4820== at 0x40059D: main (program.c:3)
==4820==
==4820== Conditional jump or move depends on uninitialised value(s)
==4820== at 0x4005EB: main (program.c:9)
==4820== Uninitialised value was created by a stack allocation
==4820== at 0x40059D: main (program.c:3)
==4820==
j
j
j
==4820==
==4820== More than 10000000 total errors detected. I'm not reporting any more.
==4820== Final error counts will be inaccurate. Go fix your program!
==4820== Rerun with --error-limit=no to disable this cutoff. Note
==4820== that errors may occur in your program without prior warning from
==4820== Valgrind, because errors are no longer being displayed.
==4820==
Offline
e, nu e portabil... folosesti cuvinte foarte complicate dar din pacate fara fundament (Hosted Environment,`implementatii `,implementation-defined,Old fashion,valgrind).
legat de valgrind... faptul ca semnaleaza variabila aia neinitializata nu inseamna nimic. sunt lucruri care se semnaleaza in mod standard. poti sa initializezi n-ul ala cu cat vrei ca daca urmatoarea instructiune e una care oricum il initializeaza atunci nu conteaza. insa incrementarea urmatoare nu se face pe variabila neinitializata deci acolo conteaza. cu alte cuvinte chiar daca valgrind ala semnaleaza in mod corect
More than 10000000 total errors detected. I'm not reporting any more.
de fapt spune o prostie
Editat ultima oară de geosoft1 (13 Mar 2016 19:11:23)
Offline
geosoft1 a scris:
de fapt spune o prostie
Nu si daca te asiguri tu, sa nu se ajunga acolo
Oricum nu as salva rezultatul lui scanf (m) fara sa verific daca scanf are errori la citire.
m += scanf("%d", &n);
Daca apas orice litera duce la loop infinit si cifra 0 (zero) nu te mai scoate de acolo . Sunt convins ca orice Debugger iti confirma asta.
Editat ultima oară de TARA24. (13 Mar 2016 21:31:34)
Offline
prietene, tocmai ai gasit nodul din papura
aici este vorba de o problema simpla de gimnaziu si ti-am aratat cum se face in 11/14 linii ce ai facut tu in 55. ca sa verifici daca niste amarate de numere sunt negative poti sa o faci foarte simplu prin detectarea pozitivelor din citire si incrementarea unui contor pe care il verifici ulterior. ideea era algoritmul, nu ai nevoie de vectori acolo
in plus ma iei cu profilere,standarde si teoria lui void... c'mon
nu ai nevoie de profilere/debugere ca sa vezi daca o variabila trebuie sau nu initializata. sunt lucruri care se vad dar nu le vezi dupa cateva luni de programare
apoi, daca vrei sa verifici toate tipurile de traznai pe care le poate introduce utilizatorul esti invitatul meu dar probabil numai tu o vei face intr-un program de uz didactic. ca si verificarile cu Valgrind... care asa cum ti-am demonstrat spune si prostii
asa ca
legat de ultima ta tentativa de program am sa te rog ... inainte sa te apuci de programe in C sau sa dai sfaturi
sa te concentrezi mai mult pe algoritm
Editat ultima oară de geosoft1 (14 Mar 2016 21:31:30)
Offline
geosoft1 a scris:
sa te concentrezi mai mult pe algoritm
Frustrat rau mai esti )
In fine nu este comparabila abordarea ta cu a mea, tu folosesti o variabila eu un Array. Totul este in scop documentar.
Modul meu, cum am abordat problema este pentru a bloca utilizatorul, de a mai folosii programul in momentul in care il utilizeaza incorect sau, daca se ajunge la posibile erori de citire (vezi ce returneaza scanf).
Daca tu crezi, ca abordarea mea este gresita, ce sa zic....esti nesigur pe tine in C si ai trecut la un alt Limbaj mai simplu .
Editat ultima oară de TARA24. (14 Mar 2016 22:14:02)
Offline