Avatar billede hclarsen Nybegynder
06. juli 2008 - 16:18 Der er 12 kommentarer og
1 løsning

Forklaring af pointer-kode

Når vi betragter et array bestående af integers:

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

I dette tilfælde er adressen (p+n) det samme som &test[n], hvor n er et heltal.

Hvis vi derimod betragter et array bestående af chars:

char str[] = "larsen"
char *p = str;

I dette tilfælde er adressen (p+n) det samme som &str[n], men her er det ikke adressen der udskrives - men derimod selve strenngen.

1) Hvorfor denne logik?

2) Hvordan får jeg udskrevet adressen? Både via pointer og via selve "str"?

Mvh
Hans Christian
Avatar billede erikjacobsen Ekspert
06. juli 2008 - 16:27 #1
Hvordan udskriver du?
Avatar billede dehdar Nybegynder
06. juli 2008 - 17:49 #2
Compile følgende kode. Her kan du se, hvordan du udskriver adressen på en pointer, adressen pointeren peger på og hvad pointeren peger på. Problemet optræder når man forsøger at udskrive adressen en char pointer peger på. Jeg mener det er fordi, at cout operatoren er overloaded til at udskrive alle tegn indtil nultermineringen, når man forsøger at udskrive et char string.

#include <iostream>
#include <cstdio>
using namespace std;

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

    cout << test << endl; //adressen paa dit array
    cout << p << endl; //adressen pointeren peger på
    cout << &p << endl; //pointerens adresse

    cout << endl;
    char str[] = "larsen";
    char *x = str;

    cout << &str << endl; //adressen på dit array
    cout << x << " = " << &x[0] << endl; //adressen pointeren peger på? Nej
    printf ("%p \n", x); //adressen pointeren peger på!
    cout << &x << endl; //pointerens adresse
}

%p (pointer adress mode) angiver hvilken mode printf skal udskrive i. Jeg håber det var svar på dit spørgsmål.
Avatar billede hclarsen Nybegynder
07. juli 2008 - 00:07 #3
Det var svar på mit spørgsmål. Men "printf ("%p \n", x);" er da C, og ikke C++?

Er det velset i C/C++ - community'et at "blande" C og C++ syntaks sammen?
Avatar billede hclarsen Nybegynder
07. juli 2008 - 12:09 #4
Men når jeg bruger "out << &str[1] << endl;", så giver den mig ikke adressen af element 1, men udskriver derimod "larsen"?
Avatar billede dehdar Nybegynder
07. juli 2008 - 14:25 #5
Du kan udskrive det således:

printf ("%p \n", str+1);

Om der findes en nemmere metode har jeg ikke undersøgt eftersom jeg aldrig har haft behov for det, men det kan en af eksperterne forhåbentligt svare på. Hvad angår god programmeringsskik eller rettere sagt iostream kontra cstdio, så fandt jeg følgende link på google.

http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.1
Avatar billede hclarsen Nybegynder
07. juli 2008 - 14:49 #6
Så det vil sige, at der er forskel mellem adressen på et array, og adressen på de enkelte del-elementer i arrayet?
Avatar billede hclarsen Nybegynder
07. juli 2008 - 15:02 #7
- jeg kan vel også udskrive det via

    printf ("%p \n", x+1)

?
Avatar billede dehdar Nybegynder
07. juli 2008 - 16:33 #8
Ja sagtens for pointeren har du sat til at pege på char stringen, så derfor vil dit eget eksempel også virke.

Når du erklærer en pointer, så bliver der allokeret plads i hukommelsen til pointeren, ligesom der gør når du erklærer en variabel. Derfor vil pointeren have sin egen adresse i hukommelsen. Adressen på dit array vil altid være adressen på det første element i arrayet. Hver plads/element i dit array bliver allokeret i en plads for sig selv i hukommelsen. Derfor sætter man pointeren til at pege på den første plads i arrayet, så man kan travesere ned gennem alt indholdet af arrayet.
Avatar billede hclarsen Nybegynder
07. juli 2008 - 18:02 #9
Cool, tak skal du have.
Avatar billede arne_v Ekspert
08. juli 2008 - 03:06 #10
Man kan også udskrive pointere med C++ stream IO ved at slå en knude på sig selv:

#include <iostream>
#include <iomanip>
#include <cstdio>

using namespace std;

int main()
{
    void *p = (void*)0x12345;
    printf("%p\n",p);
    cout << resetiosflags(ios::basefield) << setiosflags(ios::hex) << setw(8) << setfill('0') << (int)p << endl;
    return 0;
}
Avatar billede arne_v Ekspert
08. juli 2008 - 03:07 #11
Man bør aldrig blande C og C++ IO.

Skal du programmere meget i C++, så skal du lære C++ IO.

Men der er ret mange som mener at C++ IO var et fejlskud.
Avatar billede kenneth_gorking Nybegynder
10. juli 2008 - 03:38 #12
Burde 'setw(8)' ikke være 'setw(sizeof(void*)*2)'? Ellers bliver 64-bit addresser trunkeret...
Man kunne alternativt bruge denne her:

#include <iostream>
using namespace std;

int main()
{
    void *p = (void*)0x12345;
    cout << "0x" << p << endl;
    return 0;
}
Avatar billede arne_v Ekspert
10. juli 2008 - 04:06 #13
Jo.

Jeg var ikke klar over at stream<<pointer var overloadet.

Den virker dog lidt compiler specific.

VC++ 9 udskriver:

0x00012345

GCC 4.2 MinGW udskriver:

0x0x12345
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