Diskuze: Průměr známek z více předmětů
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 6 zpráv z 6.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Nesedi ti slozene zavorky, posledni zavorka ti navazuje na prvni while (1) - takze int main() zustane neukoncena.
Mimodem, k cemu presne ma slouzit zadani "100"?
Chci docílit: Chci se proto zeptat zda to nejde jednodušeji než to stále kopírovat...
Samozřejmě že to jde, níže se můžeš inspirovat.
Program vypisuje průměry známek předmětů postupně po zadání
jednotlivých známek.
Pokud bychom chtěli vypisovat průměry naráz, všímej si částí s
komentáři.
Program z důvodu jednoduchosti postrádá validace vstupů.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
int pocet_predmetu;
int pocet_znamek_predmetu;
int znamka;
int soucet_znamek_predmetu;
printf("Zadej pocet predmetu: ");
scanf("%d", &pocet_predmetu);
if (pocet_predmetu <= 0){
printf("\nNeplatny pocet predmetu.\n");
printf("Nelze urcit prumer znamek.\n");
return 0;
}
// Zde by se dynamicky alokovalo 1D pole typu float o velikosti pocet_predmetu pomoci calloc()
for (int i = 0; i < pocet_predmetu; i++) {
printf("\nZadej pocet znamek %d. predmetu: ", i + 1);
scanf("%d", &pocet_znamek_predmetu);
if (pocet_znamek_predmetu <= 0) {
printf("\nNeplatny pocet znamek %d. predmetu.\n", i + 1);
printf("Nelze urcit prumer znamek tohoto predmetu.\n");
continue;
}
soucet_znamek_predmetu = 0;
for (int j = 0; j < pocet_znamek_predmetu; j++) {
printf("Zadej %d. znamku %d. predmetu: ", j + 1, i + 1);
scanf("%d", &znamka);
soucet_znamek_predmetu += znamka;
}
printf("\nPrumer znamek %d. predmetu: %.2f\n", i + 1, (float) soucet_znamek_predmetu / pocet_znamek_predmetu);
// Zde by se namisto vypisu na obrazovku do pole ukladala hodnota prumeru znamek na pozici i-teho indexu
}
// Zde by se z pole vypisovaly vsechny prumery znamek naraz
return 0;
}
ještě otázka,
šlo by to udělat vypisování průměrů více předmětů najednou úpravou
pomocí níže uvedeného příkazu za použití polí??
#include <stdio.h>
int main(int argc, char **argv)
{
int prg[15];//pole[0], pole[1], pole[2], pole[3], pole[4]
int i, pocet,suma = 0;
while(1){
printf("Zadej pocet znamek (max 15) pro konec zadej 100: ");
scanf("%d",&pocet);
if(pocet == 100)
break;
for(i = 0;i < pocet;i++){
printf("Zadej %d. prvek: ",i+1);
scanf("%d",&prg[i]);
suma = suma + prg[i];
}
printf("soucet znamek je %d\n",suma);
printf("prumer znamek je %.2lf\n",(double)suma/pocet);
//suma = 0;
}
return 0;
}
Děkuji přede za odpověď
šlo by to udělat vypisování průměrů více předmětů najednou úpravou pomocí níže uvedeného příkazu za použití polí??
Samozřejmě. Jen by to nebylo tak jednoduché jak uvádíš v příkladu výše, ve kterém házíš známky všech předmětů do jednoho pytle. Mohlo by to vypadat zhruba následovně:
V první řadě je třeba si to celé představit. V reálné aplikaci by vše bylo uloženo v datovém souboru odděleně, aby se mohl určit průměr známek pro ten daný předmět. V čase překladu nevíš, kolik je předmětů a kolik známek (pro zjištění počtu předmětů se provede analýza datového souboru, je samozřejmě možné si údaj o počtu předmětů z důvodu efektivity v souboru uchovávat). To znamená, že nelze použít staticky alokovaná pole. Ano, dopředu prozradím, že celé se to musí řešit dynamicky a že těch dynamicky alokovaných polí bude trochu více (v závislosti na počtu předmětů). Počty známek pro každý předmět může být různý. Celé si to lze představit jako zubaté 2D pole. Zjištěním počtu předmětu získáme první rozměr (počet řádků). První co se musí udělat je vytvořit dynamické 1D pole ukazatelů na typ int. Toto pole je třeba si představit jako první sloupec, který bude sloužit pro napojení dalších nově vytvořených 1D dynamicky alokovaných polí, jejichž velikost se odvíjí od počtu známek pro ten daný předmět. Počet nově vytvořených polí bude roven počtu předmětů. Prvky prvního (svislého) pole jsou ukazatele na začátky nově vytvořených polí. Tím se získá 2D pole, jehož velikost druhého rozměru je proměnlivá (zubaté 2D pole). Tímto vytváříme přesně paměťový prostor pro známky pro konkrétní předmět. Pro uložení rozměrů jednotlivých řádků si vytvoříme další dynamicky alokované pole o velikosti počtu předmětů, tentokrát typu int. Nyní máme vše co potřebujeme pro určení průměru známek pro daný předmět. Vytvořením for cyklu o počtu iterací rovno počtu předmětů, kde aktuální hodnota řídící proměnné pomáhá přistupovat k ukazateli na konkrétní pole, ve kterém sečteme všechny známky, kterých je hodnota na indexu aktuální hodnoty řídící proměnné u posledního dynamicky alokovaného pole. Podílem součtů známek a počtů známek pro každý řádek získáme průměry známek pro ten který předmět a tyto hodnoty vypíšeme.
V popisu jsem zmínil, že celé je to třeba řešit dynamicky a ne za pomocí statických polí. Někdo by namítnul a už jsem se s tím zde setkal, že by se jednoduše vytvořilo statické 2D pole o určitých rozměrech, empiricky stanovených, které by pro danou situaci bohatě stačilo.
Např.
#define POC_PREDMET 30
#define POC_ZNAMEK 50
unsigned char pole[POC_PREDMETU][POC_ZNAMEK];
Vytvoření statických polí je rychlejší než vytvoření polí dynamických. Celé by to bylo podstatně jednodušší, paměti je dost, nějakých POC_PREDMETU x POC_ZNAMEK x sizeof(unsigned char) bytů (1500) nás nevytrhne, je to přehlednější.
Ano, to vše je pravda, ale takovýto přístup je obecně špatně.
Na této jednoduché aplikaci to tolik nevadí, ale až se naučíš o C víc,
zjistíš, jak jsou tyto detaily důležité.
Zobrazeno 6 zpráv z 6.