Avatar billede hclarsen Nybegynder
26. august 2009 - 17:49 Der er 32 kommentarer og
1 løsning

Arrays og pointere

Hej alle

Som bekendt kan man overføre et array til en funktion således

void testfunktion(int testarray[])
{
    printf("test");
}

void main()
{
    int test[]={1,2,3};
    testfunktion(test);
}

Altså står der "int testarray[]=test", og idet vi overfører adressen, kunne vi også have brugt "int *testarray" i stedet for.



Men hvorfor virker følgende ikke?

void main()
{
    int test[]={1,2,3};
int test2[]=test;
    testfunktion(test);
}

når vi kan skrive "int *test2=test"?
Avatar billede arne_v Ekspert
26. august 2009 - 18:10 #1
Man kan ikke assigne arrays paa den maade i C.
Avatar billede arne_v Ekspert
26. august 2009 - 18:12 #2
int *test2=test;

Laver en pointer (typisk 4 byte) som peger paa test.

int test2[3]=test;

Ville hvis det var legal syntax lave et array af 3 int (typisk 3*4 byte = 12 byte) og kopiere data til det.

To helt forskellige ting.
Avatar billede hclarsen Nybegynder
26. august 2009 - 20:06 #3
I din tråd #2: Hvad nu hvis du ikke angiver arrayets størrelse?

I C er det vel ikke helt forkert at sige, at "int test[]" er ækvivalent med "int *test"?
Avatar billede arne_v Ekspert
26. august 2009 - 20:38 #4
Jo det er forkert.

int *test

er en pointer

int test[]

et et array hvor size ses af hooejre side.

Som parametre i funktioner er de det sammen, men ikke naar man definerer variable.
Avatar billede hclarsen Nybegynder
26. august 2009 - 20:51 #5
Hmm, ok. Se følgende:



int testarr[] = {1,2,3};
int *p = testarr; // alt OK indtil videre

Ovenstående kan vi, fordi "testarr" har adressen til første element i arrayet. Men hvordan kan vi gå fra ovenstående til blot at definere

int *p = {1,2,3};

Hvordan vil du forklare det?
Avatar billede arne_v Ekspert
26. august 2009 - 21:31 #6
int testarr[] = {1,2,3};
int *p = testarr;

definerer et array af int med 3 elementer og en pointer som peger paa dette array

int *p = {1,2,3};

definerer en pointer til et navneloest array af int med 3 elementer

(og arrayet i det sidste eksempel kan vaere readonly !)
Avatar billede hclarsen Nybegynder
26. august 2009 - 21:57 #7
Med "forklar" mente jeg, hvorfor det er muligt at definere det således. Hvorfor er det overhovedet muligt at benytte

int *p = {1,2,3};

? Størrelsen "{1,2,3}" er jo ikke en adresse?
Avatar billede arne_v Ekspert
26. august 2009 - 22:02 #8
pointer = array

betyder saet pointer til at pege paa foerste element i array.
Avatar billede hclarsen Nybegynder
26. august 2009 - 22:11 #9
Hvorfor er det, at jeg kan bruge "array"-notation, når jeg har "int *ptr = {1,2,3}"?

I.e., hvorfor kan jeg følgende: ptr[1] == 1?
Avatar billede arne_v Ekspert
26. august 2009 - 22:18 #10
ptr[1] er ikke en pointer men en int

int *ptr = {1,2,3}

saetter en pointer til at pege paa et array

ptr[1] == 1

returnerer true eller false alt efter om den int som er det andet element i det ptr peger paa er 1 eller ej
Avatar billede hclarsen Nybegynder
26. august 2009 - 22:32 #11
1) Nu taler jeg om følgende eksempel:

int *ptr = {1,2,3}

I dette tilfælde, er ptr[1] blot en tilfældig notation, eller er der en logik i at angive det sådan?

Det er dette spørgsmål jeg forsøgte at stille i indlæg #9.


2) Se følgende kode:

int testarr[] = {1,2,3};
int *p = testarr;

Denne kode giver god mening, fordi *p kan indeholde en adresse, og testarr er en adresse.


Se nu følgende kode:

int *p = {1,2,3};

"{1,2,3}" er et array, og ikke en adresse. Mit spørgsmål i indlæg #7 var, om "int *p = {1,2,3}" er en tilfældig notation som K&R i sin tid blot vedtog, eller er der en logik i at skrive det sådan?



____________



I begge spørgsmål forstår jeg, hvad koden gør. Det jeg ønsker forklaret er, hvorfor det kan lade sig gøre. E.g., hvorfor virker "int *p = {1,2,3}" og lign.

Jeg håber ikke du finder, at jeg er tung at danse med, men der er forskel på at lære noget udenad og at forstå noget. Jeg ønsker det sidstnævnte.
Avatar billede arne_v Ekspert
26. august 2009 - 22:41 #12
int *ptr = {1,2,3}

ptr[1] er det andet element i det som ptr peger paa d.v.s. en int med vaerdien 2

ikke tilfaeldigt
Avatar billede arne_v Ekspert
26. august 2009 - 22:42 #13
testarr er ikke en adresse men et array

men

pointer = array

betyder at pointeren saettes til at pege paa det foerste element i arrayet
Avatar billede arne_v Ekspert
26. august 2009 - 22:44 #14
et sprog har en syntax med defineret semantik

det er ikke altid specielt logisk hvad der er muligt og hvad der ikke er muligt

men saa laenge at det er veldefineret saa finder man ud af det
Avatar billede hclarsen Nybegynder
26. august 2009 - 22:54 #15
Angående dine svar til

#1) Ok, så K&R valgte at definere, at når man har "int *p = {1,2,3}", så er betegnelsen p[1] ækvivalent med *(p+1)? Det er bare en notation?

#2) Så K&R valgte ved konvention, at når man har "pointer = array" i C, så betyder det at pointeren peger på arrayets første adresse?

Det er, hvad jeg læser udfra dine svar, og jeg synes det virker meget tilfældigt. Korrigér mig endelig, hvis jeg tager fejl eller har misforstået det.
Avatar billede arne_v Ekspert
26. august 2009 - 23:01 #16
Jeg ville vende den om:

{1,2,3} er et array

array[index] henter element ud af array

pointer = array

saetter pointer til at pege paa foerste element af array

derfor svarer ptr[i] til *(ptr+i)
Avatar billede arne_v Ekspert
26. august 2009 - 23:05 #17
Tilfaeldigt er nok ikke et godt ord.

Men der traeffes nogle valg med hensyn til et sprog.

C/Java/C# bruger = for assignment og == for test
Pascal bruger := for assignment og = for test
VB bruger = for assignment og = for test (konteksten bestemmer hvad det er)

C kan ikke lave array=array
Pascal kan godt lave array=array
Java og C# har kun referancer til arrays saa problemet eksisterer ikke for dem

Forskellige sprog har forskellige regler for ting.
Avatar billede hclarsen Nybegynder
26. august 2009 - 23:12 #18
Ok, det forklarer #1.

Angående #2:

Er "int *p = {1,2,3}" blot en kort skrivemåde for

"int hej[]={1,2,3};
int *p = hej"?
Avatar billede arne_v Ekspert
26. august 2009 - 23:25 #19
Ikke helt.

Den foerste form har ikke hej defineret og data kan ligge i readonly memory.
Avatar billede arne_v Ekspert
26. august 2009 - 23:26 #20
Nu proevede jeg lige.

int *p = {1,2,3};

kompiler slet ikke !?!?

Hvad oversaetter du med?
Avatar billede hclarsen Nybegynder
26. august 2009 - 23:26 #21
I min Schildt-bog står der, at hvis vi har en funktion

void test(int arr[]),

så konverterer C-kompileren selv int arr[] til en int *arr. Er dette korrekt?
Avatar billede hclarsen Nybegynder
26. august 2009 - 23:32 #22
Min kompilerer heller ikke. Vi bruger char *hej = "boef" istedet for så :-)
Avatar billede arne_v Ekspert
26. august 2009 - 23:36 #23
Den konverterer saadan set ikke noget.

Men du kan bruge den som begge.

I denne kontekst er der ikke forskel paa de to.

Det er samme instruktioner som genereres.
Avatar billede arne_v Ekspert
26. august 2009 - 23:39 #24
Forskellen ses her:

#include <stdio.h>

int main()
{
    char s1[] = "ABC";
    char *s2 = "DEF";
    /* dette udskriver AXC */
    s1[1] = 'X';
    printf("%s\n", s1);
    /* dette crasher eller udskriver DXF */
    s2[1] = 'X';
    printf("%s\n", s2);
    return 0;
}
Avatar billede hclarsen Nybegynder
26. august 2009 - 23:53 #25
#1) Jeg kan ikke gennemskue, hvilken logik der tillader at vi kan bruge

void test(int arr[]),

når int arr[] skal indeholde en adresse.


2) Ok, så sætningen " char *s = "hej"; " opretter et read-only array, og sætter *s til at have adresen på første tegn.

Kan du, ligesom i dit indlæg #16, give en logisk forklaring på hvorfor man kan læse sætningen sådan? Eller er det noget, som K&R bare besluttede?
Avatar billede arne_v Ekspert
27. august 2009 - 00:12 #26
Fordi C sender et array over som en adresse.

Ja.
Avatar billede arne_v Ekspert
27. august 2009 - 00:16 #27
paa et gaengs 32 bit system vil:

char s1[] = "ABC";

lave 4 bytes i readwrite memory med vaerdierne 65, 66, 67, 0

char *s2 = "DEF";

lave 4 bytes i readonly memory med vaerdierne 65, 66, 67, 0 og 4 bytes i readwrite memory med adressen paa de foerste bytes

s1[1] tager adressen paa de 4 bytes og ligger 1 til

s2[1] tager pointer varedien og ligger 1 til
Avatar billede hclarsen Nybegynder
27. august 2009 - 00:21 #28
Angående #1:

Det jeg mente var, at funktionen overfører som bekendt kun adressen på arrayet.

Men funktionens parametejava script:%20void(0);r er int arr[], som skal indeholde talværdier, i.e. {1,2,3,...}. Hvordan kan den blive sat lig med en adresse?

int arr[] = adresse.
Avatar billede arne_v Ekspert
27. august 2009 - 01:18 #29
I C overfoeres array altid som adressen paa foerste element.
Avatar billede hclarsen Nybegynder
27. august 2009 - 09:24 #30
Jeg ved, at C overfører arrays som adressen på første element i arrayet.

Funktionsparameteren er et array, som er tiltænkt at skulle indeholde talværdier.

Hvordan er det muligt for et array at blive sat lig med en adresse så? Følgende er nemlig ikke muligt

char s[] = "hej;
char s1[] = s;

Der melder den fejl.
Avatar billede arne_v Ekspert
27. august 2009 - 18:49 #31
Der bruger du igen:

array = array
Avatar billede arne_v Ekspert
13. september 2009 - 02:26 #32
all set ?
Avatar billede hclarsen Nybegynder
13. september 2009 - 09:44 #33
Jeg må indrømme, at jeg ikke fik de detaljerede svar som jeg havde håbet på.

Men ikke desto mindre synes jeg du skal have pointene.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester