c++

Programmeren in C++

1. Introductie

C++ (uitgesproken als C plus plus) is een programmeertaal wat is gebaseerd op C. De taal is ontworpen omdat de taal C te beperkt was. De term c++ is ook een codeeropdracht: verhoog de variabele c met 1.

C++ wordt op diverse  manieren gebruikt maar je kunt het vooral zien als een taal die direct diverse bronnen kan aanspreken. Je programmeert dicht bij de processor in tegenstelling tot bijvoorbeeld Java wat in een virtuele machine draait (Java Virtual Machine). Hierdoor is het ook gevoeliger voor hacks. De buffer overflow is hiervan de meest bekende.

Bij deze cursus gaan we ervan uit dat je de basisprincipes van het programmeren onder de knie hebt. Hiervoor kun je op deze websites twee cursussen doen: Greenfoot (het programmeren van een Java Game) en Een interactieve applicatie in Java.

Het is daarom dat we er meteen stevig tegenaan gaan. We starten met het maken van een loginsysteen.

2. Visual Studio installeren en instellen

Voor deze cursus installeer je Visual Studio van Microsoft (niet op school). Neem de gratis community versie 2022.

https://images.computational.nl/galleries/c++/2021-11-07_11-58-17.png

Voer het bestand uit wat je hebt gedownload.

https://images.computational.nl/galleries/c++/2021-11-09_19-49-17.png

Nadat je de Installer hebt geïnstalleerd komt het eigenlijke werk. Je dient dan te kiezen voor een bepaalde configuratie. Kies voor Desktop development with C++.

https://images.computational.nl/galleries/c++/2021-11-11_19-34-48.png

Nadat het programma is geïnstalleerd kun je een bepaald thema kiezen (wij hebben gekozen voor Blue maar veel programmeurs kiezen voor een donker thema).  Vervolgens zie je het hiernavolgende scherm. Kies hierin Create a new project.

https://images.computational.nl/galleries/c++/2021-11-11_19-56-51.png

In het scherm van het nieuwe project kun je kiezen voor Windows en daarna voor Console App. Vul eventueel bovenin C++ als dit niet meteen tevoorschijn komt.

https://images.computational.nl/galleries/c++/2021-11-11_20-00-35.png

Geef je project de naam <voornaamproject> en stel het in zoals hieronder is afgebeeld. Wij gebruikkten in eerste instantie Google Drive (zoals getoond in de afbeelding) maar dat gaf soms een foutmelding. Als dat het geval is kun je beter een mapje in Mijn Documenten aanmaken (C:\Users\<jouwgebruikersnaam>\Documents\

https://images.computational.nl/galleries/c++/2021-11-11_20-06-47.png

Klik uiteindelijk op Create. Het project wordt gemaakt. Aan de rechterkant zie je nu de volgende mappenstructuur.

https://images.computational.nl/galleries/c++/2021-11-11_20-49-39.png

3. Hello world

C++ heeft altijd een begin nodig en dit is de main methode. Deze is in ons project al gemaakt. Als je het mapje Source files open klapt dan zie je de file <jouwvoornaam>project.cpp en deze heeft de volgende inhoud.

// <jouwvoornaam>project.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
}

// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu

// Tips for Getting Started: 
//   1. Use the Solution Explorer window to add/manage files
//   2. Use the Team Explorer window to connect to source control
//   3. Use the Output window to see build output and other messages
//   4. Use the Error List window to view errors
//   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
//   6. In the future, to open this project again, go to File > Open > Project and select the .sln file

Verwijder, voordat je verder gaat, alle commentaar. Doe dit door de toetscombinatie Ctrl-x te gebruiken. Deze verwijderd een regel inclusief return.

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
}

De regel #include <iostream> maakt dat je de bibliotheek iostream kunt gebruiken. We voegen hier nog een regel aan toe: using namespace std;

#include <iostream>
using namespace std;

int main()
{
    cout << "Hello World!\n";
}

Deze regel maakt dat je de regel std::cout << "Hello World!\n"; kunt reduceren naar bovenstaand voorbeeld. Een namespace is vergelijkbaar met een achternaam van een persoon. Stel je hebt in een groep twee keer de naam Tim: Tim Jansen en Tim Pietersen. De achternaam is de namespace en bepaalt welke Tim het is. In dit geval is dus de namespace std.

We gaan nu de file werkend maken. Klik hiervoor op Local Windows Debugger

.https://images.computational.nl/galleries/c++/2021-11-21_16-12-33.png

Er zou nu een Console moeten openen met de volgende output.

Hello World!

C:\Users\...\Documents\Visual Studio 2022\ConsoleApplication2\x64\Debug\ConsoleApplication2.exe (process 19932) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

De regel cout << "Hello World!\n"; heeft gemaakt dat Hello World wordt geprint. De regel \n maakt dat er een extra witregel wordt geprint.

4. De main methode

De main methode is de start van C++. Zonder deze methode werkt de applicatie niet. Er mag maar een main methode zijn ook al zijn er verschillende files.

Er zijn twee typen methoden: expressies of opdrachten. Een opdracht geef je als volgt aan:

void main () 
{
  //hier de code
}

Het mag wel maar een betere manier om een main te maken is om het type te veranderen in een expressie. Een expressie betekent dat de methode wat terug moet geven door middel van het codewoord return.

int main () 
{
   //hier alle code

   return 0;
}

De returnwaarde 0 betekent in c++ dat het OK is en dat er geen errors zijn.

5. cout en cin

Het eerst wat we doen is de regels laten weten aan de gebruiker. We gebruiken hiervoor de regel cout (spreek uit: sie-out).

#include <iostream>
using namespace std;

int main()
{
	system("cls"); //maak het scherm schoon
	cout << "\n\n\n\t\t======Nummer raden met pegels======\n"; // \n=volgende regel \t=tab
	cout << "\t1. Kies 1, 2 of 3. \n";
	cout << "\t2. Als je wint krijg je 1-10x aantal pegels.\n";
	cout << "\t3. Als je verliest ben je je inzet kwijt.\n\n";

	return 0;
}

Kijk eerst of de file werkt en of de regels worden getoond.

Het tegenovergestelde van cout is cin. Hiermee kunnen we variabelen waarden geven. Beschouw de volgende code:

#include <iostream>
using namespace std;

int main() {

	cout << "Geef twee getallen" << endl;
	int variable1 = 0, variable2 = 0;
	cin >> variable1 >> variable2; //de variabelen krijgen een waarde via de console
	cout << "De optelling van getal 1 en getal 2 is " << variable1 + variable2 <<  endl; // een berekening in cout is ook mogelijk
	return 0;
}

Je ziet dat we hier endl gebruiken in plaats van \n. Deze code maakt dat er een volgende regel is.

In de regel int variable1 = 0, variable2 = 0; zie je dat er twee regels tegelijk worden gedeclareerd. Dat is vrij gebruikelijk.

6. Variabelen

Het volgende wat we nu nodig hebben voor onze game zijn variabelen. Dat werkt niet anders dan in andere talen. We gebruiken drie soorten variabelen namelijk een int, een string (zonder hoofdletter) en een char. Een char is precies één karakter. Deze is om de J/N vraag te kunnen beantwoorden.

De variabelen maken we aan in de main methode. Vanaf nu plaatsen we het commentaar in het Engels zodat we ook op internationale fora terecht kunnen voor het stellen van vragen.

#include <iostream>
using namespace std;

int main()
{
	string playerName;
	int balance; // stores player's balance
	int bettingAmount;
	int guess = 0;
	int dice; // stores the random number

	system("cls"); //maak het scherm schoon
	cout << "\n\n\n\t\t======Nummer raden met pegels======" << endl; // \n=volgende regel \t=tab
	cout << "\t1. Kies 1, 2 of 3." << endl; ;
	cout << "\t2. Als je wint krijg je 1-10x aantal pegels." << endl; ;
	cout << "\t3. Als je verliest ben je je inzet kwijt." << endl;

	return 0;
}

7. do while

De stap die we nu nemen is als het spel is afgelopen we aan de gebruiker vragen of hij nog een keer wil spelen. Dit doen we aan de hand van een do-while constructie. We geven eerst de syntax.

do {
  // code block to be executed
}
while (condition);

Het blok do wordt eerst altijd uitgevoerd ongeacht wat er in de while staat. Hieronder een voorbeeld.

#include <iostream>
using namespace std;

int main()
{

	string playerName;
	int balance; // stores player's balance
	int bettingAmount;
	int guess = 0;
	int dice; // stores the random number
	char choice;

	do {
		//system("cls"); //maak het scherm schoon
		cout << "\n\n\n\t\t======Nummer raden met pegels======" << endl; // \n=volgende regel \t=tab
		cout << "\t1. Kies 1, 2 of 3." << endl; ;
		cout << "\t2. Als je wint krijg je 1-10x aantal pegels." << endl; ;
		cout << "\t3. Als je verliest ben je je inzet kwijt." << endl;

		int i = 0;
		i++; //increase i with 1


		cout << "\n\n-->Wil je opnieuw spelen (j/n)? ";
		cin >> choice;
	} while (choice == 'J' || choice == 'j');

}

Om goed te laten zien wat er gebeurt hebben we system(cls) even uitgezet.

Merk op dat de variabelen buiten het do statement staan.

8. De nog een keer spelen vraag

We kunnen na de while ook een mededeling plaatsen.

#include <iostream>
using namespace std;

int main()
{
	string playerName; //name of the player
	int balance=100; // stores player's balance
	int bettingAmount; //what the user will bet 
	int guess; //the user choose 1,2 or 3
	int dice; // stores the random number
	char choice; //play again


	do
	{
		system("cls"); //clear the screen
		cout << "\n\n\n\t\t======Nummer raden======" << endl; // \n=next rule \t=tab
		cout << "\t1. Kies 1, 2 of 3. " << endl;
		cout << "\t2. Als je wint krijg je 10x je inleg." << endl;
		cout << "\t3. Als je verliest ben je je inzet kwijt.\n" << endl;

		cout << "\n\nWil je de game opnieuw spelen (j/n)? " << endl;
		cin >> choice;

	} while (choice == 'J' || choice == 'j');

	cout << "\n\nBedankt voor het spelen van de game. Het bedrag wat op je rekening staat is $" << balance  << endl;
	return 0;
}

We hebben met behulp van cout een vraag gesteld en het antwoord vangen we met cin op. Vervolgens checken we in het while statement of er op een j of J is gedrukt. Als het antwoord j of J is dan draait de while nog een keer en anders wordt de mededeling getoond.

9. Refences en pointers

Voordat we verder gaan met de game, is er kennis nodig van een speciaal soort variabelen: references en pointers. Een reference is een referentie naar een bestaande variabele en wordt aangegeven met het & teken.

#include <iostream>
using namespace std;

int main()
{
	string student = "Piet";
	string& rStudent = student;

	cout << student << endl; //output Piet
	cout << rStudent<< endl;  //output Piet
	return 0;
}

Als we de reference rStudent een andere waarde geven dan krijgt ook de variabele student een andere waarde.

#include <iostream>
using namespace std;

int main()
{
	string student = "Piet";
	string& rStudent = student;

	cout << student << endl;
	cout << rStudent << endl;

	rStudent = "Jan";

	cout << student << endl;
	cout << rStudent << endl;
	return 0;
}

De outpunt is nu:

Piet
Piet
Jan
Jan

De reference is in eigenlijk een andere naam is voor dezelfde variabele. We kunnen dat ook zien aan het geheugenadres. Dit is namelijk exact hetzelfde. Een geheugenadres kunnen we uitprinten met het &-teken.

#include <iostream>
using namespace std;

int main()
{
	string student = "Piet";
	string& rStudent = student;
	string* pStudent = NULL;

	cout << student << endl; 
	cout << rStudent << endl;
	cout << &rStudent << endl; 
	return 0;
}

En de output is

Piet
Piet
000000E2006FFAC8
000000E2006FFAC8

..waarbij je kunt zien dat het adres exact hetzelfde is.

References worden vooral gebruikt als parameters voor functies. Daarover later meer.

pointers

Een pointer is een speciale variabele die in plaats van de waarde, het geheugenadres opslaat. We kunnen dus een pointer vullen met een reference.

#include <iostream>
using namespace std;

int main()
{
	string student = "Piet";
	string* pStudent = &student; //de pointer krijgt het geheugenadres van student
	string& rStudent = student; //de referentie rStudent krijgt de waarde van student

	cout << student << endl;
	cout << pStudent << endl;
	cout << rStudent << endl;
}

Maar wat gebeurt er als we de volgende code uitvoeren waarbij we de referentie van student een andere waarde geven.

#include <iostream>
using namespace std;

int main()
{
	string student = "Piet";
	string* pStudent = &student;
	string& rStudent = student;

	cout << student << endl;
	cout << pStudent << endl;
	cout << rStudent << endl;

	rStudent = "Jan"; //rStudent krijgt een nieuwe waarde

	cout << student << endl;
	cout << pStudent << endl;
	cout << rStudent << endl;
	return 0;
}

In dat geval krijgt ook de variabele student een andere waarde. Het adres van de pointer blijft hetzelfde.

Piet
0000001CB7CFF888
Piet
Jan
0000001CB7CFF888
Jan

Opmerking: als we de variabele rStudent veranderen dan kun je niet zien dat student ook meeverandert. Dat is niet erg duidelijk. Het is daarom beter om daar waar mogelijk bij het definieren van een variabele het codewoord const te gebruiken. In dat geval mag je de waarde alleen maar veranderen als je de eigenlijke variabele verandert.

string student = "Piet";
const string& rStudent = student;

cout << student << endl;
cout << rStudent << endl;

rStudent = "Jan"; //dit geeft nu een foutmelding
student = "Jan"; //dit is de juiste manier om een variabele te veranderen

Als laatste kunnen we bij een pointer ook een zogenaamde dereference geven met weer dezelfde ster. In dat gev al krijgen we weer de waarde.

#include <iostream>
using namespace std;

int main()
{
	string student = "Piet";
	string* pStudent = &student;
	string& rStudent = student;

	cout << pStudent << endl;
	cout << *pStudent << endl;
	
	return 0;
}
000000D0478FF728
Piet

Verschillen tussen een reference en een pointer

reference pointer
Kan geen NULL-waarde krijgen Kan in principe een NULL-waarde krijgen
Heeft de waarde van een variabele Heeft een geheugenadres als waarde.
Kan een derefence krijgen waardoor de waarde van dat adres geprint of gegeven.
Heeft maar één level. Er kan een dubbele pointer (met twee sterren) worden geïntialiseerd waardoor er een dubbele laag ontstaat. Daarover later meer.
Eenmaal aangemaakt kan deze niet meer verwijzen naar een andere variabele. Kan eenmaal aangemaakt worden gewijzigd in een ander geheugenadres.
Kan geen rekenkundige operaties verwerken zoals bijvoorbeeld ref++ Kan in principe alle rekenkundige operaties verwerken.

10. Het maken van een functie

Om alles zo overzichtelijk mogelijk te houden is het van belang soorten code bij elkaar te houden. Hiervoor gebruiken we een functie. Laten we de regels eens onder brengen in een functie.

void rules()
{
	system("cls"); //maak het scherm schoon
	cout << "\n\n\n\t\t======Nummer raden met pegels======" << endl; // \n=volgende regel \t=tab
	cout << "\t1. Kies 1, 2 of 3." << endl; ;
	cout << "\t2. Als je wint krijg je 1-10x aantal pegels." << endl; ;
	cout << "\t3. Als je verliest ben je je inzet kwijt." << endl; 
}

De volledige code ziet er dan als volgt uit:

	#include <iostream>
	using namespace std;

	void rules()
	{
		system("cls"); //maak het scherm schoon
		cout << "\n\n\n\t\t======Nummer raden met pegels======" << endl; // \n=volgende regel \t=tab
		cout << "\t1. Kies 1, 2 of 3." << endl; ;
		cout << "\t2. Als je wint krijg je 1-10x aantal pegels." << endl; ;
		cout << "\t3. Als je verliest ben je je inzet kwijt." << endl;
	}

	int main()
	{
		string playerName; //name of the player
		int balance = 100; // stores player's balance
		int bettingAmount; //what the user will bet 
		int guess; //the user choose 1,2 or 3
		int dice; // stores the random number
		char choice; //play again


		do
		{
			system("cls"); //clear the screen
			rules();
			cout << "\n\nWil je de game opnieuw spelen (j/n)? " << endl;
			cin >> choice;

		} while (choice == 'J' || choice == 'j');

		cout << "\n\nBedankt voor het spelen van de game. Het bedrag wat op je rekening staat is $" << balance << endl;
		return 0;
	}

Dus met de opdracht rules() roep je de functie aan. De methode main is nu overzichtelijker geworden.

11. functies met behulp van een reference en een pointer

We gaan nu de voorgaande twee lessen combineren. Eerst maken we de volgende functie.

void setPlayer(string* playerName)
{
	cout << "\n\t\t========Geef eerst je naam: ";
	cin >> *playerName;
	cout << "\t\tHallo " << *playerName << endl;
}

Je ziet dat we een pointer gebruiken om een waarde in de functie

12. temporary lesson

Dit onderdeel is uitgeschakeld door de docent.