#include <iostream>
#include <cstring>
#include <iomanip>

using namespace std;

void demonstrateFirstLawOfArrays(){
	cout<<"\n--- 1. Ο ΠΡΩΤΟΣ ΝΟΜΟΣ ΤΩΝ ΠΙΝΑΚΩΝ ---"<<endl;
	int arr[5]={10,20,30,40,50};
	cout<<"Πίνακας arr[5]={10,20,30,40,50}"<<endl;
	cout<<"(&arr[0]): "<<&arr[0]<<endl;
	cout<<"(arr): "<<arr<<endl;
	if(arr==&arr[0]){
		cout<<"\nΤο όνομα του πίνακα είναι η διεύθυνση της αρχής του."<<endl;
	}
	int *p=arr;
	cout<<"int *p=arr;"<<endl;
	cout<<"(*p): "<<*p<<endl;
}

void demonstratePointerArithmetic(){
	cout<<"\n--- 2. ΑΡΙΘΜΗΤΙΚΗ ΔΕΙΚΤΩΝ ---"<<endl;
	float A[6]={1.5,2.5,3.5,0.5,4.5,5.5};
	float *walker=A;
	cout<<"Πίνακας A[6]={1.5,2.5,3.5,0.5,4.5,5.5}"<<endl;
	for(int i=0;i<6;i++){
		cout<<" - (A["<<i<<"]): "<<A[i]<<endl;
		cout<<" - (*A + "<<i<<")): "<<*(A+i)<<endl;
	}
	//Προσπελαση πινακα με αυξηση του ιδιου του δεικτη
	float *theMin=&A[0];
	walker=&A[1];
	while(walker<&A[6]){
		if(*walker<*theMin){
			theMin=walker;
		}
		walker=walker+1;
	}
	cout<<"Το ελάχιστο στοιχείο είναι το "<<*theMin<<" και βρίσκεται στη διεύθυνση "<<theMin<<endl;
}

void demonstrateCharPointersAndStrings(){
	cout<<"\n--- 3. Η ΕΞΑΙΡΕΣΗ ΤΩΝ CHAR POINTERS ---"<<endl;
	int num=10;
	char letter='Z';
	int *pNum=&num;
	char *pChar=&letter;
	//Η cout χειριζεται τους char * σαν strings και τυπωνει χαρακτηρες μεχρι να βρει το \0
	cout<<"Δείκτης int (pNum): "<<pNum<<endl;
	cout<<"Δείκτης char (pChar): "<<pChar<<endl;
	//Για να δω τη διεθυνση ενος char πρεπει να τον κανω cast σε void *
	cout<<"reinterpret_cast<void *>(pChar): "<<reinterpret_cast<void *>(pChar)<<endl;
}

void demonstratePointerToPointer(){
	cout<<"\n--- 4. ΔΕΙΚΤΕΣ ΣΕ ΔΕΙΚΤΕΣ ---"<<endl;
	int V=101;
	int *P=&V;
	int **Q=&P;
	cout<<"V = 101"<<endl;
	cout<<"*P = &V"<<endl;
	cout<<"**Q = &P"<<endl;
	cout<<"\n(&V): "<<&V<<endl;
	cout<<"(P): "<<P<<endl;
	cout<<"(Q): "<<Q<<endl;
	cout<<"(**Q): "<<**Q<<endl;
}

void showMenuPart2(){
	cout<<"\n===================================================="<<endl;
	cout<<"   ΕΚΠΑΙΔΕΥΤΙΚΟ ΜΕΝΟΥ ΔΕΙΚΤΩΝ (ΜΕΡΟΣ 2)"<<endl;
	cout<<"===================================================="<<endl;
	cout<<"1. Ο Πρώτος Νόμος των Πινάκων"<<endl;
	cout<<"2. Αριθμητική Δεικτών"<<endl;
	cout<<"3. Η Εξαίρεση των char * και strings"<<endl;
	cout<<"4. Δείκτες σε Δείκτες"<<endl;
	cout<<"0. Έξοδος"<<endl;
	cout<<"===================================================="<<endl;
	cout<<"Επίλεξε μια λειτουργία (0-4): ";
}

int main(){
	int choice=-1;
	while(choice!=0){
		showMenuPart2();
		cin>>choice;
		if(cin.fail()){
			cin.clear();
			cin.ignore(10000,'\n');
			cout<<"Εισάγετε έναν έγκυρο αριθμό."<<endl;
			continue;
		}
		switch(choice){
			case 1:
				demonstrateFirstLawOfArrays();
				break;
			case 2:
				demonstratePointerArithmetic();
				break;
			case 3:
				demonstrateCharPointersAndStrings();
				break;
			case 4:
				demonstratePointerToPointer();
				break;
			case 0:
				cout<<"Ολοκλήρωση!"<<endl;
				break;
			default:
				cout<<"Μη έγκυρη επιλογή. Προσπάθησε ξανά."<<endl;
				break;
		}
	}
	return 0;
}
