Vinnaren i pepparkakshustävlingen!
2018-04-05, 23:09
  #2989
Medlem
Xploits avatar
Citat:
Ursprungligen postat av Ranndall
Okej intressant tack för ditt tilläg.

Nästa fråga:
Vad är skillnaden mellan värdeanrop (call-by-value) och referensrop (call-by-reference)?

Så som du skriver stämmer. Om vi har en funktion som tar en vector (som finns i standardbiblioteket i C++, men inte i C om det är det du jobbar med) av doubles
Kod:
void ComputeSum(std::vector<double> Vector);
kommer en kopia av Vector göras när funktionen anropas. Inne i funktionen jobbar vi alltså då endast med denna kopia, varvid förändringar vi gör med Vector inne i funktionen inte påverkar Vector utanför funktionens scope. Detta är alltså värdeanrop.
Om vi istället har en funktion
Kod:
void ComputeSum(std::vector<double>& Vector);
görs ingen kopia av Vector. Vi jobbar alltså direkt med Vector i minet; alla förändringar vi gör med Vector i funktionen följer med sedan när vi lämnar funktionens scope. Detta är alltså referensanrop.

Jobbar man med en std::vector som rymmer ett stort antal element är det alltså ineffektivt att arbeta med värdeanrop eftersom vi måste kopiera samtliga element varje gång funktionen anropas. Om man endast vill läsa data utan att riskera att modifiera argumentet vid referensanrop kan man använda sig av const, t ex
Kod:
void ComputeSum(const std::vector<double>& Vector);
Citera
2018-04-06, 09:15
  #2990
Medlem
Ranndalls avatar
Citat:
Ursprungligen postat av Xploit
Jobbar man med en vector som rymmer ett stort antal element är det alltså ineffektivt att arbeta med värdeanrop eftersom vi måste kopiera samtliga element varje gång funktionen anropas.
Jobbar med C. Okej intressant kan utveckla fördelarna/nackdelarna med call-by-value så att en nybörjare kan förstå?
__________________
Senast redigerad av Ranndall 2018-04-06 kl. 09:19.
Citera
2018-04-06, 11:32
  #2991
Medlem
Ranndalls avatar
Försöker förstå begreppet rekursion.

Varför blir inte fak(x) = 1 av denna kod? Den går ju ner till 1, sedan returnerar den 1. Borde väl bli fak(x) = 1 då?


Körning av program:
Kod:
Fakulteten av 5 är 120 
__________________
Senast redigerad av Ranndall 2018-04-06 kl. 11:36.
Citera
2018-04-06, 13:18
  #2992
Avstängd
Citat:
Ursprungligen postat av Ranndall
Varför blir inte fak(x) = 1 av denna kod? Den går ju ner till 1, sedan returnerar den 1.

Ja, men inte till main().
Citera
2018-04-06, 13:50
  #2993
Medlem
Ranndalls avatar
Citat:
Ursprungligen postat av Eliwood
Ja, men inte till main().
Okej.
Uppgift: Vad blir utskriften av följande kod?

Jag trodde den första raden skulle bli typ 2.667? Varför blir det 2.000000 det här fallet? tal1 och tal2 är ju "int" men det skulle väl inte spela någon roll eftersom svar är en "float"?
__________________
Senast redigerad av Ranndall 2018-04-06 kl. 13:52.
Citera
2018-04-06, 16:58
  #2994
Avstängd
Citat:
Ursprungligen postat av Ranndall
Kod:
    int tal1 = 8, tal2 = 3;
    float svar;
    svar = tal1/tal2;

Citat:
Ursprungligen postat av Ranndall
Jag trodde den första raden skulle bli typ 2.667? Varför blir det 2.000000 det här fallet? tal1 och tal2 är ju "int" men det skulle väl inte spela någon roll eftersom svar är en "float"?

Ett uttryck styrs av operatorerna. Varje operator utför en operation. Ordningen beror på prioriteten, med associativiteten (vänster-till-höger eller höger-till-vänster) som tie-breaker när prioriteten är densamma. Operationer utförs alltid på två likadana typer och producerar ett resultat av den typen. Skulle operanderna (värden från variabler, konstanter, funktionsanrop, andra delar av uttrycket, whatever) vara av olika typ, konverteras först den ena.

Reglerna för den automatiska konverteringen har skrivits för att i högsta mån förhindra förlorandet av information. Med två flyttalstyper av olika längd, konverteras den kortare till den längre. Med två heltalstyper av olika längd händer samma sak. Med ett flyttal och ett heltal, konverteras heltalet till flyttalstypen. Blandar man en signed och en unsigned, beror det på om den signade typen kan hålla alla värden som den unsignade typen kan, dvs "är större".

/ har högre prioritet och utförs först. Med två int som operander (och resultat), kastar den bort resten från divisionen. = får resultatet, en int med värdet 2, konverterar det till en float och lagrar den i variabeln svar. Vill du istället utföra en flyttalsdivision, cast:a (konvertera manuellt) den ena operanden till float så konverteras den andra som sagt automatiskt.

Kod:
svar = (float) tal1 / tal2;
__________________
Senast redigerad av Eliwood 2018-04-06 kl. 17:01.
Citera
2018-04-06, 22:43
  #2995
Moderator
Neksnors avatar
Citat:
Ursprungligen postat av Eliwood
Ett uttryck styrs av operatorerna. Varje operator utför en operation. Ordningen beror på prioriteten, med associativiteten (vänster-till-höger eller höger-till-vänster) som tie-breaker när prioriteten är densamma. Operationer utförs alltid på två likadana typer och producerar ett resultat av den typen. Skulle operanderna (värden från variabler, konstanter, funktionsanrop, andra delar av uttrycket, whatever) vara av olika typ, konverteras först den ena.

Reglerna för den automatiska konverteringen har skrivits för att i högsta mån förhindra förlorandet av information. Med två flyttalstyper av olika längd, konverteras den kortare till den längre. Med två heltalstyper av olika längd händer samma sak. Med ett flyttal och ett heltal, konverteras heltalet till flyttalstypen. Blandar man en signed och en unsigned, beror det på om den signade typen kan hålla alla värden som den unsignade typen kan, dvs "är större".

/ har högre prioritet och utförs först. Med två int som operander (och resultat), kastar den bort resten från divisionen. = får resultatet, en int med värdet 2, konverterar det till en float och lagrar den i variabeln svar. Vill du istället utföra en flyttalsdivision, cast:a (konvertera manuellt) den ena operanden till float så konverteras den andra som sagt automatiskt.

Kod:
svar = (float) tal1 / tal2;
Kan vara lämpligt att tydliggöra att hela
Kod:
svar = tal1/tal2
är ett, alltså 1, uttryck (där / utförs först och = sist). På ett mer "matematiskt" sätt kan det skrivas som
Kod:
(svar = (tal1/tal2))
Vill man skriva det som ett "träd" så blir det något i stil med

Kod:
                           =
float svar                                  /
                                  int tal1    int tal2
                                     8             3
__________________
Senast redigerad av Neksnor 2018-04-06 kl. 22:45. Anledning: "Trädet" såg/ser för jävligt ut
Citera
2018-04-06, 22:50
  #2996
Moderator
Neksnors avatar
Citat:
Ursprungligen postat av Ranndall
Försöker förstå begreppet rekursion.

Varför blir inte fak(x) = 1 av denna kod? Den går ju ner till 1, sedan returnerar den 1. Borde väl bli fak(x) = 1 då?


Körning av program:
Kod:
Fakulteten av 5 är 120 
fak(5)
returnerar
5*fak(5-1).
Vad returnerar fak(5-1)? Sätt in det på raden ovanför.
Citera
2018-05-24, 18:11
  #2997
Medlem
Jag har en vector<unique_ptr<X>x; där jag, med hjälp av reset(), tar bort ett element. Detta fungerar, bortsett från att det blir ett "hål", där elementet tidigare var och om jag lägger till ett nytt element, så fylls detta hål, istället för att läggas till längst bak i vectorn (antar att detta beror på den unika pekaren). Det jag skulle vilja göra, är att elementen efter det borttagna elementet flyttas fram ett steg i vectorn och nya element läggs till längst bak. Finns det något bättre sätt att ta bort ett element, än med reset() eller kan jag på något sätt flytta fram de element som ligger efter det borttagna elementet?
Citera
2018-05-25, 07:45
  #2998
Moderator
RostigHinks avatar
Citat:
Ursprungligen postat av Tiger-Lily
Jag har en vector<unique_ptr<X>x; där jag, med hjälp av reset(), tar bort ett element. Detta fungerar, bortsett från att det blir ett "hål", där elementet tidigare var och om jag lägger till ett nytt element, så fylls detta hål, istället för att läggas till längst bak i vectorn (antar att detta beror på den unika pekaren). Det jag skulle vilja göra, är att elementen efter det borttagna elementet flyttas fram ett steg i vectorn och nya element läggs till längst bak. Finns det något bättre sätt att ta bort ett element, än med reset() eller kan jag på något sätt flytta fram de element som ligger efter det borttagna elementet?
reset() antar jag du menar reset(nullptr)? Hur som helst så nollställer reset() endast själva pekarobjektet, vektorn påverkas inte alls utan elementet med det nu tomma pekarobjektet blir kvar. vector har metoden erase() som du kan ta bort elementet med.
Citera
2018-05-25, 08:50
  #2999
Medlem
Citat:
Ursprungligen postat av RostigHink
reset() antar jag du menar reset(nullptr)? Hur som helst så nollställer reset() endast själva pekarobjektet, vektorn påverkas inte alls utan elementet med det nu tomma pekarobjektet blir kvar. vector har metoden erase() som du kan ta bort elementet med.

Tack för tipset!
Citera
2018-05-31, 19:27
  #3000
Medlem
Zabriskie.Points avatar
Ska jag ge mig på C eller C++? Alltså att lära mig. Jag kan redan programmera, men de språk jag har arbetat med är Java, Python och Assembler (för Cortex M - serien, Thumb 2).

Om man lär sig C++, kan man säga att man kan C då med?


Vad ska du göra kanske någon frågar sig då, ingen aning, men jag avslutade precis första året för att bli Civ.Ing i Datateknik, och nu under sommaren tänkte jag ge mig på C eller C++
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback