Dwie funkcje napisane w C.

0

Pierwsza funkcja oblicza wartość dla danego wielomianu. Dla funkcji kwadratowej, pierwszy element tablicy z numerem 0 to współczynnik c, drugi element to współczynnik b, trzeci to a. Ostatnim argumentem jest ilość elementów w tablicy. Druga funkcja o nazwie "derivative" oblicza określoną wartość dla pochodnej podanego wielomianu. Co o tym myślicie? Działać to działa ale czy dałoby się to lepiej napisać?

#include <stdio.h>
#include <math.h>
double func(const double* data, const double value, int elements)
{
   double ToReturn=0;
   for(int i=0; i<elements; ++i)
       ToReturn+=pow(value, i)*data[i];
   return ToReturn;
}
double derivative(const double* data, const double value, int elements)
{
   double ToReturn=0;
   for(int i=1; i<elements; ++i)
       ToReturn+=pow(value, i-1)*data[i]*i;
   return ToReturn;
}
int main(void)
{
   double tab[]={2, -3, 4, -5};
   for(int i=-3;i<=3;++i)
       printf("f(%d) = %f\n", i, func(tab, i, 4));
   printf("\n");
   for(int i=-3;i<=3;++i)
       printf("f'(%d) = %f\n", i, derivative(tab, i, 4));
   return 0;
}
3
  1. Słabe nazewnictwo — func nie jest dobrą nazwą dla funkcji, podobnie nazwy argumentów niewiele mówią. Sam fakt, że musisz coś tłumaczyć w temacie zamiast tylko pokazać kod jest dobrym indykatorem, że kod mógłby być czytelniejszy.
  2. Pisałbym raczej double toReturn = 0.0.
  3. Uważam, że nawet jednolinijkowe instrukcje w pętlach czy instrukcjach warunkowych powinny być otoczone klamrami.
2
  1. Wybiórcze używanie const - argument elements nie jest modyfikowany w żadej z funkcji, ale mimo to nie jest oznaczony jako const.

  2. Kontynuując powyższe - nie przesuwasz wskażnikow data, zatem one też mogłyby być const. Masz "const double *data", czyli "wskaźnik na stały double" - możesz zastosować "const double *const data", wtedy będziesz miał "stały wskaźnik na stały double". (Opcja trzecia, czyli "stały wskaźnik na double", to "double *const data").

  3. Kwestia stylu, ale zgadzam się z człowiekiem wyżej - krótkie instrukcje w ifach/pętlach albo pozostają w tej samej linii, co warunek, albo stosujemy klamry. Stąd prosta droga do bugów typu goto fail;.

0

Dzięki za sugestie.
@Althorion To po prostu jakaś powszechna praktyka, że nazwy zmiennych pisze się z małej litery oraz jak jest typ zmiennoprzecinkowy to nadaje mu się wartość 0.0?

0

Nazewnictwo jest kwestią konwencji, zależną od projektu. Zwyczajowo nazwy zaczynające się od wielkich liter są zarezerwowane dla klas. Wybór konkretnej konwencji jest mało istotny, ale jej bezwzględne trzymanie się już wręcz przeciwnie — jest absolutnie niezbędne.

0 to dla kompilatora int, 0.0 to double. Trochę lepiej jest dostarczać mu od razu wartość odpowiedniego typu. Tzn. kompilatorowi to nie robi różnicy, ale jest czytelniej dla ludzi. Przy czym różnica jest doprawdy niewielka.

0

Zamiast ciągłego wywoływania pow(value, i) możesz stworzyć dodatkowa zmienną
pow_value = 1.0;
i w każdej iteracji robić pow_value*=value;
Dla małych wielomianów wiele to nie zmieni, ale im stopień będzie wyższy tym bardziej to odczujesz w wydajności.

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