english

Urszula Libal

PWr

    

    

    Podstawy programowania

              - laboratorium


    
 

     Lab. 1.  Operacje I/O

     Lab. 2.  Pętle

     Lab. 3.  Tablice

     Lab. 4.  Funkcje

     Lab. 5.  Stringi i wskaźniki

     Lab. 6.  Typ strukturalny

     Lab. 7.  Odczyt i zapis pliku

     Losowanie liczb

 
 
 


PWr


Podstawy programowania


Kurs dla I roku AIR EKA INF (laboratorium 15h)




Zasady zaliczenia:


Obecność jest obowiązkowa. W semestrze mamy tylko kilka spotkań, więc nie ma możliwości odrabiania zajęć, ani poprawiania kartkówek.
 
Ocena końcowa zostanie wystawiona na podstawie 6 kartkówek. Kartkówka nr 6 jest nieobowiązkowa. Każda kartkówka pozwala zbobyć 10 punktów. Prezentacja na tablicy własnego rozwiązania zadania to dodatkowe 3 punkty.

Każda nieobecność skutkuje otrzymaniem 0 punktów za kartkówkę. Nieobecności z powodu dłuższego pobytu w szpitalu będą rozpatrywane indywidualnie.

Ocena końcowa przy 5 kartkówkach to:
  1. 5.5 - 100% (50 pkt),
  2. 5.0 - od 90% (45-49 pkt),
  3. 4.5 - od 80% (40-44 pkt),
  4. 4.0 - od 70% (35-39 pkt),
  5. 3.5 - od 60% (30-34 pkt),
  6. 3.0 - od 50% (25-29 pkt),
  7. 2.0 - mniej niż 50% (czyli 0-24 pkt).

Studenci powtarzający kurs Podstawy programowania, którzy zaliczyli laboratorium w poprzednim semestrze, mogą mieć przepisaną ocenę na podstawie oceny w indeksie. Żadne inne kursy czy certyfikaty nie zwalniają z tego kursu.



Visual Studio 2010:


W laboratorium programujemy w środowisku Visual C++ 2010 Express.
Zobacz instrukcję, jak szybko zacząć pracę w VS.
Przeglądnij także instrukcję na temat zarządzania projektami w VS.



Listy zadań:


pdf  Lista 1.   Operacje I/O
pdf  Lista 2.   Pętle
pdf  Lista 3.   Tablice
pdf  Lista 4.   Funkcje
pdf  Lista 5.   Stringi i wskaźniki   pdf  
pdf  Lista 6.   Typ strukturalny
pdf  Lista 7.   Odczyt i zapis pliku




Przykładowe programy w C++ oraz zadania dodatkowe:


Lab. 1.  Operacje I/O

// cout() - wypisanie ciagu znakow na ekran
// cin() - wczytywanie liczb i znakow z klawiatury

#include <iostream>
using namespace std;

int main()
{
// komentarz jednoliniowy
/* komentarz
wieloliniowy */
// endl - nowa linia
// '\n' - nowa linia
// '\t' - tabulacja

// deklaracje zmiennych
char a;
int b1, b2, b3;

cout << "Hello world!\n";

cout << "\nPodaj pierwsza liczbe:";
cin >> b1; //wczytuje liczbe b1
cout << "\nPodaj druga liczbe:";
cin >> b2; //wczytuje liczbe b2
b3 = b1 + b2;
cout << "Wynik dodawania liczb " << b1
<< " i " << b2 << " to " << b3 << endl;

cout << "\n\nPodaj znak z klawiatury\t";
cin >> a; //wczytuje znak z klawiatury
cout << "\nTwój znak to: " << a <<endl;

system("PAUSE");
return 0;
}



Lab. 2.  Pętle i instrukcje warunkowe


#include <iostream>
#include <windows.h>
using namespace std;

int main(void)
{
int klucz;
char wyjscie;
double a, b;
int kolor=0;
//0-czarny, 1-niebieski, 2-zielony, ... 7-bialy
HANDLE hk = GetStdHandle(STD_OUTPUT_HANDLE);

do
{
system("cls"); // czyszczenie ekranu
kolor++;
//niebieski pierwszym kolorem czcionki
SetConsoleTextAttribute(hk, kolor);
cout<<"KOLOR "<<kolor<<endl;

cout<<"PROSTY KALKULATOR"<<endl;
cout<<"Podaj a= "<<endl;
cin>>a;
cout<<"Podaj b= "<<endl;
cin>>b;

cout<<"\n\nMENU:"<<endl;
cout<<"1. a+b"<<endl;
cout<<"2. a-b"<<endl;
cout<<"3. a*b"<<endl;
if(b!=0) cout<<"4. a/b"<<endl;
cin>>klucz;

switch(klucz)
{
case 1: cout<<"a+b="<<a+b<<endl;
break;

case 2: cout<<"a-b="<<a-b<<endl;
break;

case 3: cout<<"a*b="<<a*b<<endl;
break;

case 4: if(b!=0)
{
cout<<"a/b="<<a/b<<endl;
break;
}
default: cout<<"Blad wyboru operacji!\n";
}

cout<<"\n\nWyjscie z kalkulatora. T/N? \n";
cin>>wyjscie;

}while((wyjscie=='n')||(wyjscie=='N'));

system("PAUSE");
return 0;
}



Lab. 3.  Tablice statyczne


//OPERACJE NA TABLICACH

#include<iostream>
using namespace std;
const int N = 3; //stala w jezyku C: #define N 10

void wczytaj_tab(double[]);
void wypisz_tab(double[]);
void dodaj_tab(double[], double[], double[]);

int main (void)
{
double a[N], b[N], c[N];
wczytaj_tab(a);
wczytaj_tab(b);
wypisz_tab(a);
wypisz_tab(b);
dodaj_tab(a, b, c);
wypisz_tab(c);

// liczba bajtów
cout<<"\n sizeof(char)="<< sizeof(char);
cout<<"\n sizeof(int)="<< sizeof(int);
cout<<"\n sizeof(float)="<< sizeof(float);
cout<<"\n sizeof(double)="<< sizeof(double);

// liczba bajtów tablicy N-elementowej
cout<<"\n sizeof(tablica)="<< sizeof(a);
cout<<"\n sizeof(double)*N="<< sizeof(double)*N;

system("PAUSE");
return 0;
}

void wczytaj_tab(double tab[])
{
cout<<"\nWCZYTAJ\n";
for(int i=0; i<N; i++)
{
cout<<"tab["<<i<<"]=";
cin>>tab[i];
}
}

void wypisz_tab(double tab[])
{
cout<<"\nWYPISZ\n";
for(int i=0; i<N; i++)
{
cout<<"tab["<<i<<"]="<<tab[i];
cout<<"\t adres ="<<&tab[i]<<endl;
}
}

void dodaj_tab(double a[], double b[], double suma[])
{
cout<<"\nDODAJ\n";
for(int i=0; i<N; i++)
suma[i]=a[i]+b[i];
}

// TABLICZKA MNOZENIA 10x10

#include<iostream>
using namespace std;
const int N = 10;

void inicjalizuj(double tab[N])
{
cout<<"\nINICJALIZUJ\n";
for(int i=0; i<N; i++)
{
tab[i]=i+1;
}
}

void wypisz_tab(double tab[N][N])
{
cout<<"\nWYPISZ\n";
for(int i=0; i<N; i++)
{
for(int k=0; k<N; k++)
{
cout<<tab[i][k]<<"\t";
}
cout<<endl;
}
}

void mnoz_tab(double a[], double b[], double iloczyn[][])
{
cout<<"\nMNOZ\n";
for(int i=0; i<N; i++)
{
for(int k=0; k<N; k++)
{
iloczyn[i][k]=a[i]*b[k];
}
}
}

int main (void)
{
double a[N], b[N], c[N][N];
inicjalizuj(a);
inicjalizuj(b);
mnoz_tab(a, b, c); //wymnozenie tablic a[] i b[]
wypisz_tab(c); //wypisanie tablicy c[][]

cout<<endl;
system("PAUSE");
return 0;
}


Lab. 4.  Funkcje


PRZYKŁAD 1.
Przykład prezentujący sposób przekazania parametrów programu
z wiersza poleceń do funkcji main().
// PARAMETRY W WIERSZU POLECEN
// lab4_1.cpp

/*
Program rozwiazuje rownanie liniowe ax+b=0.

Parametry main():
argc - liczba parametrow,
argv[0] - nazwa programu,
argv[1], argv[2],... - parametry wejsciowe programu
(tu: argv[1] to a, argv[2] to b)

Uruchomienie w wierszu polecen z dwoma parametrami:
>lab4_1.exe a b
np. C:\lab4\Debug>lab4_1.exe 2.4 -4.8
*/

#include<iostream>
#include<stdlib.h> // potrzebne atof()
using namespace std;

int main(int argc, char* argv[])
{
if(argc==3)
{
cout<<"\n Rozwiazanie rownania ax+b=0 dla ";
double a=atof(argv[1]); // string 2 double
double b=atof(argv[2]);
cout<<"a = "<<a;
cout<<", b = "<<b;
if(a!=0)
cout<<" to \n x = "<<-b/a<<endl<<endl;
else
if(b==0)
cout<<" to dowolna liczba rzeczywista.\n\n";
else
cout<<" nie istnieje.\n\n";
}else
cout<<"\n Niepoprawna liczba parametrow!\n\n";

system("PAUSE");
return 0;
}
Uruchomienie w wierszu poleceń z dwoma parametrami:

wiersz polecen

Parametry wejściowe funkcji main() można wpisać także w VisualStudio we właściwościach projektu (Debugging >  Command Arguments).


PRZYKŁAD 2.
Ten sam program, ale zbudowany z wielu funkcji i odpytujący
o parametry równania. Pierwszy sposób polega na zwróceniu wartości parametrów do zmiennych a i b. Drugi sposób to użycie referencji do zmiennych, dzięki czemu nie ma potrzeby zwracania ich wartości.
#include<iostream> 
using namespace std;

void informuj(void);
double wczytaj_przez_wartosc(char *);
void wczytaj_przez_referencje(char *, double &);
void rozwiaz(double, double);
double oblicz(double, double);

int main()
{
double a, b;
informuj();
//zwrocenie wartosci do zmiennych
a = wczytaj_przez_wartosc("dla\n a = ");
b = wczytaj_przez_wartosc(" b = ");
rozwiaz(a, b);

wczytaj_przez_referencje("\n\n Teraz przez referencje
\n a = ", a);
wczytaj_przez_referencje(" b = ", b);
rozwiaz(a, b);

system("PAUSE");
return 0;
}

void informuj(void)
{
cout<<"\n Rozwiazanie rownania ax+b=0 ";
}

double wczytaj_przez_wartosc(char* info)
{
double liczba;
cout<<info;
cin>>liczba;
return liczba;
}

void wczytaj_przez_referencje(char* info, double& liczba)
{
cout<<info;
cin>>liczba;
}

void rozwiaz(double a, double b)
{
if(a!=0)
cout<<" to \n x = "<< oblicz(a, b) <<"\n\n";
else
if(b==0)
cout<<" to dowolna liczba rzeczywista.\n\n";
else
cout<<" nie istnieje.\n\n";
}

double oblicz(double a, double b)
{
return -b/a;
}

PRZYKŁAD 3.
Różnica między przekazywaniem wartości zmiennych, a ich zmianom dzięki referencji.
// PRZEKAZYWANIE PRZEZ WARTOSC I PRZEZ REFERENCJE

#include <iostream>
using namespace std;

int  byValue(int);
void byReference(int &);

int main()
{
   int x = 2;
   int y = 3;

   cout<<"Zwrocona wartosc iksa = "<< byValue(x) <<endl; 
   cout<<"x = "<< x <<endl;

   byReference(y);
   cout<<"y = "<< y <<endl;

   system("PAUSE");
   return 0;
}

int byValue( int number )
{
   return number += 10;
}

void byReference( int &numberRef )
{
   numberRef += 10;
}


Lab. 5. Łańcuchy znaków i wskaźniki



Zadania dodatkowe:


Zad.1. Sczytaną z klawiatury wiadomość tekstową zakoduj za pomocą szyfru Cezara (z przesunięciem alfabetu o pewną liczbę p), a następnie ją wypisz. Druga część zadania będzie polegała na odkodowaniu zaszyfrowanego tekstu po podaniu (użytego podczas kodowania) przesunięcia p. Wypisz odkodowany tekst.

Zad.2. Sprawdź, czy podane słowo jest palindromem (tzn. czytane wspak ma to samo znaczenie, gdy jest czytane normalnie).



PRZYKŁAD 1.
Użycie wskaźnika na zmienną lub referencji do niej skutkuje zmianą wartości zmiennej.
// PRZEKAZYWANIE PRZEZ WARTOSC, 
// PRZEZ WSKAZNIK NA ZMIENNA
// I PRZEZ REFERENCJE

#include <iostream>
using namespace std;

void byValue (int); //przez wartosc
void byPointer (int *); //przez wskaznik
void byReference (int &); //przez referencje

int main(void)
{
int x = 2;

byValue( x );
cout << x << "\n"; // 2

byPointer( &x );
cout << x << "\n"; // 12

byReference( x );
cout << x << "\n"; // 22

system("PAUSE");
return 0;
}

void byValue(int number)
{
number += 10;
}

void byPointer(int *numberPtr)
{
*numberPtr += 10;
}

void byReference(int &numberRef)
{
numberRef += 10;
}


PRZYKŁAD 2.
Każdy ciąg znaków jest zakończony znakiem '\0', który podczas zwykłego wypisywania tekstu nie jest przekazywany na ekran.
W poniższym przykładzie dzięki odpowiednim przesunięciom wskaźnika możliwe jest wypisanie napisu umieszczonego w tablicy text[]
oraz znaku kończącego napis '\0'.
// CIAG ZNAKOW ZAKONCZONY JEST '\0'

#include <iostream>
using namespace std;

int main(void)
{
char text[] = "To jest tekst.";
char *wsk=text; //wsk wskazuje na poczatek tablicy text[]

wsk--; // teraz zmniejszamy wsk o jeden,
// ale w pierwszej iteracji powracamy
// na poczatek tablicy text[]

cout<<"Litera\tKod ASCII\n\n";
do{
wsk++;
cout << *wsk <<'\t'<<(int)*wsk<<'\n';
}while( *wsk != '\0' ); // jezeli pojawil sie znak '\0',
// zakoncz petle

system("PAUSE");
return 0;
}



Lab. 6. Typ strukturalny



Zadania dodatkowe:

Zad.1. Stwórz strukturę Piramida o polach Bok (kwadratu podstawy)
i Wysokosc. Napisz funkcję liczącą objętość piramidy (do funkcji ma być przekazana jedynie struktura Piramida, a nie pojedyncze zmienne). Wymiary piramidy mogą być wpisane na stałe w kodzie programu.

Zad.2. Zmodyfikuj zadanie 1 dopisując funkcję służącą do sczytywania z klawiatury wymiarów piramidy. Funkcja ma zwracać strukturę Piramida, czyli definicja funkcji powinna wyglądać następująco:

   struct Piramida czytajWymiary(void)
   {
      struct Piramida p;
      ...  // tutaj sczytanie wymiarów
      return p;
   }



PRZYKŁAD 1.
#include <iostream>
using namespace std;

struct Box {
double length;
double width;
double height;
};

double countVolume(struct Box b)
{
return b.height * b.length * b.width;
}

int main() {
Box firstBox = { 80.0, 50.0, 40.0 };

cout << "firstBox:\t"
<< firstBox.length << '\t'
<< firstBox.width << '\t'
<< firstBox.height << endl;

Box secondBox = firstBox;

secondBox.length *= 1.1;
secondBox.width *= 1.1;
secondBox.height *= 1.1;

cout << "secondBox:\t"
<< secondBox.length << '\t'
<< secondBox.width << '\t'
<< secondBox.height << endl;

cout << "Objetosc firstBox to \t"
<< countVolume(firstBox) << endl;
cout << "Objetosc secondBox to \t"
<< countVolume(secondBox) << endl;

system("PAUSE");
return 0;
}


Lab. 7. Odczyt i zapis do pliku



PRZYKŁAD 1. Zapis do pliku (ofstream - output file stream):
#include <fstream>
using namespace std;

int main()
{
//otwarcie pliku fout do zapisu
ofstream fout("text.txt");
fout << "Tekst zapisany \nw pliku\n";
fout.close();
return 0;
}

PRZYKŁAD 2. Odczyt pliku (ifstream - input file stream):
#include <fstream>
#include <iostream>
using namespace std;

int main()
{
//otwarcie pliku fin do odczytu
ifstream fin("text.txt");
char ch;

//odczyt znak po znaku
while (fin.get(ch))
cout << ch;

fin.close();
system("PAUSE");
return 0;
}

PRZYKŁAD 3. Zapis i odczyt plików (fstream):
#include <fstream>
#include <iostream>
using namespace std;

int main ()
{

fstream f_stary;
fstream f_nowy;
char ch;

//otwarcie pliku z ustawieniem kursora na końcu pliku
f_stary.open("stary.txt",ios::app);
f_stary << " Nowa linia \n";
f_stary.close();

//otwarcie pliku do odczytu
f_stary.open("stary.txt",ios::in);
//otwarcie pliku do zapisu
f_nowy.open("nowy.txt",ios::out);
f_nowy << "Oto kopia pliku:\n";
while( !f_stary.eof() )
{
f_stary.get(ch);
cout << ch;
f_nowy << ch;
}
f_nowy.close();
f_stary.close();

system("PAUSE");
return 0;
}



Losowanie liczb



PRZYKŁAD:
#include <iostream>
#include <ctime> // zawiera srand(), time(), rand()
using namespace std;

int main( void )
{
int i, j, n;
double k, a, b;
srand( time( NULL ) );

// rand()
cout << "\n1. rand()
\n\tzwraca liczbe calkowita
ze zbioru {0, 1, 2, ..., RAND_MAX}\n\n";
cout << "RAND_MAX = " << RAND_MAX << endl;
for( i = 0; i < 5; i++ )
{
j= rand();
cout << j << endl;
}


// rand()%n
cout << "\n2. rand() % n
\n\tzwraca liczbe calkowita
ze zbioru {0, 1, 2, ..., n-1}\n\n";
cout << "Podaj n = ";
cin >> n;

for( i = 0; i < 5; i++ )
{
j= rand()%n;
cout << j << endl;
}


// a + (b-a) * rand()/(1.0*RAND_MAX)
cout << "\n3. a + (b-a) * rand()/(1.0*RAND_MAX)
\n\tzwraca liczbe zmiennoprzecinkowa
ze zbioru [a, b]\n\n";
cout << "Podaj a = ";
cin >> a;
cout << "Podaj b = ";
cin >> b;

for( i = 0; i < 5; i++ )
{
k= a + (b-a) * rand()/(1.0*RAND_MAX);
cout << k << endl;
}

system("PAUSE");
return 0;
}