• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Średnia arytmetyczna - ANSI C

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
1,165 wizyt
pytanie zadane 30 października 2018 w C i C++ przez gorgonkowa Obywatel (1,810 p.)

Hejka. :)
Chciałabym się Was poradzić, jak można w tym kodzie źródłowym zrobić średnią arytmetyczną? Wydaje mi się, że nie do końca kumam jak to zrobić. Czy mogłabym poprosić o sprawdzenie i wytłumaczenie co jest nie tak? Byłabym bardzo wdzięczna. :)
Kod C:
 

#include <stdio.h>
#include <stdlib.h>


typedef struct
{
    char nazwisko[20], imie[20];
    int rok_ur;
    float srednia;
}TDane;

typedef struct
{
    TDane d;
    struct TElement* next;
}TElement;

typedef TElement* TWsk;

int main()
{
    TWsk P;
    TDane x;
    P=NULL;
    WprowadzDane(&P);
    printf("Wprowadzone dane to: \n");
    UsunStos(&P);
    return 0;
}

int WprowadzStudenta(TDane *x)
{
    printf("Podaj nazwisko: ");
    scanf("%s", x->nazwisko);
    printf("Podaj imie: ");
    scanf("%s", x->imie);
    printf("Podaj rok urodzenia: ");
    scanf("%d", &x->rok_ur);
    printf("Podaj srednia: ");
    scanf("%f", &x->srednia);
    return 0;
}

int WyswietlStudenta(TDane x)
{
    printf("%s %s %d %4.2f \n", x.nazwisko, x.imie, x.rok_ur, x.srednia);
    return 0;
}

int NaStos(TWsk *P, TDane x)
{
    TWsk Q;
    Q = (TElement*)malloc(sizeof(TElement));
    Q->d=x;
    Q->next=(*P);
    (*P) = Q;
    return 0;
}

int ZeStosu(TWsk *P, TDane *x)
{
    TWsk Q;
    if(P!=NULL)
    {
        Q=(*P);
        *x=Q->d;
        *P=Q->next;
        free(Q);
    }
    return 0;
}

int WprowadzDane(TWsk *P)
{
    int n, i;
    TDane x;
    printf("Dane ilu osob chcesz wprowadzic?: ");
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        printf("%d osoba", i);
        WprowadzStudenta(&x);
        NaStos(&(*P), x);
    }
    return 0;
}

int UsunStos(TWsk *P)
{
    TDane x;
    while((*P)!=NULL)
    {
        ZeStosu(&(*P), &x);
        WyswietlStudenta(x);
    }
    return 0;
}

int WyswietlStos(TWsk P)
{
    while(P!=NULL)
    {
        WyswietlStudenta(P->d);
        P=P->next;
    }
    return 0;
}

float srednia(TWsk *P, TDane x)
{
    float n;
    printf("Srednia to: %1f", (x.srednia)/n);
    return 0;
}

 

1 odpowiedź

+1 głos
odpowiedź 31 października 2018 przez Bondrusiek Maniak (61,440 p.)

Witam,

wydaje mi się że tu jest problem

float srednia(TWsk *P, TDane x)
{
    float n;
    printf("Srednia to: %1f", (x.srednia)/n);
    return 0;
}

Zauważ że n nie jest zdefiniowanie i w tej zmiennej losowa wartość. Musisz utworzyć jeszcze dwie zmienne pomocnicze, które określą sumę średnich oraz ilość danych np:

float srednia(TWsk *P, TDane x)
{
    float srednia = suma_srednich / ilosc_danych;
    printf("Srednia to: %1f", srednia);
    return srednia;
}

 

komentarz 31 października 2018 przez gorgonkowa Obywatel (1,810 p.)

Hmm utworzyłam coś takiego:
 

float srednia(TWsk *P, TDane x)
{
    float suma_srednich[WprowadzStudenta(x.rok_ur)];
    float ilosc_danych[WprowadzDane(P->n)];
    float srednia = suma_srednich / ilosc_danych;
    printf("Srednia to: %1f", srednia);
    return srednia;
}

Jednak chyba już za bardzo mieszam z tymi wskaźnikami i czym dalej coś spróbuję zmienić, tym więcej błędów :/

komentarz 31 października 2018 przez Bondrusiek Maniak (61,440 p.)

Wydaje mi się że powinieneś zrobić coś w tym stylu.

float srednia(TWsk *P)
{
    float suma_srednich = 0;
    int ilosc = 0;
    while( P != NULL){
      suma_srednich = P->d.srednia;
      P = P->next;
      ++ilosc;
    }
    float retVal = 0.f;
    if( ilosc != 0){
      retVal = suma_srednich/ ilosc;
    }
    return retVal;
}

PS.

Jak masz wskaźnik to do elementów odwołujesz się poprzez -> a w przypadku obiektu wykorzystujesz kropkę .

komentarz 31 października 2018 przez gorgonkowa Obywatel (1,810 p.)
Hmm rozumiem :) Cóż, jeśli w głównej funkcji jest (TWsk *P) to wyskakują 2 errory, a próbując bez gwiazdki, czyli (TWsk P), program włącza się mimo 7 warningów, jednak tak jakby w ogóle nie wyświetlał funkcji średniej. Czyli użytkownik podaje ilość wprowadzonych danych, potem dane personalne, a gdy zakończy pętlę to wówczas nic się nie dzieje. Czy należy do tej funkcji w środek głównego "int main()" jakoś ją wprowadzić? Sama funkcja główna jest INT, a średnia arytmetyczna to funkcja float, stąd nie wiem, czy można coś zrobić żeby jednak działała w konsoli :P
komentarz 31 października 2018 przez Bondrusiek Maniak (61,440 p.)
edycja 31 października 2018 przez Bondrusiek

Widzę że masz pewne braki wiedzy z dziedziny funkcji w C++. Doczytaj sobie

http://cpp0x.pl/kursy/Kurs-C++/Poziom-2/Funkcje-pierwsze-starcie/291

Jeśli funkcja nic nie zwraca to możesz pominąć funkcje return wartość. Możesz również przerwać taką funkcję samym return.

void WprowadzDane(TWsk *P) // void czyli funkcja nic nie zwraca
{
    int n, i;
    TDane x;
    printf("Dane ilu osob chcesz wprowadzic?: ");
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        printf("%d osoba", i);
        WprowadzStudenta(&x);
        NaStos(&(*P), x);
    }
    // nie potrzeba tu return 0;
}

Spróbuj dodać funkcje srednia w main.

np.

    TWsk P;
    TDane x;
    P=NULL;
    WprowadzDane(&P);
    printf("Srednia %2", srednia(&P) );

 

komentarz 31 października 2018 przez gorgonkowa Obywatel (1,810 p.)
Masz rację, moja wiedza jest na prawie żadnym poziomie, a uczę się każdego kodu na pamięć, ponieważ nie jest to związane z przyszłością i próbuję tylko każdy semestr studiów związany z językiem C popchnąć dalej. :P
Wracając do tematu, dodając printf w głównym int main() wyskakuje w kompilatorze błąd: "conflicting types for 'srednia' ". Hmm... Czy da się jakoś zapisać tego float w int? Co można zrobić z takim czymś?
PS. Z góry przepraszam za moją niewiedzę, bardzo chcę się nauczyć, jednak jestem typem człowieka, który ma trudność w przyswajaniu wiedzy, stąd nauka na pamięć. Jedni potrafią w 5 minut coś załapać, u mnie to trwa ponad 20 godzin.
komentarz 31 października 2018 przez Bondrusiek Maniak (61,440 p.)
Spoko. Ważne że próbujesz. Musisz być cierpliwa i starać się uporządkować wiedzę wtedy dużo łatwiej będzie Ci się uczyć. Widzę że teraz u Ciebie konflikt nazw. Musisz czytać błędy/ostrzeżenia kompilatora wtedy będzie łatwiej rozwiązać problem. Tu już można się domyślić : "conflicting types for 'srednia' .

Wklej jeszcze raz kod bo już coś tam dopisałaś wtedy będzie łatwiej ogarnąć i pomóc.
komentarz 31 października 2018 przez gorgonkowa Obywatel (1,810 p.)

Dziękuję :) i jeszcze raz przepraszam. Staram się, mimo błędów w końcu wyjdzie, jednak jak każda osoba potrzebuje też to ogarnąć w głowie. Em... Kod teraz wygląda następująco:
 

#include <stdio.h>
#include <stdlib.h>


typedef struct
{
    char nazwisko[20], imie[20];
    int rok_ur;
    float srednia;
}TDane;

typedef struct
{
    TDane d;
    struct TElement* next;
}TElement;

typedef TElement* TWsk;

int main()
{
    TWsk P;
    TDane x;
    P=NULL;
    WprowadzDane(&P);
    printf("Srednia %2", srednia(*P));
    printf("Wprowadzone dane to: \n");
    UsunStos(&P);
    return 0;
}

int WprowadzStudenta(TDane *x)
{
    printf("Podaj nazwisko: ");
    scanf("%s", x->nazwisko);
    printf("Podaj imie: ");
    scanf("%s", x->imie);
    printf("Podaj rok urodzenia: ");
    scanf("%d", &x->rok_ur);
    printf("Podaj srednia: ");
    scanf("%f", &x->srednia);
    return 0;
}

int WyswietlStudenta(TDane x)
{
    printf("%s %s %d %4.2f \n", x.nazwisko, x.imie, x.rok_ur, x.srednia);
    return 0;
}

int NaStos(TWsk *P, TDane x)
{
    TWsk Q;
    Q = (TElement*)malloc(sizeof(TElement));
    Q->d=x;
    Q->next=(*P);
    (*P) = Q;
    return 0;
}

int ZeStosu(TWsk *P, TDane *x)
{
    TWsk Q;
    if(P!=NULL)
    {
        Q=(*P);
        *x=Q->d;
        *P=Q->next;
        free(Q);
    }
    return 0;
}

int WprowadzDane(TWsk *P)
{
    int n, i;
    TDane x;
    printf("Dane ilu osob chcesz wprowadzic?: ");
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        printf("%d osoba", i);
        WprowadzStudenta(&x);
        NaStos(&(*P), x);
    }
    return 0;
}

int UsunStos(TWsk *P)
{
    TDane x;
    while((*P)!=NULL)
    {
        ZeStosu(&(*P), &x);
        WyswietlStudenta(x);
    }
    return 0;
}

int WyswietlStos(TWsk P)
{
    while(P!=NULL)
    {
        WyswietlStudenta(P->d);
        P=P->next;
    }
    return 0;
}

float srednia(TWsk *P)
{
    float suma_srednich = 0;
    int ilosc = 0;
    while( P != NULL){
      suma_srednich = P->d.srednia;
      P = P->next;
      ++ilosc;
    }
    float retVal = 0.f;
    if( ilosc != 0){
      retVal = suma_srednich/ ilosc;
    }
    return retVal;
}

I pokazują się następujące przy tym błędy:
1) conflicting types for 'srednia'
2) note: previous implicit declaration of 'srednia' was here - dotyczy dodanego printf do int main()
3) request for member 'd' in something not a structure or union
4) request for member 'next' in something not a structure or union - dotyczą linijek:
 

while( P != NULL){
      suma_srednich = P->d.srednia;
      P = P->next;
      ++ilosc;
    }
komentarz 31 października 2018 przez Bondrusiek Maniak (61,440 p.)

Poprawiłem Twój kod. Wykorzystałem zmienne/funkcje statyczne. Można również wykorzystać zmienne/funkcje globalne do tego zadania. Jest jeszcze błąd w funkcji UsunStos gdyż wywala mi błąd. Mój poprawiony kod:

#include <stdio.h>
#include <stdlib.h>


struct TDane
{
    char nazwisko[20], imie[20];
    int rok_ur;
    float srednia;
    static float suma_sr;
    static int ilosc_sr;
    static float zwroc_srednia();
};

float TDane::suma_sr = 0.f;
int TDane::ilosc_sr = 0;
float TDane::zwroc_srednia()
{
    if(ilosc_sr == 0)
    {
        return 0.f;
    }

    return suma_sr / ilosc_sr;
}

struct TElement
{
    TDane d;
    struct TElement* next;
};

typedef TElement* TWsk;

void WprowadzStudenta(TDane *x);
void WyswietlStudenta(TDane x);
void NaStos(TWsk *P, TDane x);
void ZeStosu(TWsk *P, TDane *x);
void WprowadzDane(TWsk *P);
void UsunStos(TWsk *P);
void WyswietlStos(TWsk P);
float srednia(TWsk *P, TDane x);



int main()
{
    TWsk P;
    TDane x;

    WprowadzDane(&P);
    printf("Wprowadzone dane to: \n");
    printf("//////////////////////////////////////////////////////////////\n");
    printf("Srednia to : %f", TDane::zwroc_srednia());


    return 0;
}

void WprowadzStudenta(TDane *x)
{
    printf("Podaj nazwisko: ");
    scanf("%s", x->nazwisko);
    printf("Podaj imie: ");
    scanf("%s", x->imie);
    printf("Podaj rok urodzenia: ");
    scanf("%d", &x->rok_ur);
    printf("Podaj srednia: ");
    scanf("%f", &x->srednia);
//Tutaj dodajemy srednia
    TDane::suma_sr += x->srednia;
    ++TDane::ilosc_sr;
}

void WyswietlStudenta(TDane x)
{
    printf("%s %s %d %4.2f \n", x.nazwisko, x.imie, x.rok_ur, x.srednia);
}

void NaStos(TWsk *P, TDane x)
{
    TWsk Q;
    Q = (TElement*)malloc(sizeof(TElement));
    Q->d=x;
    Q->next=(*P);
    (*P) = Q;
}

void ZeStosu(TWsk *P, TDane *x)
{
    TWsk Q;
    if(P!=NULL)
    {
        Q=(*P);
        *x=Q->d;
        *P=Q->next;
        free(Q);
    }

}

void WprowadzDane(TWsk *P)
{
    int n, i;
    TDane x;
    printf("Dane ilu osob chcesz wprowadzic?: ");
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        printf("%d osoba\n", i);
        WprowadzStudenta(&x);
        NaStos(&(*P), x);
    }

}

void UsunStos(TWsk *P)
{
    TDane x;
    while((*P)!=NULL)
    {
        ZeStosu(&(*P), &x);
        WyswietlStudenta(x);
    }
}

void WyswietlStos(TWsk P)
{
    while(P!=NULL)
    {
        WyswietlStudenta(P->d);
        P=P->next;
    }
}

float srednia(TWsk *P, TDane x)
{
    float n;
    printf("Srednia to: %1f", (x.srednia)/n);
    return 0;
}

Możesz sobie doczytać:

https://pl.wikipedia.org/wiki/Zmienna_statyczna

http://strefakodera.pl/programowanie/c/instrukcja-typedef-w-c

Podobne pytania

0 głosów
0 odpowiedzi 599 wizyt
pytanie zadane 16 czerwca 2018 w C i C++ przez fruczka Użytkownik (570 p.)
0 głosów
1 odpowiedź 981 wizyt
pytanie zadane 14 lipca 2019 w C i C++ przez Padomen Początkujący (260 p.)
0 głosów
1 odpowiedź 307 wizyt
pytanie zadane 15 lutego 2019 w C i C++ przez Michał_Warmuz Mądrala (5,830 p.)

93,103 zapytań

142,077 odpowiedzi

321,562 komentarzy

62,445 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...