Gå til innhold

Anbefalte innlegg

Hei.

 

Leste igjennom Jaffe sin Wiki om C tidligere i dag og bestemte meg for å lage et "Tre på rad" spill. Etter å ha koda littegrann fant jeg ut at C er ganske rart i forhold til Java (som jeg hovedsakelig kan best), det er så slitsomt å holde styr på rekkefølger osv.

 

Men over til problemet. Jeg har da som sagt koda littegrann og har havna oppi et lite problem.

 

TrePaaRad.c:

#include <stdio.h>

// Informasjon om spillerne
typedef struct
{
char navn[20];
int alder;
char tegn;
} spiller;

// Funksjons headere
spiller LagSpiller(int spiller_nr, char tegn);

// Globale variabler
spiller spiller1;
spiller spiller2;

int main(void)
{
printf("Velkommen til Tre på rad!\n\n");
spiller1 =LagSpiller(1, 'X');
spiller2 = LagSpiller(2, 'O');
return 0;
}

spiller LagSpiller(int spiller_nr, char tegn)
{
spiller _spiller;

printf("Lag spiller %i:\n", spiller_nr);
printf("Navn: ");
scanf("%s", _spiller.navn);
printf("Alder: ");
scanf("%i", _spiller.alder);
printf("\n");
_spiller.tegn = tegn;

return _spiller;
}

Av denne koden får jeg en feilmelding etter spiller1 er registrert:

Program has been terminated receiving signal 11 (Segmentation fault)

Press the Enter key to close this terminal ...

Noen som vet hva som er galt i koden min?

Lenke til kommentar
Videoannonse
Annonse
Takk, det fungerte. Jaffe sin guide er ikke ferdig, så jeg leste ingenting om pekere. Dette er vel noe av det jeg må lære meg!

8959904[/snapback]

 

At du må ha & foran variabelnavn (slik at scanf får hvor den skal lagre det inntastede tallet) står nevnt i guiden.

Lenke til kommentar

Hehe, greit ;) Men det jeg mente var at det ikke er et eget kapittel enda om pekere. Kjempefin guide forresten!

 

Men jeg har nå kjøpt meg boka "The C programming language" og har lest litt om pekere der. Jeg skjønte forsåvidt at man kan endre verdien i flere variabler på en gang ved at variablene har samme minneadresse osv, men jeg skjønner ikke helt poenget (vant til Java vett). Også skjønte jeg ikke helt når man skal bruke * og når man skal bruke &. Slik jeg tolket det er * til å deklarere en variabel som man skal peke mot en annen variabel, mens & er variablen som * peker mot?

Endret av kjey
Lenke til kommentar

En ting som er forvirrende med pekere er at * betyr to forskjellige ting i definisjonen og selve bruken av pekeren.

 

I en variabeldefinisjon betyr * at en peker av den typen blir definert.

Når vi bruker pekeren (altså utenfor definisjonen) og Har * foran pekeren vil det føre til at vi får det pekeren peker til, altså innholdet i den adressen den peker til. Dersom vi ikke har * foran pekeren, får vi adressen som pekeren holder. Har man & foran en peker igjen, får man adressen til pekeren i minnet. Et program for å illustrere:

 

CODE

#include <stdio.h>

 

int main(void)

{

int a = 1234;

int* p = &a;

 

printf("Pekeren p peker til adresse %d\n", p);

printf("Innholdet i den adressen er %d\n", *p);

printf("Pekeren selv ligger i adresse %d\n", &p);

printf("Variabelen a inneholder %d\n", a);

printf("Variabelen a ligger i adresse %d\n", &a);

return 0;

}

 

Ved kjøring av programmet fikk jeg følgende utskrift:

 

Pekeren p peker til adresse 2293620

Innholdet i den adressen er 1234

Pekeren selv ligger i adresse 2293616

Variabelen a inneholder 1234

Variabelen a ligger i adresse 2293620

 

Merk at adressen til a (&a) og pekeren p (p) er like. Merk også at innholdet av a (a) og det p peker til (*p) er det samme.

 

Men det er såklart totalt unyttig å bruke en peker til noe slikt. Pekere er egentlig (stort sett) bare nyttige når man allokerer minne når programmet kjører. Dette er grunnen til at jeg ikke har tatt det med i boka enda.

Endret av Jaffe
Lenke til kommentar

& er reference operatoren, returnerer minne-adresse

* er dereference operatoren, returnerer det pekeren peker til (f.eks. et tall)

 

Pekere kan være nyttige i flere sammenhenger. F.eks. ved å iterere gjennom en array.

 

Funksjonspekere er også noe som kan være veldig nyttig, men disse kan være veldig forvirrende, spesielt i starten, så de er det kanskje greit å vente med. :)

 

Edit: ...

Endret av staalezh
Lenke til kommentar
Jeg ser ikke helt hva som er nyttig med å bruke en peker i stedet for indekseringsoperatøren når man itererer over en tabell, og i alle fall ikke for folk som er vant med Java?

8976702[/snapback]

 

Offtopic:

Jeg leste tidligere i en guide fra AMD at de fleste kompilatorer greier og optimaliserer mer hvis man bruker indekseringsoperatøren istede for pekere.

Og i koden blir letere å forstå (syntes jeg) ved bruk at indekseringsoperatøren.

Så jeg støtter Jaffe sin mening

Lenke til kommentar
Jeg er klar over at det er ett fett hva man bruker, men det var beregnet som et eksempel på nyttig bruk av pekere annet enn allokering. :)

8982794[/snapback]

 

Jeg forstår at det er det du mener, men pekere er ikke nyttige til dette, i motsetning til f.eks. minneallokering der de brukes.

 

Forresten, eksempelet ditt er feil. For-løkka vil antageligvis gå uendelig siden i aldri blir lik 10 (med mindre arrayet mystisk nok ligger i det området, noe det mest sannsynlig ikke gjør.) Du mente kanskje for (i = b; i != b+10; i++) eller noe lignende, som egentlig bare blir mer rotete enn å bruke indeksering?

Endret av Jaffe
Lenke til kommentar

Hehe, det stemmer. Jeg tenke for mye på iteratorer i C++. :p

const int array_size = 10;
int array[array_size];
int* end = &array[array_size+1];

for(int* p = array; p != end; ++p)
  *p = 0;

Jeg vil allikevel påstå at dette er nyttig, selv om det kan diskuteres til hvilken grad.

:)

 

Edit: omg

Endret av staalezh
Lenke til kommentar
Hehe, det stemmer. Jeg tenke for mye på iteratorer i C++. :p

const int array_size = 10;
int array[array_size];
int* end = array[array_size+1];

for(int* p = array; p != end; ++p)
  *p = 0;

Jeg vil allikevel påstå at dette er nyttig, selv om det kan diskuteres til hvilken grad.

:)

8988959[/snapback]

 

Her er nok en feil: Du gir pekeren end verdien i element 10 av array og ikke adressen.

 

EDIT: Det er riktignok bare å sette inn en &: int* end = &array[array_size+1];

 

Jeg syns det begynner å bli rimelig klart at dette er unyttig, i hvertfall i en for-loop der man enkelt kan bruke indeksering uten å sette opp to pekere.

Endret av Jaffe
Lenke til kommentar

Dette var et eksempel for å illustrere. Jeg har ikke testet koden (så syntaksfeil forekommer), og det er heller ikke ment som et revolusjonerende alternativ til indeksering. Det var et eksempel på enkel bruk av pekere til annet enn minneallokering.

 

Å si noe annet enn at pekere er nyttige er feil. I C++ brukes de blant annet til arv/polymorfi, chesire cat classes og reference counting, osv, er helt klart ting der peker er nyttige. Men jeg tenkte som så at det kanskje ikke er så lurt å dra inn konkrete eksempler med dette, da det fort kan bli forvirrende for en nybegynner.

 

Edit: leif

Endret av staalezh
Lenke til kommentar
Dette var et eksempel for å illustrere. Jeg har ikke testet koden (så syntaksfeil forekommer), og det er heller ikke ment som et revolusjonerende alternativ til indeksering. Det var et eksempel på enkel bruk av pekere til annet enn minneallokering.

 

Å påstå at pekere ikke er nyttige er feil. I C++ brukes de blant annet til arv/polymorfi, chesire cat classes og reference counting, osv, er helt klart ting der peker er nyttige. Men jeg tenkte som så at det kanskje ikke er så lurt å dra inn konkrete eksempler med dette, da det fort kan bli forvirrende for en nybegynner.

8989139[/snapback]

 

Les tittelen på denne tråden er du snill. Syns jeg ser en C i parantes jeg?

Lenke til kommentar

Uansett hva dere vil krangle dere frem til er det helt essensielt å vite hva pekere er og hvordan de fungerer i både C og C++. Dette viser man best ved å ha en del eksempler, og selv om staalezh løkke kan erstattes med mer optimalisert kode/færre variabler, så viser den èn av flere måter pekere _kan_ brukes på og hvordan de virker.

Lenke til kommentar
Jeg tok det med fordi det er relevant i et C/C++ forum... Nå får du se ting i et litt større perspektiv her.

8989162[/snapback]

 

Det kan man jo si i en hver sammenheng, i hvilken som helst tråd. Grunnen til at man oppretter tråder er vel for å ha en viss struktur og ryddighet, i stedet for at folk bare poster vilt? Her snakker trådstarter om C, og da kan vi vel holde oss til C? Hadde jeg opprettet en tråd der jeg trenge hjelp til noe, spesielt hvis jeg var en nybegynner i språket, er urelevante ting det siste jeg ville hatt der.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...