12 svar
103 visningar
mekatronik är nöjd med hjälpen
mekatronik 613
Postad: 23 aug 2022 09:24 Redigerad: 23 aug 2022 09:36

Pekar som är initierad till en array och en integer

Hej, jag har en liten snabb fråga ang ptr1 här:

ptr1 är initierad till arr+1, jag tänker då att det bör vara nästa adress dvs att ptr1 bör peka på det andra elementet i arrayen. Men enligt facit pekar den på det första elementet. Varför är det så? 

Laguna 28443
Postad: 23 aug 2022 09:47

Det är svårläst. Kan du skriva in det som ren text?

mekatronik 613
Postad: 23 aug 2022 09:51
Laguna skrev:

Det är svårläst. Kan du skriva in det som ren text?

Det är egentligen bara den här delen jag inte förstår:

int arr[] = {1,2,3};

int *ptr1 = arr + 1; 

Förstår inte varför ptr1 pekar på det första elementet och inte det andra? Enligt facit skall den göra det innan funktionen exekveras 

CurtJ 1141
Postad: 23 aug 2022 09:52

Gör som det står i uppgiften och rita bilder över hur minnet är använt för de olika variablerna och pekarna. En integer upptar mer utrymme än en byte, det är nyckeln.

mekatronik 613
Postad: 23 aug 2022 09:54
CurtJ skrev:

Gör som det står i uppgiften och rita bilder över hur minnet är använt för de olika variablerna och pekarna. En integer upptar mer utrymme än en byte, det är nyckeln.

Alltså det är inte själva uppgiften som är problemet, jag har bara svårt att förstå varför ptr1 pekar på första elementet i arrayen. Jag tänker att den bör peka på det andra med tanke på att man utför arr + 1 i initieringen? 

Om det bara hade stått arr i initieringen hade det inte varit så konstigt, då vet jag att den pekar på det första elementet.

CurtJ 1141
Postad: 23 aug 2022 10:15

Med det så förtsätter du att storleken på ett element i arrayen är 1 enhet lång?  Enhet i det här fallet är en byte.

mekatronik 613
Postad: 23 aug 2022 10:20
CurtJ skrev:

Med det så förtsätter du att storleken på ett element i arrayen är 1 enhet lång?  Enhet i det här fallet är en byte.

Ah okey då förstår jag, blev väldigt förvirrad eftersom man senare i uppgiften jämför ptr1 och ptr3. Men jag antar att increment och decrement i C förstår då att den skall ta *4 för att flytta pekaren?

CurtJ 1141
Postad: 23 aug 2022 10:24 Redigerad: 23 aug 2022 10:25

Ja kompilatorn vet att det är en int-pekare och när du inkrementerar den så vet kompilatorn att den ska flytta den till nästa int-element som i de vanligaste arkitekturerna nu är 2 eller 4 byte. När initieringen av ptr1 görs till arr+1 tolkar kompilatorn det som adressen till det första elementet + 1 byte, dvs pekaren pekar in i det första elementet. Pekararitmetik i C är kraftfullt men knepigt och man har olika strategier för att förvissa sig om att det är rätt. Den första strategin är att förstå hur det fungerar och för det är mycket praktik, tester och felsökningar en bra väg till framgång.

mekatronik 613
Postad: 23 aug 2022 10:25
CurtJ skrev:

Ja kompilatorn vet att det är en int-pekare och när du inkrementerar den så vet kompilatorn att den ska flytta den till nästa int-element som i de vanligaste arkitekturerna nu är 2 eller 4 byte. När initieringen av ptr1 görs till arr+1 tolkar kompilatorn det som adressen till det första elementet + 1 byte, dvs pekaren pekar in i det första elementet. Pekararitmetik i C är knepigt och man har olika strategier för att förvissa sig om att det är rätt. Den första strategin är att förstå hur det fungerar och för det är mycket praktik, tester och felsökningar en bra väg till framgång.

Tack så mycket, väldigt klart och tydligt!

manik 82
Postad: 23 aug 2022 10:58

Det här stämmer inte

När initieringen av ptr1 görs till arr+1 tolkar kompilatorn det som adressen till det första elementet + 1 byte, dvs pekaren pekar in i det första elementet.

Du kan kontrollera med printf(), %p skriver ut en pekares adress.

#include <stdio.h>
int main() {
    int arr[] = {1, 2, 3};
    int *ptr1 = arr + 1;
    printf("arr=%p ptr1=%p *ptr1=%d diff=%ld\n", arr, ptr1, *ptr1, ptr1 - arr);
}

=> arr=0x7ffc32942acc ptr1=0x7ffc32942ad0 *ptr1=2 diff=1

 

ptr1 pekar alltså på det andra elementet, arr[1].

arr = {
  1,      arr[0]
  2,      arr[1]   <= ptr1
  3       arr[2]
}

anders_k Online 234
Postad: 23 aug 2022 11:46

ptr1 initialt pekar på andra elementet i arr[]

men på rad 4 så dekrementeras pekaren ptr1-- som då landar på först elementet i arr[]

int* ptr3 = ptr1--; // nu pekar ptr1 på &arr[0]
mekatronik 613
Postad: 23 aug 2022 12:20 Redigerad: 23 aug 2022 12:28
manik skrev:

Det här stämmer inte

När initieringen av ptr1 görs till arr+1 tolkar kompilatorn det som adressen till det första elementet + 1 byte, dvs pekaren pekar in i det första elementet.

Du kan kontrollera med printf(), %p skriver ut en pekares adress.

#include <stdio.h>
int main() {
    int arr[] = {1, 2, 3};
    int *ptr1 = arr + 1;
    printf("arr=%p ptr1=%p *ptr1=%d diff=%ld\n", arr, ptr1, *ptr1, ptr1 - arr);
}

=> arr=0x7ffc32942acc ptr1=0x7ffc32942ad0 *ptr1=2 diff=1

 

ptr1 pekar alltså på det andra elementet, arr[1].

arr = {
  1,      arr[0]
  2,      arr[1]   <= ptr1
  3       arr[2]
}

Såhär står det i facit som min lärare gjort:

CurtJ påstående stämmer även överens med lösningen som koden ger, så det bör stämma!

CurtJ 1141
Postad: 23 aug 2022 17:26

Jag pudlar, både manik och anders_k har rätt och det är kompatibelt med lösningen i ditt facit. Som sagt, pekare är knepigt och jag lite rostig när det gäller c. Uppenbart är att kompilatorn vet att int-pekaren stegas upp ett element i taget.

Svara Avbryt
Close