Vinnaren i pepparkakshustävlingen!
2017-11-25, 03:13
  #2941
Medlem
Citat:
Ursprungligen postat av smellyproof
Någon pedagogisk som kan förklara vad pekare är för något? Vad ar det för syfte. ex *char det hör ihop med variabler förstår jag.

Pekare är precis vad som namnet innebär, de syftar liksom på ställen i minnet istället för att själva innehålla data.

Kod:
int i = 8;
int *p = &i; //& skapar en pekare, alltså syftar pekaren p på i. nu innehåller p en minnesadress istället för någon slags data.

//vi kan komma åt det som p syftar på genom att skriva *p, så kallas det en dereference.

*p = 2; //förändra data som p syftar på, sen innehåller i 2
printf("%d\n", i); //visa förändringen

Det är viktigt att man lär sig använda pekare för de kommer väl till pass när man jobbar med till exempel struct:er. Föreställ dig att man har skrivit en struct och vill komma åt och jobba med structen i en funktion.

Kod:
struct thing
{
    int a;
    int b;
};

void do_something(thing A)
{
    A.a = 1;
}

int main(int argc, char **argv)
{
    thing x;
    do_something(x);
    printf("%d\n", x.a);
    //Ska x.a vara 1 efteråt? Vad tror du? Läs följande förklaringen eller kör själv...
}

Eftersom C/C++ använder pass-by-value-systemet, ska den ovanstående funktionen do_something ta emot ett helt objekt, alltså ska x kopieras och sen ska kopian skickas till funktionen när man kallar den. Om man inte vill att funktionen ska ta emot en kopia utan objektet direkt, för att man vill ändra på objektet och vill att förändringarna ska synas av den kallande funktionen, blir det lite jobbigt om funktionen bara tar emot en kopia.

Dessutom är det inte så bra när det gäller prestanda. Tänk på om det finns många element inom struct:en som måste kopieras, så blir det uppenbart varför.

Alltså finns pekare. Man kan köra pekare istället för kopior, såhär:

Kod:
void do_something(thing * A)
{
    A->a = 1;
}

int main(int argc, char **argv)
{
    thing x;
    do_something(&x);
    printf("%d\n", x.a);
}

Med pekare kan man lätt göra sånt.

Ställ frågor om det var nånting oklart eller du vill få ett till exempel...
__________________
Senast redigerad av kanes272 2017-11-25 kl. 03:15.
Citera
2017-11-25, 10:35
  #2942
Moderator
RostigHinks avatar
Det kan även vara bra att veta att namnen på arrayer är implicita pekare. Därför blir nedanstående exempel "call by reference" dvs pekaren till arrayen skickas med anropet.
Kod:
#include <stdio.h>

void doSomething(int a[]) {
  a[0] = 2;
}

int main() {
  int arr[2] = {0, 0};

  doSomething(arr);
  printf("%d\n", arr[0]);
}
Just detta är nog det som förvirrar nybörjare i C mest. Det kan hjälpa om man vet att arrayer kan indexeras på två sätt, de är ekvivalenta:
Kod:
 a[1] = 1;
*(a + 1) = 1;
Citera
2017-11-26, 03:22
  #2943
Avstängd
Citat:
Ursprungligen postat av smellyproof
Någon pedagogisk som kan förklara vad pekare är för något? Vad ar det för syfte. ex *char det hör ihop med variabler förstår jag.

Tänk dig att du jobbar hos en handlare av klockor. Lagret är några mil långt, och inga produkter staplas bakom eller på varandra utan står på en lång rad (datorns minne). De flesta klockorna är små (inbyggda typer som char, short, int och long) och det är enklare att ge en direkt till reparatören (funktionen) än att skriva en lapp (pekare) till honom var klockan finns. En lapp är ungefär lika stor som en klocka.

Men en 10 meter bred klocka är jobbig att släpa på. Ge reparatören, som liksom resten av personalen har ett IQ på 25 och bara gör vad de blir tillsagda, en lapp och säg att han får arbeta på plats. Och var försiktig att inte ge kopior av lappen till flera personer samtidigt, så en sätter igång att måla klockan medan en annan fortfarande håller på och tvättar den.

Ibland vill man såklart ha en uppsättning likadana böcker tillsammans (array) på lagret, t.ex de 60 som ska till damlandslaget, för att inte behöva leta efter varje enskild. Då kan man ge killen som klistrar dit #metoo-stickern, en lapp med platsen till den första av dem (pekare) och en annan som talar om hur många till höger om den han ska behandla (vilken heltals-typ som helst, men kolla typen size_t som är särskilt för att ange längd/storlek).

När det konstant säljs och kommer in fläktar av olika storlekar, och speciellt större partier, blir det tomrum lite här och var (minnesfragmentering), men det är sällan problem eftersom minnet är så stort och arrayer man skapar bara brukar vara några procent av det. Fragmentering av enskilda arrayer är knepigare om man behöver kunna lägga till och/eller plocka bort element, för varje gång skapas det ju eller behöver skapas ett tomrum så att man måste flytta efter alla element till höger eller vänster om platsen.

Då fungerar länkade listor bättre, där varje element innehåller 1) datat för det elementet 2) en pekare till nästa element och eventuellt 3) en pekare till föregående element. Varje element kan placeras var som helst på lagret där det finns plats, de behöver inte ligga på rad. Nackdelen är att det tar längre tid att hitta t.ex. element nr 155, eftersom man måste springa 154 gånger till nästa element och kolla adressen till nästa.
__________________
Senast redigerad av B-programmerare 2017-11-26 kl. 03:47.
Citera
2017-12-12, 18:39
  #2944
Medlem
Citat:
Ursprungligen postat av lazyass
Har fått något besynnerligt problem i mina noob ögon. När jag kör min kod så verkar programmet inte köra igenom all kod och levererar ett konstigt resultat. Vad är det för fel? Mvh Lazy

#include <iostream>

using namespace std;

void Sortera(int vekt[], int n);



int main (){
int j;
int i;
double summa;

//benämning av nummer sekvens.
double array[ ]={i}; //Sparar variable sekvens
//int length = sizeof (array)/ sizeof (int) Beräknar medelvärde med binära tal.


for (i=0; i<10;i++) {
if (array[i]==0){
break;
}
cout<< "skriv in nummer " << i+1<< " "<< endl;
cin>> array[i];

}
//skriver ut talföljden

for (i=0; i<10;i++){
if (array[i]==0){
break;
}
cout<< array[i]<< endl;}


//skriva en sträng som summerar ihop listan
//summa = array[j++]
for (i=0; i<10;i++){
if (array[i]==0){
break;}
summa += array[i];

}
cout<< "Summa" << summa << endl;
//skriva ihop sortera
}

https://www.flashback.org/announcement.php?f=205
Citera
2017-12-12, 19:05
  #2945
Medlem
lazyasss avatar
Får en be sinnerlig utskrift när jag kör koden, och har ingen aning om varför. Det är som den bara hoppar över looparna och får inget resultat mer än en utskrift summa1.4822e-323 . som jag inte förstår något av efter google sökning. Hoppas att med lite hjälp och vaselin så kanske det kan gå in i huvudet.
Kod:
#include <iostream>

using namespace std;

void Sortera(int vekt[], int n);



int main (){
    
int j;
    
int i;
    
double summa;
    
     
//benämning av nummer sekvens. 
    
double array[ ]={i}; //Sparar variable sekvens 
    //int length = sizeof (array)/ sizeof (int) Beräknar medelvärde med binära tal. 
    

    
for (i=0i<10;i++) {
            if (array[
i]==0){
            break;
            }
        
cout<< "skriv in nummer " << i+1<< " "<< endl;
        
cin>> array[i];
        
    }
    
//skriver ut talföljden
        
        
for (i=0i<10;i++){
            if (array[
i]==0){
            break;
            }
    
cout<< array[i]<< endl;}
    
    
    
//skriva en sträng som summerar ihop listan
    //summa = array[j++]
    
for (i=0i<10;i++){
            if (array[
i]==0){
            break;}
        
summa += array[i];
        
    }
    
cout<< "Summa" << summa << endl;
    
//skriva ihop sortera 

Citera
2017-12-12, 19:34
  #2946
Medlem
Citat:
Ursprungligen postat av lazyass
Får en be sinnerlig utskrift när jag kör koden, och har ingen aning om varför. Det är som den bara hoppar över looparna och får inget resultat mer än en utskrift summa1.4822e-323 . som jag inte förstår något av efter google sökning. Hoppas att med lite hjälp och vaselin så kanske det kan gå in i huvudet.
Kod:
#include <iostream>

using namespace std;

void Sortera(int vekt[], int n);



int main (){
    
int j;
    
int i;
    
double summa;
    
     
//benämning av nummer sekvens. 
    
double array[ ]={i}; //Sparar variable sekvens 
    //int length = sizeof (array)/ sizeof (int) Beräknar medelvärde med binära tal. 
    

    
for (i=0i<10;i++) {
            if (array[
i]==0){
            break;
            }
        
cout<< "skriv in nummer " << i+1<< " "<< endl;
        
cin>> array[i];
        
    }
    
//skriver ut talföljden
        
        
for (i=0i<10;i++){
            if (array[
i]==0){
            break;
            }
    
cout<< array[i]<< endl;}
    
    
    
//skriva en sträng som summerar ihop listan
    //summa = array[j++]
    
for (i=0i<10;i++){
            if (array[
i]==0){
            break;}
        
summa += array[i];
        
    }
    
cout<< "Summa" << summa << endl;
    
//skriva ihop sortera 


Du initierar arrayen till att ha endast ett värde, det av i, som du inte definierar. Klarar du av att kompilera koden kommer i, som du lägger in i arrayen på index 0, kanske ha värde 0, och i varje loop avbryter du loopen ifall index 0, har värde 0. När du sedan ska skriva ut summan skriver du istället ut vad som finns i den minnesplats som summa ska ha, men eftersom du inte definierat summa, kan värdet vara lite vad som helst.


Ändra början av programmet till:
Kod:
int j = 0;
int i = 0;
double summa = 0.0;

double array[10]; // då användaren inte blivit tillsagt om att använda decimaler kanske det är bättre med int?

Sen kanske det är bra att lägga till ett mellanslag i sista utskriften.
__________________
Senast redigerad av Gottisborgen 2017-12-12 kl. 19:44.
Citera
2017-12-12, 19:42
  #2947
Medlem
lazyasss avatar

Tack så mycket för hjälpen
Citera
2017-12-12, 20:28
  #2948
Medlem
lazyasss avatar
Citat:
Ursprungligen postat av Gottisborgen
Du initierar arrayen till att ha endast ett värde, det av i, som du inte definierar. Klarar du av att kompilera koden kommer i, som du lägger in i arrayen på index 0, kanske ha värde 0, och i varje loop avbryter du loopen ifall index 0, har värde 0. När du sedan ska skriva ut summan skriver du istället ut vad som finns i den minnesplats som summa ska ha, men eftersom du inte definierat summa, kan värdet vara lite vad som helst.


Ändra början av programmet till:
Kod:
int j = 0;
int i = 0;
double summa = 0.0;

double array[10]; // då användaren inte blivit tillsagt om att använda decimaler kanske det är bättre med int?

Sen kanske det är bra att lägga till ett mellanslag i sista utskriften.

Jag gjorde som du sa och bytte även plats på första if satsen sedan fungerade det utmärkt. Tackar igen för hjälpen gjorde min dag mycket enklare.
Citera
2017-12-12, 22:42
  #2949
Medlem
lazyasss avatar
Fick lite mera konstigheter som jag inte förstår. När programmet beräknar ut det största och näst största talen så fixar inte det riktigt om man avslutar program sekvensen med 0 vilket gör att jag kan få helt absurt felaktiga tal och som inte är inmatade.
Kod:
#include <iostream>

using namespace std;



int main (){
    
setlocale(LC_ALL,"");
    
    
int j 0;
    
int i 0;
    
float summa 0.0;
     
//benämning av nummer sekvens. 
    
int array [10]; //Sparar variable sekvens 
    //int length = sizeof (array)/ sizeof (int) Beräknar medelvärde med binära tal. 
    
int ain = -1//antal inmatningar 

    
for (i=0i<10;i++) {
        
cout<< "skriv in nummer " << i+1<< ": "<< endl;
        
cin>> array[i];
        
ain++;
                    if (array[
i]==0){
            break;
            }
    }



    
//skriver ut talföljden
        
        
for (i=0i<10;i++){
            if (array[
i]==0){
            break;
            }
    
cout<< array[i]<< " ";}
    
    
cout<< endl;
    
//Summerar ihop listan.
    
for (i=0i<10;i++){
            if (array[
i]==0){
            break;}
        
summa += array[i];
        
    }
    
cout<< "Summa:" << summa << endl;
    
//Sortera ut det största och näst största talen. 

int st 0;//störstatalet
int nst 0;//näst största talet

    
    
for(i=0;i<10;i++){
        if (
st<=array[i]){
        
st = array[i];}
        else {
            if(
nst < array[i])
        
nst=array[i];}
    }
    
cout << "Största talet:"<< st<< endl;
    
cout << "Näst största talet:"<< nst << endl;


//Beräkna medelvärdet
float mv;

mv summa/ain;
cout <<"Medelvärdet:"<< mv << endl

cout << ain;
    
    
    
    


Här någonstans ligger problemet tror jag.
Kod:
//Sortera ut det största och näst största talen. 

int st 0;//störstatalet
int nst 0;//näst största talet

    
    
for(i=0;i<10;i++){
        if (
st<=array[i]){
        
st = array[i];}
        else {
            if(
nst < array[i])
        
nst=array[i];}
    }
    
cout << "Största talet:"<< st<< endl;
    
cout << "Näst största talet:"<< nst << endl
Citera
2017-12-13, 01:49
  #2950
Avstängd
Citat:
Ursprungligen postat av lazyass
Fick lite mera konstigheter som jag inte förstår. När programmet beräknar ut det största och näst största talen så fixar inte det riktigt om man avslutar program sekvensen med 0 vilket gör att jag kan få helt absurt felaktiga tal och som inte är inmatade.

Citat:
Ursprungligen postat av lazyass
Här någonstans ligger problemet tror jag.
Kod:
//Sortera ut det största och näst största talen. 

int st 0;//störstatalet
int nst 0;//näst största talet

    
    
for(i=0;i<10;i++){
        if (
st<=array[i]){
        
st = array[i];}
        else {
            if(
nst < array[i])
        
nst=array[i];}
    }
    
cout << "Största talet:"<< st<< endl;
    
cout << "Näst största talet:"<< nst << endl

Utan `if (array[i]==0) break;` i loopen, läser den alla tio elementen.

`int array [10];` ger tio ints utrymme i minnet men sätter dem inte till något. Elementen är odefinierade, och programmet får odefinierat beteende (vad som helst kan hända) om man läser från ett av dem innan man har satt det / skrivit till det en första gång. Detsamma gäller vanliga variabler också.

Odefinierat beteende betyder inte att datorn måste göra något särskilt för dig, utan tvärtom att den får göra vad som helst. Och vad är väl enklare/snabbare än att inte hålla någon koll på eller bry sig alls vad du har initierat eller inte, utan bara läsa det som finns i minnet. Det finns alltid något i en minnesplats, den kan inte vara "tom" (*). Så det är vad alla normala datorer gör. Slutet av arrayen, efter 0:an som du terminerar med, kan innehålla t.ex. skräp från uppstarten eller data från ett annat program som hade minnet innan.

Håller du dig inte ens innanför arrayens gränser utan börjar läsa bortanför den, med typ array[5000], kan du hamna t.ex. bland andra variabler i ditt program, eller i ett annat programs privata minne och krascha med segmentation fault / access violation. Det beteendet är också odefinierat.

(*) Tror att det finns datorer med minnen som inte alltid har något på minnesplatser. Då blir det odefinierade beteendet något annat.
__________________
Senast redigerad av SuperSizeMe 2017-12-13 kl. 01:54.
Citera
2017-12-13, 18:44
  #2951
Medlem
lazyasss avatar
Citat:
Ursprungligen postat av SuperSizeMe
Utan `if (array[i]==0) break;` i loopen, läser den alla tio elementen.

`int array [10];` ger tio ints utrymme i minnet men sätter dem inte till något. Elementen är odefinierade, och programmet får odefinierat beteende (vad som helst kan hända) om man läser från ett av dem innan man har satt det / skrivit till det en första gång. Detsamma gäller vanliga variabler också.

Odefinierat beteende betyder inte att datorn måste göra något särskilt för dig, utan tvärtom att den får göra vad som helst. Och vad är väl enklare/snabbare än att inte hålla någon koll på eller bry sig alls vad du har initierat eller inte, utan bara läsa det som finns i minnet. Det finns alltid något i en minnesplats, den kan inte vara "tom" (*). Så det är vad alla normala datorer gör. Slutet av arrayen, efter 0:an som du terminerar med, kan innehålla t.ex. skräp från uppstarten eller data från ett annat program som hade minnet innan.

Håller du dig inte ens innanför arrayens gränser utan börjar läsa bortanför den, med typ array[5000], kan du hamna t.ex. bland andra variabler i ditt program, eller i ett annat programs privata minne och krascha med segmentation fault / access violation. Det beteendet är också odefinierat.

(*) Tror att det finns datorer med minnen som inte alltid har något på minnesplatser. Då blir det odefinierade beteendet något annat.
Aha sådär tänk att det var en sådan skit sak. Tack så mycket.
Citera
2018-01-12, 16:01
  #2952
Medlem
smellyproofs avatar
Tentauppgift:

Behöver inte en hel kod för ovanstående uppgift. Funderar mest på hur man skriva ut bokstäver på detta sätt? Är det så att "char bokstav = 0" motsvar = a osv?
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