C programavimo bedos

Skelbti atsakymą
Žinutė
Autorius
Vartotojo avataras
mrg
garbės narys
garbės narys
Pranešimai:229
Užsiregistravo:2006 02 07 20:14
C programavimo bedos

#1 Standartinė mrg » 2006 10 23 13:50

Sveiki (ypac su brain'u, godhack'u ir darkforce), prireike jusu pagalbos. kaip pastebejau atsirado nauju flooderiu :D Geriau neminesiu ju niku, tos pacios emocijos dar tebera, kaip sakoma seni laikai.Dziaugiuosi, kad prisijunge ir gudresni veikejai, o ne tik pienburniai :) Pradejau programuoti c kalboje, noriu paprasyti, kad istaisytumete klaidas siame kode ir jei galite kuo placiau pakomentuokite. Nes kai paleidziu programa ji pakimba. Aciu is anksto.


#include<stdio.h>
main()
{
char x,y;
int z;
printf("Koks jusu vardas\n", x);
scanf("%s", x);
printf("Kokia jusu pavarde\n");
scanf("%s", y);
printf("Iveskite savo gimimo metus\n");
scanf("%ld", z);
printf("Jusu vardas: %s\n Pavarde: %s \n Jusu gimimo metai: %ld", &x,&y,&z);
system("PAUSE");
return 0;
}

brain5ide
profesionalas
profesionalas
Pranešimai:2030
Užsiregistravo:2004 12 01 19:05

#2 Standartinė brain5ide » 2006 10 23 14:40

Sveikas mrg. Taigi, brainas pradeda paskaitėlę, kadangi pirmasis čia užklydo :)
Programa "pakimba" todėl, kad iškviečiama funkcija system("PAUSE"). Ji sustabdo tolesnė kodo vykdymą. Kaip supratau, tu nori, kad programos langas neužsidarytų, kai tik atspausdinami rezultatai. Apie šį iškvietimą rašoma čia: http://cpp.codenewbie.com/articles/cpp/ ... age_1.html
Taigi, kaip sakė šio straipsnelio autorius, šito iškvietimo geriau nevartoti. Ten parašyta funkcija, kuri turėtų sustabdyti darbą, bet tik pradėjusiam programuoti su C, manau, geriau būtų naudoti paprasčiausią scanf. Kaip ir paskalyje readln.
Taigi, išsiaiškinom problemą, dėl ko programa pakimba. Bet šiaip, ji ir kompiliuotis turėtų su perspėjimais, kadangi čia padarytos dar kelios programavimo klaidos.

Kodas: Pasirinkti visus

char x,y;
Šita vieta sukuria du char tipo kintamuosius. Į char tipo kintamąjį galima įrašyti tik vieną simbolį, taigi, norint įvesti vardą reikia naudoti rodykles arba masyvus.

Kodas: Pasirinkti visus

char x[15], y[15]; //masyvai arba
char *x, *y; // rodyklės
Tokiu atveju išsitaiso ir klaida su scanf. Nuskaitydami simbolių eilutę string(su scanf, naudodami %s), turime pateikti atminties adresą(taip pat ir nuskaitant skaičius ar dar ką kitką perduodamas adresas). Jeigu sakysime, kad vis dėlto norėjome nuskaityti po vieną simbolį, tuomet turime šiek tiek pakeisti scanf iškvietimą(rodyklių ir masyvų atveju čia viskas tvarkoje, t.y. jeigu pradžioje sukūrėme rodykles ar masyvus, čia nieko keisti nereikia). scanf su %s argumentu į nudorytą adresą įkelia nurodytus simbolius + eilutės pabaigos simbolį "\n". Taigi į vieną simbolį galintį išsaugoti kintamąjį dviejų simbolių neįrašysime. %s keičiame į %c/

Kodas: Pasirinkti visus

scanf("%c", &x);
Toliau viskas gerai, pagal esamą kodą, tačiau jeigu naudosime ne simbolius, tai reikės pakeisti printf iškvietimą.

Kodas: Pasirinkti visus

 printf("Jusu vardas: %s\n Pavarde: %s \n Jusu gimimo metai: %ld", x,y,z);
Na lyg ir viskas. O dabar parašysiu, kaip ši programa turi atrodyti, kad ji veiktų.

Kodas: Pasirinkti visus

#include <stdio.h>
// programa su simboliais, t.y. vardas ir pavardė po vieną raidę
int main()
{
  char x,y;
  int z;
  printf("Koks jusu vardas\n");
  scanf("%s", &x);
  printf("Kokia jusu pavarde\n");
  scanf("%s", &y);
  printf("Iveskite savo gimimo metus\n");
  scanf("%ld", &z);
  printf("Jusu vardas: %c\n Pavarde: %c \n Jusu gimimo metai: %ld", x,y,z);
  scanf("%d", &z);
  return 0;
}
kita versija

Kodas: Pasirinkti visus

#include<stdio.h>
main()
{
char x[15],y[15]; // sukurti 15 simbolių dydžio masyvai
int z;
printf("Koks jusu vardas\n");
scanf("%s", x);
printf("Kokia jusu pavarde\n");
scanf("%s", y);
printf("Iveskite savo gimimo metus\n");
scanf("%ld", &z);
printf("Jusu vardas: %s\n Pavarde: %s \n Jusu gimimo metai: %ld", x,y,z);
return 0;
}
Tingiu toliau aiškinti. Jei bus klausimų - klausk.

P.S. Pas tave printf, kuris klausia vardo taip pat parašytas klaidingai :) Šitą pastebėjau tik rašydamas kodą :D Kadangi formato simbolių(tų, kurie pasideda procentų ženklais) nėra, tai x argumentas yra nereikalingas. Tačiau jokios reikšmės programos veikimui šitai neduoda. Tiesiog pastebėjimas.
Never argue with an idiot. They bring you down to their level and beat you with experience.

Vartotojo avataras
mrg
garbės narys
garbės narys
Pranešimai:229
Užsiregistravo:2006 02 07 20:14

#3 Standartinė mrg » 2006 10 23 16:45

Didziulis aciu, prireikus uzbegsiu i skaitykla ir paprasysiu jusu pagalbos :) Tik dar nesuprantu kada reikia naudoti ambersendo simboli pries kintamaji &?

brain5ide
profesionalas
profesionalas
Pranešimai:2030
Užsiregistravo:2004 12 01 19:05

#4 Standartinė brain5ide » 2006 10 23 16:50

Kai tau reikia gaut kintamojo adresa. Pvz. scanf() reikalauja adreso. Tačiau jeigu su rodyklėm darai, nereikia & , nes rodyklė yra kintamasis, kuris saugo adresą. Pridėdamas & tu gausi pačios rodyklės adresą. Ganėtinai painu atrodo, bet šiek tiek pasėdėjus ir viską išsiaiškinus nėra taip sunku.
Never argue with an idiot. They bring you down to their level and beat you with experience.

Vartotojo avataras
Trolis gumis
Crowbar Master
Pranešimai:1980
Užsiregistravo:2003 07 19 14:23

#5 Standartinė Trolis gumis » 2006 10 23 23:41

system ("pause")
reikalingas naudot jeigu kompiliuosi su....pvz Dev c++ kompiliatorium. atsimenu, kol normalaus microsoftinio visual c++ neparsipuciau, nesupratau, kodel namie su Dev gaudavosi, o univere su microsoftiniu paluzdavo. tiesiog jei nori naudot system("pause") komanda, reikia dar kazkokia biblioteka dasijungti, tada atrodo, viskas normaliai vyksta.

Vartotojo avataras
mrg
garbės narys
garbės narys
Pranešimai:229
Užsiregistravo:2006 02 07 20:14

#6 Standartinė mrg » 2006 12 14 11:41

Reikia patarimo :) noreciau, kad papasakotu, kas ismano (breinai, tu laukiamas visuomet :) ) placiau apie do-while operatoriu, kada programoje turi buti dvi ar daugiau main() funkciju ir tarkim atidarius tekstini dokumenta su fopen, kad nuskaitytu ten esancius skaicius? Jei kiltu kitu klausimu - rasysiu :)

brain5ide
profesionalas
profesionalas
Pranešimai:2030
Užsiregistravo:2004 12 01 19:05

#7 Standartinė brain5ide » 2006 12 14 17:41

Do while veikia lygiai taip pat, kaip ir while, tik tas, kad sąlyga yra tikrinama po atilkimo.

Kodas: Pasirinkti visus

while(1==2)
{
    kodas;
}
Čia kodas nebus atliktas, nes sąlyga pateikta tarp skliaustų nėra teisinga.
Na o dabar while ciklą perdarykime į do while ciklą.

Kodas: Pasirinkti visus

do
{
    kodas;
}while(1==2);
Čia kodas bus atliktas vieną kartą, nors sąlyga ir yra klaidinga. Tiesiog čia sąlyga tikrinama po kodo vykdymo.

Apie dvi main() funkcijas neesu girdėjęs.

O dėl skaitymo iš failo, tai jis vykdomas panašiai, kaip ir iš klaviatūros, tik funkcijų pavadinimai nežymiai skiriasi.

Kodas: Pasirinkti visus

int a[10]; // 10 sveikų skaičių masyvas, į kurį įkelsime skaičius iš failo
int i=0; // i naudosime, kaip indeksą masyvo elementams
int buf; // kintamąjį buf naudosime, kaip laikinąjį elementą;
FILE  *fp; // failo rodyklė;
fp = fopen("failas.txt", "r"); // failo atidarymas skaitymo režime
fscanf(fp,"%d",&buf);
while(buf != EOF && i < 10) // tikriname, ar gautas skaičius nėra failo pabaigos žymuo ir ar ne per daug skaičių paėmėm
{
    a[i++] = buf;
    fscanf(fp,"%d",&buf);
}
fclose(fp);
Na jeigu vien tik pažiūrėjus į kodą ir komentarus yra šiek tiek neaišku, tai paaiškinsiu dar šiek tiek.
Eilutė FILE *fp; reikalinga tam, kad programa žinotų, kad ten mes saugome failą(tiksliau jo adresą, kuomet jis įkeltas į atmintį su funkcija fopen).
fopen("failo_vardas","r"); nurodo, kad failą mes atidarom skaitymo režime(kitiems režimams kodai skiriasi). Ji įkelia tą failą į atmintį ir gražina adresą, kad galėtumėm jį iš ten pasiimti.
fscanf(fp,"%d",&buf) veikia lygiai taip pat, kaip paprastas scanf, tik jos pradžioje nurodoma failo, iš kurio norime pasiimti informaciją, rodyklė.

Na lyg ir viskas būtų. Jeigu dar kas neaišku, klausk.
Never argue with an idiot. They bring you down to their level and beat you with experience.

Vartotojo avataras
mrg
garbės narys
garbės narys
Pranešimai:229
Užsiregistravo:2006 02 07 20:14

#8 Standartinė mrg » 2006 12 16 23:33

Tik niekaip nesuprantu kam naudojamas do while operatorius, jei ivykdo funkcija, o po to tikrinama salyga. Kur ta komanda gali praversti? Kur ji naudojama?

rand
nuolatinis dalyvis
nuolatinis dalyvis
Pranešimai:28
Užsiregistravo:2006 08 13 18:06

#9 Standartinė rand » 2006 12 17 01:07

Na tas do kodo segmentas bus vykdomas kol while salyga bus TRUE(neskaitan pirmojo karto)


Na turbut bereiksme situacija ir nelabai naudojama, bet kaip pavyzdys tai tiks ;]

Kodas: Pasirinkti visus

int a;
a = 1;
do {
printf("%d", a);
a++;
}while(a<10);
outputas bus:
1
2
3
4
5
6
7
8
9
pakeitus a i didsni skaiciu uz 10, tiesiog ji isprintins ir baigs darba nes nebeatitiks while salyga...


Kur panaudoti tai priklauso nuo tavo fantazijos :)


pvz.:
A common use of the do loop is to read disk files. This code will read a fine until and EOF (end of file) is encountered.

do
{
ch = getc(fp);
if (!eof(fp)) printf("%c", ch);
}while (!eof(fp));

Vartotojo avataras
GODhack
profesionalas
profesionalas
Pranešimai:4469
Užsiregistravo:2005 03 18 21:13
Susisiekti:

#10 Standartinė GODhack » 2006 12 17 01:16

mrg rašė:Tik niekaip nesuprantu kam naudojamas do while operatorius, jei ivykdo funkcija, o po to tikrinama salyga. Kur ta komanda gali praversti? Kur ji naudojama?
Skonio reikalas, tikriausiai visada galima issisukti ir be "do while".
Tiesiog su tokia komanda lengviau persiteikia mintis rasant kode daryti...trampampam...kol...kaskas. Ne visada patogu kodijant galvoti apie salygas dar pries rasant veksmus.
Nepatikti blogiems - girtinas dalykas. SENEKA
__________________________________________
progenic.com
library.2ya.com
Paveikslėlis

Vartotojo avataras
oxigen
mega dalyvis
mega dalyvis
Pranešimai:803
Užsiregistravo:2006 03 21 15:48
Miestas:Klaipėda
Susisiekti:

#11 Standartinė oxigen » 2007 02 18 19:43

Aš kad nekurti naujos temos parašysiu čia. Mokausi šiuo metu c++ ir vat knygoje yra tokia užduotis :

parašykite masyvo rikiavimo funkciją, panaudodami "minimakso" algoritmą, kuriame naudojami tokie masyvo tvarkymo principai :
- iš pradžių laikoma, kad nesurikiuota dalis užima visą masyvą;
- rikiavimas vykdomas žingsniais, kurie formuoja dvi surikiuotas sritis : vieną - masyvo pradžioje ir kitą - gale;
- kiekviename žingsnyje nesurikiuotoje dalyje randami elementai su didžiausia reikšme, kuris sukeičiamas su galiniu;
- sutvarkyti galinis ir pradinis elementai atmetami iš nesurikiuotos dalies, o rikiavimas baigiamas tada, kai nesurikiuotoje dalyje nebelieka elementų;

Nelabai įsivaizduoju kaip tai aprašyto programavimo kalba. Nes nėra knmygoje jokių masyvo dalinimo pavyzdžių ar ko panašaus... Tad gal betn kas galėtų pasakyti kaip maždaug čia ką daryti.

P.S. Google žiūrėjau ieškojau to algoritmo, bet neradau :/
Mokausi ir noriu išmokti
-
Veni, vidi, vici
Multa paucis
Errare humanum est
Divide et impera!

Skelbti atsakymą

Grįžti į

Dabar prisijungę

Vartotojai naršantys šį forumą: 1 ir 0 svečias(ių)