👤

Potrzebuje pomocy z programowaniem

Napisz funkcję, która otrzymuje dwa argumenty liczbę n oraz n –elementową tablicę tab o elementach typu int i zwraca jako wartość sumę elementów tablicy tab o indeksach parzystych (uznajemy, że 0 jest parzyste)

Ma być w c++


Odpowiedź :

Kod poniżej, dodatkowo załączyłem widok programu w pliku

#include<iostream>

#include<cstdlib>

using namespace std;

int funkcja(int n, int tab[])

{

int wynik=0;

for(int i=0;i<n;i+=2) wynik+=tab[i];

return wynik;

}

main()

{

int n = 5;

int tab[n]={0,69,420,2137,10000};  

cout<<funkcja(n,tab);

}

Zobacz obrazek SLAWEK080

Odpowiedź

Kolega szybko napisał program, a ja go w pewnym sensie tylko poprawiłam, upiększyłam i znajdziesz go w pierwszym załączniku.

Rozmiary tablic powinny być inicjalizowane stałymi, a nie zmiennymi. Ten typ tablic  ( w C++ jest wiele typów tablic! )  ma stały rozmiar, a tak jak w oryginale program został napisany to zmienna  n  mogłaby w programie przyjmować różne wartości. Zatem w drugim załączniku wersja z

   int const n = 5;

Popatrzywszy na ten konkretny program widać, że zmienna  tab  – po tym gdy są jej nadane wartości początkowe – nie ulega już żadnym zmianom. Tak więc ona też może (powinna!) być zadeklarowana jako zmienna, której wartości są stałe.

Z kolei popatrzywszy na argumenty funkcji widać, że nie są one dokładnie takimi samymi typami jak argumenty używane przy wywołaniu funkcji, a kompilatory tego bardzo nie lubią (bo mogą być ukryte błędy). To jest akurat bardzo prosta reguła, że deklaracje tych samych rzeczy powinny wyglądać tak samo... Wersja w trzecim załączniku z powyższej opisanymi zmianami

int funkcja(int const n, int const tab[]) {

   int const tab[n] = { 0, 69, 420, 2137, 10000 };

Z tym, że tylko najstarsza (archaiczna) wersja C++ z roku 1998 (C++98) tak działa. W przypadku współczesnych wersji C++, począwszy od roku 2011 (C++11, C++14, C++17, C++20 i nowsze) powinno być tak jak w czwartym załączniku i to tę wersję polecam!

   int constexpr n = 5;

Wyjaśnienie

Skopiowałam program z rozwiązania kolegi do Visual Studio i nawet się nie skompilował... Na początek postanowiłam go kosmetycznie poprawić w Code::Blocks, bo chyba tam było testowane rozwiązanie. Pierwszy załącznik:

  • wyrzuciłam nieużywany (a więc zbędny #include)
  • wstawiłam int jako wartość zwracaną przez main()
  • zamiast włączania całej biblioteki, włączyłam tylko te dwie funkcje, które są potrzebne, bo są używane cout oraz endl (tak, endl jest taką nietypową funkcją)
  • dostawiłam na końcu pustą linię (bo takie wymaganie mają kompilatory C++98)

I taki program się kompiluje używając clang oraz g++ przy użyciu standardów od C++98 do C++20.

Nieźle, ale w ogóle się nie kompiluje używając Visual Studio oraz kompilatora Intela (jest dostępny za darmo). Otóż to nie jest widzimisię kompilatorów tylko standard C++ wymaga aby zamiast

   int n = 5;

było

   int const n = 5;

co można zapisać (obie formy są poprawne)

   const int n = 5;

Wersja z drugiego załącznika kompiluje się wszędzie. Prawie sukces. :)

Popatrzyłam teraz na ostrzeżenia. Aby wyeliminować podstawowe ostrzeżenia (uwagi) kompilatorów stworzyłam trzecią wersję.

Okazało się jednak, że wersja trzecie nie generuje ostrzeżeń dla C++98, czyli dla bardzo starej. Aby uwspółcześnić stworzyłam wersję czwartą

   int constexpr n = 5;

Materiał zaawansowany

Czy to oznacza, że kompilatory nie emitują już żadnych ostrzeżeń?

Skądże znowu. :) Kompilatory ubolewają, że tak się nie powinno używać tablic w C++. Otóż zgodnie ze standardem języka C++ nie ma żadnych mechanizmów zabezpieczających taki rodzaj tablic przed używaniem indeksów tablic poza rozmiarem tablicy. Programista chcąc poprawnie używać takich tablic musi pisać zupełnie inaczej...

Zobacz obrazek 0AB
Zobacz obrazek 0AB
Zobacz obrazek 0AB
Zobacz obrazek 0AB

On Studier: Inne Pytanie