Program w C

0

Cześć, moglibyście mi powiedzieć czy ten program jest dobrze napisany? Mam na studiach zrobić projekt o obliczaniu BMI i nie tylko, więc zrobiłem to tylko jestem kompletnie początkującym więc nie mam pewności czy jest to dobrze i w miarę optymalnie napisany program. Będę wdzięczny za pomoc.

Treść zadania:
Cel: Nauka implementacji prostych programów liniowych, nauka implementacji programów z warunkiem,
poznanie różnych typów zmiennych w języku C, opracowanie pierwszego użytkowego programu

BMI Body mass index – jest to wskaźnik pozwalający określić czy występuje zagrożenie chorobami związanymi z
nadwagą oraz otyłością (np. nowotwory, cukrzyca, nadciśnienie)
Formuła Mifflina-St Jeor’a pozwala obliczyć BMR (Basal Metabolic Rate) na podstawie masy ciała, informacji o płci,
wzroście i wieku użytkownika. W języku polskim BMR oznacza się jako PPM (Podstawowa Przemiana Materii) i
wskazuje on najmniejsze dzienne zapotrzebowanie kaloryczne, która pozwala na utrzymanie podstawowych funkcji
życiowych.
Szacuje się, że aż 25% energii PPM zużywane jest na pracę układu nerwowego, podczas gdy zaledwie niespełna 7%
zużywane jest na pracę serca.
BAF – współczynnik aktywności fizycznej jest czynnikiem skalującym BMR. Określa się go na podstawie dziennej
aktywności fizycznej. Jego wartości są następujące (źródło):
Sedentary = 1.2 (little or no exercise, desk job)
Lightly active = 1.375 (light exercise/ sports 1-3 days/week)
Moderately active = 1.55 (moderate exercise/ sports 6-7 days/week)
Very active = 1.725 (hard exercise every day, or exercising 2 xs/day)
Extra active = 1.9 (hard exercise 2 or more times per day, or training for
marathon, or triathlon, etc.
Dzienne zapotrzebowanie kaloryczne (TDEE) równe jest BMR x BAF
Żeby schudnąć bądź przytyć należy w pierwszym kroku odjąć lub dodać 7.5% zapotrzebowania kalorycznego, a
następnie po upływie dwóch tygodni należy wykonać ponowną kalkulację. Pamiętać należy, iż zdrowe tempo zmiany
wagi to różnica 0.5 kg/tydzień.
W zbilansowanej diecie należy spożywać pomiędzy 0.9g a 1.5g białka na kilogram masy ciała (przyjmij do obliczeń
1.1g/kg). Węglowodany powinny stanowić 50% zapotrzebowania energetycznego, a tłuszcze powinny stanowić
pozostałość.
Napisz program w języku C, który pozwoli obliczyć dzienne zapotrzebowanie energetyczne dla użytkownika według
wzoru Mifflina-St Jeor’a oraz wskazanego przez niego BAF (Basic Activity Factor). Program na podstawie wskaźnika
BMI użytkowania zdecyduje o tym, czy należy nie modyfikować TDEE lub czy należy odjąć/dodać 7.5%
zapotrzebowania energetycznego. Program ma wyświetlić w konsoli następujące informacje:

  1. Wartość wskaźnika BMI
  2. Informację tekstową z przedziałami BMI
  3. Notkę informującą o zależności pomiędzy nieprawidłowym BMI a zachorowaniem na nowotwory
  4. BMR w kcal
  5. TDEE w kcal w 3 wariantach (schudnięcie/utrzymanie wagi/przytycie)
  6. Podział na makroskładniki (podobnie jak w punkcie 6)

Mój projekt (z tego co widzę to źle mi oblicza BMI jednak nie wiem, gdzie popełniłem błąd, bo wzoru użyłem dobrego):

#include <stdio.h>

int main()
{
	int masa;
	int wzrost;
	int wiek;
	float BMI;
	char plec;
	float BMR;
	float TDEE;
	float bialka;
	float weglowodany;
	float tluszcze;
	float bialkakcal;
	float weglowodanykcal;
	float tluszczekcal;
	int tryb_zycia;
	printf("Podaj mase ciala w kg:\n");
	scanf_s("%i", &masa);
	printf("Podaj swoj wzrost w cm:\n");
	scanf_s("%i", &wzrost);
	printf("Podaj swoj wiek:\n");
	scanf_s("%i", &wiek);
	BMI = masa / ((wzrost/100) * (wzrost/100));
	printf("Twoje BMI wynosi: %f", BMI);
	if (BMI < 16)
	{
		printf("\nTwoje BMI jest mniejsze niz 16\nMasz niedowage, jestes w kategorii wyglodzenia");
	}
	if (BMI >= 16 && BMI < 17)
	{
		printf("\nTwoje BMI jest mniejsze niz 17\n Jestes w kategorii wychudzenia");
	}
	if (BMI >= 17 && BMI < 18.5)
	{
		printf("\nTwoje BMI jest mniejsze niz 18,5\n Jestes w kategorii niedowagi");
	}
	if (BMI >= 18.5 && BMI < 25)
	{
		printf("\nTwoje BMI jest mniejsze niz 25 i wieksze lub rowne 18,5\n Masz pozadana mase ciala");
	}
	if (BMI >= 25 && BMI < 30)
	{
		printf("\nTwoje BMI jest wieksze lub rowne 25\n Masz nadwage");
	}
	if (BMI >= 30 && BMI < 35)
	{
		printf("\nTwoje BMI jest wieksze lub rowne 30\n Masz otylosc 1 stopnia");
	}
	if (BMI >= 35 && BMI < 40)
	{
		printf("\nTwoje BMI jest wieksze lub rowne 35\n Masz otylosc 2 stopnia");
	}
	if (BMI >= 40)
	{
		printf("\nTwoje BMI jest wieksze lub rowne 40\n Masz otylosc 3 stopnia");
	}
	printf("\nNadwaga i otylosc sa uznanymi czynnikami zwiekszajacymi ryzyko\n zachorowanie na choroby ukladu krazenia oraz narzadu ruchu.\n Badania ostatnich lat wykazaly, ze zwiekszaja takze ryzyko rozwoju chorob\n nowotworowych. Wiele badan prowadzonych w ostatnich latach udokumentowalo zwiazek miedzy otyloscia,\n a wystapieniem choroby nowotworowej. Wedlug raportu World Cancer Research Fund otylosc zwieksza\n ryzyko rozwoju wielu nowotworow przewodu pokarmowego, takich jak: rak jelita grubego, gruczolakorak\n przelyku i wpustu, rak trzustki i pecherzyka zolciowego oraz rak watroby. W celu zmniejszenia ryzyka\n wystapienia choroby nowotworowej nalezy zastosowac odpowiednia profilaktyke i leczenie otylosci.\n Najbardziej skuteczna metoda leczenia skrajnej otylosci jest chirurgia bariatryczna.");
	printf("\nJestes kobieta, czy mezczyzna (Podaj odpowiedz K lub M)");
	scanf_s(" %c", &plec);
	if (plec == 'k' || plec == 'K')
	{
		BMR = ((9.99 * masa) + (6.25 * wzrost) - (4.92 * wiek) - 161);
		printf("\nTwoje BMR wynosi %f kcal", BMR);
	}
	if (plec == 'm' || plec == 'M')
	{
		BMR = ((9.99 * masa) + (6.25 * wzrost) - (4.92 * wiek) + 5);
		printf("\nTwoje BMR wynosi %f kcal", BMR);
	}
	printf("\nPodaj cyfre odpowiadajaca twojemu trybowi zycia:\n1.Siedzacy(Sedentary)- male ilosci lub calkowity brak cwiczen\n2.Lekko aktywny(Lightly active)- lekkie cwiczenia 1-3 razy na tydzien\n3.Umiarkowanie aktywny(Modarately active)- umiarkowane cwiczenia 6-7 razy w tygodniu\n4.Bardzo aktywny(Very active)- ciezkie cwiczenia kazdego dnia lub trenowanie 2 razy na dzien\n5.Ekstra aktywny(Extra active)- ciezkie cwiczenia 2 lub wiecej razy na dzien lub trenowanie do maratonu thriatlonu\n");
	scanf_s("%i", &tryb_zycia);
	if (tryb_zycia == 1)
	{
		TDEE = 1.2 * BMR;
	}
	if (tryb_zycia == 2)
	{
		TDEE = 1.375 * BMR;
	}
	if (tryb_zycia == 3)
	{
		TDEE = 1.55 * BMR;
	}
	if (tryb_zycia == 4)
	{
		TDEE = 1.725 * BMR;
	}
	if (tryb_zycia == 5)
	{
		TDEE = 1.9 * BMR;
	}
	printf("Twoje TDEE wynosi %f kcal\n", TDEE);
	if (BMI < 18.5)
	{
		TDEE = TDEE + (TDEE * 0.075);
		printf("Masz niedowage w stosunku do prawidlowej masy ciala\n Zwieksz dzienne zapotrzebowanie kaloryczne TDEE do %f kcal\n", TDEE);
		printf("Wroc za 2 tygodnie by sprawdzic swoje postepy\n  Pamietaj ze zdrowe tempo zmiany wagi to roznica 0,5 kg na tydzien");
	}
	if (BMI >= 25)
	{
		TDEE = TDEE - (TDEE * 0.075);
		printf("Masz nadwage w stosunku do prawidlowej masy ciala\n Zmniejsz dzienne zapotrzebowanie kaloryczne TDEE do %f kcal\n", TDEE);
		printf("Wroc za 2 tygodnie by sprawdzic swoje postepy\n  Pamietaj ze zdrowe tempo zmiany wagi to roznica 0,5 kg na tydzien");

	}
	if (BMI >= 18.5 && BMI < 25)
	{
		printf("Masz poprawną masę ciała trzymaj sie aktualnego TDEE\n");
		printf("Wroc za 2 tygodnie by zobaczyc czy twoje zapotrzebowanie kaloryczne musi ulec zmianie");
	}
	bialka = masa * 1.1;
	bialkakcal = bialka * 4;
	weglowodany = (TDEE / 2) / 4;
	weglowodanykcal = weglowodany * 4;
	tluszczekcal = TDEE - bialkakcal - weglowodanykcal;
	tluszcze = tluszczekcal / 9;
	printf("\nIlosc makroskladnikow jakie powinno sie dostarczac do organizmu, zakladajac ze\n 1g bialka zapewnia 4 kcal, 1g tluszczu zapewnia 9kcal, 1g weglowodanow zapewnia 4kcal:\n bialka- %f g (%f kcal)\nweglowodany- %f g (%f kcal)\ntluszcze-  %f g (%f kcal)\n", bialka, bialkakcal, weglowodany, weglowodanykcal, tluszcze, tluszczekcal);
	return 0;
}
5
  1. Więcej funkcji, to naprawdę pomaga nie tylko czytać, ale też w razie czego testować kod.
  2. TDEE można obliczyć używając prostej tablicy zamiast drabinki ifów
  3. Używaj angielskich nazw zmiennych, dodatkowo snake_case lub camelCase ułatwia czytanie.
  4. UPPER_CASE jest z reguły zarezerwowane dla stałych.
  5. Jeśli nie musisz, to nie używaj float tylko dobule. Często może kod się wtedy wykonywać szybciej.
  6. wzrost/100 zwróci Ci coś innego niż się spodziewasz, przez to BMI też będzie miało inną wartość niż oczekujesz.
  7. L62-71 można bardzo łatwo zrefactorować by nie mieć powtórzeń.
  8. L94-112 tak samo.
  9. Nie masz zabezpieczeń przed błędnymi danymi. Co się stanie jak tryb_zycia będzie równe 6? Albo plec będzie równe z?
2

Całkiem, całkiem. Zgadza się, że możesz zastąpić sekwencję ifów pętlą, jeśli progi i komunikaty umieścisz w tablicy (warto byłoby użyć struktury). Służba uwaga co do dzielenia, wykonywane na dwóch intach, zaokrągla w dół. Aby tego uniknąć powinieneś zrobić rzutowane. Poza tym lepiej definiuj zmienne tam gdzie zaczynają być potrzebne. Definiowanie wszystkiego na początku funkcji to dawno nieaktualne ograniczenie. Też słuszność co do nazw i wydzielania funkcji.

Co do sprawdzania poprawności, to jest istotna umiejętność. Możesz na przykład napisać testy.

2
  1. Usun '&&' i '||'.
  2. naucz sie uzywac else if
  3. naucz sie dzielic lancuchy na linie, program dobrze jesli miesci sie w 80 - 100 kolumnach
0

Wiem, że mógłbym lepiej napisać ten program z używaniem innych funkcji od if ale prowadzący powiedział, żeby w tym zadaniu były tylko ify bez pętli while itd. więc musi zostać tak jak jest. Ale dzięki za wytłumaczenie tego wszystkiego. Mam takie pytanie, to co mam napisać zamiast tego "wzrost/100" żeby mi poprawnie obliczało BMI?

0

Zamiast kaskady if'ów:

static struct { double value; const char *text; } BmiTb[]=
{
	{16.0,"Masz niedowage, jestes w kategorii wyglodzenia"},
	{17.0,"Jestes w kategorii wychudzenia"},
	{18.5,"Jestes w kategorii niedowagi"},
	{25.0,"Masz pozadana mase ciala"},
	{30.0,"Masz nadwage"},
	{35.0,"Masz otylosc 1 stopnia"},
	{40.0,"Masz otylosc 2 stopnia"},
	{99.9,"Masz otylosc 3 stopnia"},
	{1E9,"Niepoprawne dane"},
};
static size_t BmiTbSize=sizeof(BmiTb)/sizeof(*BmiTb);

size_t p=0;
for(p=0;(p+1<BmiTbSize)&&(BmiTb[p].value<bmi);++p) {}
printf("%s\n",BmiTb[p].text);

1 użytkowników online, w tym zalogowanych: 0, gości: 1