Omówienie w jaki sposób działają programy wykorzystujące działanie pętli

0

Cześć, zaczynam swoją przygodę z programowaniem i natknąłem się na parę zadań wraz z rozwiązaniami. Niestety nie jestem w stanie zrozumieć niektórych przejść. Bardzo proszę o wytłumaczenie w jaki sposób działają poniższe programy, myślę że to lepiej pomoże mi zrozumienie programowania.
Bardzo proszę o wytłumaczenie jak działa cały program, tam gdzie są komentarze są pytania dodatkowe.

Zad1
Napisz program, który za pomocą instrukcji for znajduje największą i najmniejszą liczbę ze zbioru n wylosowanych liczb całkowitych od 0 do 99 (w zadaniu n=5) oraz oblicza średnią ze wszystkich liczb.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace pętle
{
    class Program
    {        
        
        static void Main(string[] args)
        {
            int ilosc_liczb = 5, i = 2; //dlaczego i = 2? Z czego to wynika?
            double liczba, suma = 0, min, max;            
            Console.WriteLine("Sumujemy, max, min i średnia");

            Random r = new Random(); //po co jest ten zapis?
            min = Math.Round(100 * (r.NextDouble())); //czemu zapis losowania liczby pseudolosowej jest zapisany w taki sposób? Z czego to wynika?
            Console.WriteLine();
            Console.Write("Wylosowano liczby: " + min + ", ");

            max = min;
            suma = suma + max;

            for (i = 2; i <= ilosc_liczb; i++)
            {
                liczba = Math.Round(100 *(r.NextDouble()));
                if (i < ilosc_liczb)
                    Console.Write(liczba + " , ");
                else
                {
                    Console.Write(liczba + " , ");
                    Console.WriteLine();
                }

                if (max < liczba) max = liczba;
                if (liczba < min) min = liczba;
                suma = suma + liczba;
            }
            Console.WriteLine();
            Console.WriteLine("Największa liczba to " + max + ".");
            Console.WriteLine();
            Console.WriteLine("Najmniejsza liczba to " + min + ".");
            Console.WriteLine();
            Console.WriteLine("Srednia wynosi " + suma / ilosc_liczb + ".");
                       
            Console.Read();
        } 
    }
}
 

Zad 2. Napisz program wyświetlający tabliczkę mnożenia dla liczb od 1 do 100 (tj. 10x10) z wykorzystaniem podwójnej pętli for.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace petlre2
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 10, wiersz, kolumna;

            Console.WriteLine("Program wyświetla liczby 1-100");
            Console.WriteLine();
            for (wiersz = 1; wiersz <= n; wiersz++) //nie rozumiem jak działa podwójna pętla i nie wiem skąd program wie że wyświetlają się kolumny i wiersze, z czego to wynika?
            {
                for (kolumna = 1; kolumna <= n; kolumna++)
                {
                    Console.Write(wiersz * kolumna + "\t");
                }
                Console.WriteLine();
            }
            Console.Read();


        }
    }
}

Zad. 3 Napisz program, który wyświetla duże litery alfabetu od A do Z i od Z do A z wykorzystaniem pętli for.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace petle3
{
    class Program
    {
        static void Main(string[] args)
        {
            char znak; //czemu char akurat a nie int czy double? Czy w charze mieszczą się literki?
            //Jeżeli tak to skąd char zna alfabet aby pokazać je po kolei?

            Console.WriteLine("Program wyświetla duże litery A-Z i Z-A");
            Console.WriteLine();
            for (znak = 'A'; znak <= 'Z'; znak++)
            {
                if (znak < 'Z')
                    Console.Write(znak + ".");
                else
                {
                    Console.Write(znak + ".");
                    Console.WriteLine();
                }
            }

                for (znak = 'Z'; znak >= 'A'; znak--)
                {
                    if (znak > 'A')
                        Console.Write(znak + ".");
                    else
                    {
                        Console.Write(znak + ".");
                        Console.WriteLine();
                    }

                }
            
            Console.Read();

        }
    }
}
 

Zad4. Wiedząc, że 1233 = 122+332, napisz program, który znajduje wszystkie liczby z przedziału od 1000 do 9999 spełniające taką ciekawą zależność. Program dodatkowo liczy ich ilość.

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Zad4
{
    class Program
    {
        static void Main(string[] args)
        {
            int j = 0;
            for (int i = 1000; i < 10000; i++)
            {
                int pdc = i/100; //-pierwsze 2 cyfry, ale skąd wiadomo że tak? Co dokładnie oznacza ten zapis
                int odc = i%100;// tak smao tutaj 2 ostatnie cyfry, skąd o tym wiemy?

                if (pdc * pdc + odc * odc == i)
                {
                    Console.WriteLine(i + "=" + pdc + "*" + pdc + "+" + odc + "*" + odc);
                    ++j; //jakbym zapisał j++ to byłoby to samo? Jeżeli nie to czym się to różni?
                    //w jaki sposób to podlicza te liczby? skąd program wie że akurat są dwie a nie 3 czy 4?
                    

                }
                
            }
            Console.WriteLine();
            Console.WriteLine("Znaleziono " + j + "liczby."); 
            Console.Read();
        }
    }
}

Z góry bardzo dziękuję za pomoc!

0

Ale brzydki ten kod, skąd ty wziąłes te przykłady? Myślę, że lepiej byś nauczył programowania z jakiegoś kursu niż analizując podrzędny kod. Proponuję przejrzeć jakiś dobry tutorial do C# i jak czegoś nie będziesz rozumiał to pytaj, najlepiej z minimalistycznym przykładem prezentującym problem.

1

Zad. 1:
Na początku deklarujesz sobie zmienne ilość_liczb, oraz i. Nie ma sensu do i przypisywać wartości w tym punkcie, bo i jest użyta jako iterator pętli i jak widzisz w pętli for jest jej przypisana wartość 2, więc dwa razy przypisujesz do niej to samo.

Potem kolejne zmienne, liczba która reprezentuje kolejna wylosowaną wartość, suma to wiadomo, min i max to minimalna i maksymalna wartość z przedziału wylosowanych liczb.

Jeszcze przed pętlą losujesz pierwszą wartość, którą przypisujesz do sumy i do wartości min i max (bo jak masz jedną liczbę to nie ma jak liczyć sumy ale zmienną suma musisz zainicjować żeby ją liczyć dalej w pętli, tak samo z min i max).

Teraz losowanie pierwszej liczby:

 
Random r = new Random(); 
min = Math.Round(100 * (r.NextDouble())); 

W CeSzarpie masz tak skonstruowane losowanie liczb że musisz najpierw utworzyć nowy obiekt klasy Random(), żeby wylosować liczbę z przedziału od 0 do 1, np 0.85 stosujesz na tym obiekcie metodę NextDouble(). Więc jak wylosować liczbę od 0 do 100 mając takie dane? Pomnożyć całość przez 100 a Math.Round po prostu zaokrągla całość do Inta.

No i pętla, zaczyna się od i = 2 bo pierwszą liczbę wylosowaleś już przed pętlą, w niej losujesz kolejne wartości które dodajesz do sumy i sprawdzasz czy przypadkiem ta wartość jest większa od maksymalnej znalezionej czy też mniejsza od minimalnej znalezionej poprzednio liczby, jezeli tak podmieniasz wartość min lub max.

1
czaffik napisał(a):

W CeSzarpie masz tak skonstruowane losowanie liczb że musisz najpierw utworzyć nowy obiekt klasy Random(), żeby wylosować liczbę z przedziału od 0 do 1, np 0.85 stosujesz na tym obiekcie metodę NextDouble(). Więc jak wylosować liczbę od 0 do 100 mając takie dane? Pomnożyć całość przez 100 a Math.Round po prostu zaokrągla całość do Inta.

Można też jak człowiek:

 rand.Next(0,100) 
1

W zadaniu drugim podwójna pętla jest potrzebna do wyświetlania konsolowego, program konsolowy wyświetla tekst tak że nie da się najpierw czegoś napisać, potem przeskoczyć na początek tekstu, coś dopisać, potem przeskoczyć do 3 wiersza, coś napisać i znowu skoczyć do 1 wiersza i coś dopisać, musisz wyświetlać tekst linijka po linijce.
Dlatego masz pierwszą pętlę, która iteruje po wierszach konsoli, a w niej siedzi druga pętla iterująca po kolumnach. Na początku pierwsza pętla przyjmuje wartość 1, więc wypisywane będą wszystkie kolumny pierwszego wiersza, a wypisywanie j-tej kolumny danego i-tego wiersza reprezentuje druga pętla.
Jak masz problem ze zrozumieniem jak działa taka pętla to zrób sobie przykład:

 for (int i = 1; i <= 20; i++)
 {
     Console.Write(i);
     for (int j = 1; kolumna <= 20; j++)
     {
         Console.Write(j);
     }
}

i popatrz się co ona wypisuje, jakie wartości i i j.

0

A reszte kombinuj se sam :P

0

No ale wstawiłem dalsze programy (3 i 4 zad) bo ich nie rozumiem, tak nagle mnie nie olśni, dalej nie wiem czemu w 3 zadaniu jest char i skąd on wie które litery w alfabecie są po kolei...
tak samo w zad 4... skąd mam wiedzieć że dane dzielenie i przez 100 daje pierwsze/ostatnie dwie liczby i czy nie można tego inaczej rozpisać...

W zad 3 zasadę działania programu rozumiem, martwi mnie tylko ten char, tak jak wyżej wspominałem, natomiast zasada działania zad 4 jest dla mnie troszkę dziwna

1

Wszystkich programów nikt ci omawiał od a do z nie będzie, ale na pewne pytania można odpowiedzieć. Pytasz się o ten char, tak prosto rozumując to char w zasadzie też jest liczbą, jednak przez program jest interpretowany inaczej niż np int, bo liczba w nim zapisana jest zamieniana na znak zgodnie z kodem ASCII, popatrz sie na kod ASCII i jakie wartości przyjmują litery od 'A' do 'Z'. Każda zmienna to liczba, różnią się sposobem interpretacji przez kompilator czy tam program.
Tutaj to możesz sobie wsiąść kartkę i długopis i powykonywać działania, np 9567/100 = ? albo 1234/100 = ? I do jakich wniosków dojdziesz? To samo z 9567%100 = ? (% - oznacza dzielenie modulo) - a więc dzielisz liczbę na 100, bierzesz całkowity wynik z tego dzielenia (bez przecinka), mnożysz wynik przez 100 i patrzysz ile brakuje do liczby.

0
czaffik napisał(a):

Wszystkich programów nikt ci omawiał od a do z nie będzie, ale na pewne pytania można odpowiedzieć. Pytasz się o ten char, tak prosto rozumując to char w zasadzie też jest liczbą, jednak przez program jest interpretowany inaczej niż np int, bo liczba w nim zapisana jest zamieniana na znak zgodnie z kodem ASCII, popatrz sie na kod ASCII i jakie wartości przyjmują litery od 'A' do 'Z'. Każda zmienna to liczba, różnią się sposobem interpretacji przez kompilator czy tam program.
Tutaj to możesz sobie wsiąść kartkę i długopis i powykonywać działania, np 9567/100 = ? albo 1234/100 = ? I do jakich wniosków dojdziesz? To samo z 9567%100 = ? (% - oznacza dzielenie modulo) - a więc dzielisz liczbę na 100, bierzesz całkowity wynik z tego dzielenia (bez przecinka), mnożysz wynik przez 100 i patrzysz ile brakuje do liczby.

To są moje pierwsze programy z którymi mam styczność i chcę je jakoś zrozumieć, póki rozumiem tylko teoretycznie działanie różnych metod, potrzebuję wytłumaczenia praktycznego, myślę że po kilkunastu/dziesięciu zadań przerobionych będę na tyle znał stronę praktyczną że takich zadań nie będzie mi musiał ktoś omawiać krok po kroku a jedynie niewielki fragment. Wrzucam przecież temat specjalnie na "Newbie" bo jestem w tym zielony.

Co do kodów ASII, skąd miałem wiedzieć że coś takiego istnieje? Teraz wiem o co chodzi i dlaczego wyświetla to w kolejności alfabetycznej.

W ostatnim (czwartm zadaniu) myślę że prawie wiem o co chodzi ale dalej martwi mnie zmienna

j

i w jaki sposób program wykrywa "naliczanie" tych liczb, jak samo j++

 potrafi zliczyć ile liczb pasuje skoro w ifie są deklaracje samych<code class="csharp"> i

.

W C# masz metodę Random.Next(od, do). Poza tym ten kod równie dobrze mógłby być napisany bez fora, skoro i tak dla pierwszego elementu liczy to samo poza nim. Nie rozumiem kompletnie sensu nauki programowania na bazie kodu pisanego przez osobę, która jak widać sama nie potrafi programować. - adwy dzisiaj, 14:28
Jak bez fora? a jak posumujesz wartości i znajdziesz maksymalną i minimalną wartość? przed pętlą wykonany jest kawałek kodu dla pierwszej wylosowanej wartości, czymś trzeba te wartości zainicjować, równie dobrze może być to pierwsza wylosowana wartość z sumy. I dobrze niech się uczy i zadaje pytania, może sam poprawi ten kod. - czaffik 1 godz. temu

Napisać bez fora pierwsze zadanie? Jakoś tego nie widzę. Może jakaś mała wskazówka?

1

Zauważ że zmienna i jest zadeklarowana w pętli i tylko w jej obrębie istnieje, ale zmienna j jest zadeklarowana na początku programu (13 linia jeśli się nie mylę, masz

 int j = 0 

) więc ona egzystuje w całym programie, i w pętli i poza nią.
W pętli masz warunek że jeżeli liczba jest zadanego typu to zmianna j ma się powiększyć o 1 dzięki zapisowi ++j.
++j działa tak że zwiększa zmienną j o jeden. Teraz pytasz się jaka jest różnica między **++j **a j++, obie zwiększają wartość j o jeden, ale pierwszy zapis zmienia tą wartość natychmiastowo, natomiast drugi zapis dopiero przy kolejnym wywołaniu tej zmiennej.
Porównaj zapisy:

int a = 1;
int b = 2;
int c;
c = a + (++b);
// wypisz wartość c na ekran
c = a + (b++);
// wypisz wartość c na ekran

Ale czy coś by się zmieniło gdybyś w swoim programie zastosował zamiast ++j zapis j++? Nie, bo przy takim zliczaniu nie ma znaczenia czy zmienną j zmienisz od razu czy dopiero przy kolejnym jej wywołaniu.

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