Värmdö Gymnasium Datainstitutionen Programmering B ++ C++ Funktioner 2 Teori De funktioner som du skrivit hittills har använt s.k. värdeanrop, d.v.s. de argument som skickats med till funktionen har kopierats till för funktionen egna lokala kopior av variablerna. De förändringar av värdena som gjorts i funktionerna har då bara påverkat funktionens kopior, inte de ursprungliga variablerna i huvudprogrammet. Du ska nu få lära dig ett specialfall av motsatsen, ett s.k. referensanrop, när de argument man skickar till funktionen i själva verket är samma variabler som huvudprogrammet använder, fast under ett annat namn. Argumentet får alltså ett slags alias i funktionen, genom att man sätter ett &-tecken framför parameternamnet. Ex. #include <iostream> using namespace std; void kvadrera(int &i) { i=i*i; } // funktionen kvadrera, som tar en referens till en heltalsvariabel // i är alltså ett alias för tal i huvudprogrammet, ändrar man i så ändras tal // här kvadreras i, och alltså också tal i huvudprogrammet main() { int tal=25; cout<<tal<<endl; kvadrera(tal); cout<<tal; system("PAUSE"); } // heltalsvariabeln tal sättes till 25 // 25 skrivs ut på skärmen // tal skickas som referensparameter till funktionen kvadrera // 625 skrivs ut på skärmen Teori En funktion som tar ett fält som argument blir alltid ett referensanrop. Det innebär alltså att fältet själv inte kommer kopieras över till ett nytt fält som hör till funktionen (det som kallas värdeanrop, se tidigare), utan bara minnesadressen till den första "lådan" kopieras. 3 7 1 9 0 1 2 3 Om du har läst in ovanstående värden i fältet tallista och skickar den till funktionen void changeboxzero(int lista[ ]) { lista[0]=8; } med anropet changeboxzero(tallista), så kommer resultatet bli: 8 7 1 9 0 1 2 3 Funktionen behöver alltså inte returnera någonting, utan du kan skicka med befintliga värden och få tillbaks nya förändrade värden med ett fält som argument (Referensanrop). En fördel med detta är att funktionen inte är beroende av hur långt fältet (t.ex. en textsträng) är, utan fungerar för alla storlekar. De tomma hakarna efter namnet tallista talar om att argumentet är ett fält och inte en vanlig variabel. C++ Lektion Funktioner 2.doc Sida 1 Värmdö Gymnasium Datainstitutionen Programmering B ++ Ex. #include <iostream> using namespace std; void kryptera(char str[]) { for(int i=0;str[i]!='\0';i++) str[i]++; } //funktionen som krypterar strängen str //ökar i tills fält nr i innehåller slutsträngtecken //förskjutning av alla bokstäver ett steg main() { char text[50]; cout<<"Mata in en text som ska krypteras: "; cin>>text; kryptera(text); cout<<"Krypterad text:"<<endl<<text<<endl; system("PAUSE"); } //anropar funktionen kryptera Ett svårt Exempelprogram som innehåller båda nämnda finesser finns sist i häftet. Läs Läs även om referensparametrar i C++-manualen online, kap 7. C++ Lektion Funktioner 2.doc Sida 2 Värmdö Gymnasium Datainstitutionen Programmering B ++ Öva Övning 1 Utöka miniräknaren och utnyttja switch-satsen i menyn. Lägg till följande alternativ: • läs in tal i en lista (Kan du lösa det du vill med en funktion som är av typen void!) • skriv en funktion som beräknar medelvärdet av listans tal (Kan du lösa det du vill med en funktion som är av typen void!) • skriv en funktion som dubblerar listans tal • skriv en funktion som sorterar listan (stigande) Övning 2 Skriv en funktion som till argument tar en textsträng, räknar efter och skriver ut hur många stora resp. små bokstäver som finns i textsträngen (i intervallen a-z och A-Z). Skriv sedan ett kort huvudprogram som testar funktionen för några olika strängar. Övning 3 Skriv en funktion som genererar en LOTTO-rad. (7 tal mellan 1 och 35). Testa sedan funktionen med enkelt program. Övning 4 Skriv en funktion som genererar en stryktips-rad och en annan funktion som skriver ut den snyggt ( se nedan). Testa sedan funktionen med enkelt program. X 1 2 2 1 X osv. Övning 5 Utöka programmet ovan med en funktion som rättar DIN tipsrad mot den RÄTTA och returnerar antal rätt. Funktionen ska vara av typen void. Referensparametrar ska användas. Övning 6 I det s.k. rövarspråket dubbleras alla konsonanter och ett ’o’ placeras mellan de dubblerade konsonanterna. Vokaler och övriga tecken är oförändrade. Skriv en funktion put_rovare som får en textsträng i rövarspråket som parameter. Funktionens uppgift är att skriva ut texten i klarspråk. Använd sedan funktionen för att skriva ett program där man matar in ett meddelande på rövarspråket och får ut det i klartext på skärmen. T.ex. ska inmatningen ”hohejoj alollolihohopopa!” ge resultatet ”hej allihopa!”. Minitest G-nivå: 1. Skriv en funktion som till argument tar en textsträng, räknar efter och skriver ut hur många stora resp. små bokstäver som finns i textsträngen (i intervallen a-z och A-Z). Skriv sedan ett kort huvudprogram som testar funktionen för några olika strängar. VG-nivå: 1. Skriv en funktion som sorterar en lista (stigande).Skriv också ett program som utnyttjar din funktion Läxa Gå igenom teori plus exempel i dagens lektion, gör klart övningarna samt läs avsnittet om referensparametrar, se läsanvisningen tidigare. C++ Lektion Funktioner 2.doc Sida 3 Värmdö Gymnasium Datainstitutionen Programmering B ++ OBS! Det är inte meningen att du ska hänga med på allt. Det kan vara lärorikt att titta och sen själv testa vissa delar. //funk_listor1.cpp #include <iostream> using namespace std; void meny (); char las_in_alternativ(); int las_in_lista(double lista[]); double medelvarde (double lista[], int n); void dubblera(double lista[], int n); void skriv_ut_lista(double lista[], int n); void las_in_lista2(double lista[10], int &x); main () { double resultat, lista[10]; int antal; char svar='1'; while (svar!='0') { meny(); svar=las_in_alternativ(); if (svar=='1') { antal=las_in_lista(lista) ; } else if (svar=='2') { resultat=medelvarde(lista, antal); cout << " Medelvarde : " << resultat << endl; } else if (svar=='3') { dubblera(lista, antal); skriv_ut_lista(lista, antal); } else if (svar=='4') { las_in_lista2(lista, antal) ; } } cout << endl << " HEJ DÅ" << endl; system("PAUSE"); return 0; } //****************************************************** void meny () { cout << endl << endl; cout << "***** MENY *****" << endl; cout << "################" << endl<<endl; cout << " 1 läs in lista" << endl; cout << " 2 beräkna medelvärde" << endl; cout << " 3 dubblera talen i listan" << endl; cout << " 4 läs in lista, alternativ 2" << endl; cout << " 0 AVSLUTA" << endl; cout << endl; } //****************************************************** C++ Lektion Funktioner 2.doc Sida 4 Värmdö Gymnasium Datainstitutionen Programmering B ++ char las_in_alternativ() { char svar; cout << endl << " Ange alternativ: " ; cin >> svar; return svar; } //****************************************************** int las_in_lista(double lista[]) { int stegare=0; char svar; while (true) { stegare++; cout<<" Ange ett tal: "; cin>>lista[stegare-1]; cout<<"Vill du fortsätta: (j/n) "; cin>>svar; if ( svar!='j' ) return stegare; } } //****************************************************** double medelvarde (double lista[], int n) { double sum=0; for (int i=0; i<n; i++) sum+= lista[i]; return sum/n; } //****************************************************** void dubblera (double lista[], int n) { for (int i=0; i<n; i++) lista[i]*=2; } //****************************************************** void skriv_ut_lista(double lista[], int n) { for ( int i=0; i<n; i++) cout << lista[i]<<endl; } //****************************************************** void las_in_lista2(double lista[], int &x) { int stegare=0; char svar='j'; while (svar=='j') { stegare++; cout<<" Ange ett tal: "; cin>>lista[stegare-1]; cout<<"Vill du fortsätta: (j/n) "; cin>>svar; if ( svar!='j' ) x=stegare; } } //****************************************************** C++ Lektion Funktioner 2.doc Sida 5