Wskaźniki w C - operacje na tablicach

0

Cześć,
mam takie zadanie:
user image

Mam następujący problem:

Skoro w zadaniu został utworzony wskaźnik int* p[5] to:

  • czy samo "p" zwraca adres wskaźnika?
  • czy "*p" zwraca wartość pierwszego adresu wskaźnika?

Przykładowo:

a) **p - skoro "p" zwraca adres wskaźnika to "*p" powinno zwrócić wartość znajdującą się pod pierwszym adresem tj. "4206616". Idąc dalej "**p" powinno zwrócić wartość znajdującą się pod adresem "4206616" czyli 3 - i to się zgadza, jest to poprawna odpowiedź.

Niestety problem pojawia się dla mnie w przykładzie "c" kompletnie nie rozumiem, dlaczego odpowiedzią jest "15" skoro nigdzie nie ma * więc nie powinno zwrócić wartości a co najwyżej adres.

Będę bardzo wdzięczny za wytłumaczenie tego zadania. Dziękuję

3

p jest tablicą, nie "zwraca" żadnych wskaźników.

W C i C++ dla tablic zapis a[b] jest tylko cukrem syntaktycznym dla *(a+b), więc **p to to samo co p[0][0], a p[1][1] to to samo co *(*(p+1)+1)

1
#include <iostream>
        int *p[6]={
                (int[]){4206610,4206636,4206656,4206676,4206696},
                (int[]){3,1},
                (int[]){41,15,27},
                (int[]){120,250,170},
                (int[]){2200,1100},
                (int[]){5003,9004,6007,8001}
        };
int main(){
	using namespace std;
	cout 	<< "**p: " << **p << endl
		<< "(*p)[1]: " << (*p)[1] << endl
		<< "p[1][1]: " << p[1][1] << endl
		<< "*(p+2): "  << *(p+2)  << ", *(*(p+2)): "<< *(*(p+2)) << endl
		<< "*p+2: "    << *p+2    << ", *(*p+2): "<< *(*p+2) << endl
		<< "*p[2]: "   << *p[2]   << endl;
	return 0;
}
 

Wynik:

**p: 4206610
(*p)[1]: 4206636
p[1][1]: 1
*(p+2): 0x8049cf0, *(*(p+2)): 41
*p+2: 0x8049cdc, *(*p+2): 4206656
*p[2]: 41
 
1

@fasadin no właściwie tak wygląda, ale jak spojrzymy na adresy to wszystko gra. Już samo polecenie jakby miało błąd:
Mamy 5 elementową tablicę wskaźników int (zgodnie z adresami), ale jest 6 wskaźników na obrazku do tablic.

1

Jest 5 wskaźników

1

Zrozumiałem swój błąd przepraszam za wprowadzenie zamieszania.
arekusa W pierwszej tablicy masz adresy, poprzez które odwołujesz się do wartości.

0
Pokolenie NSDAP napisał(a):
#include <iostream>
        int *p[6]={
                (int[]){4206610,4206636,4206656,4206676,4206696},
                (int[]){3,1},
                (int[]){41,15,27},
                (int[]){120,250,170},
                (int[]){2200,1100},
                (int[]){5003,9004,6007,8001}
        };
int main(){
	using namespace std;
	cout 	<< "**p: " << **p << endl
		<< "(*p)[1]: " << (*p)[1] << endl
		<< "p[1][1]: " << p[1][1] << endl
		<< "*(p+2): "  << *(p+2)  << ", *(*(p+2)): "<< *(*(p+2)) << endl
		<< "*p+2: "    << *p+2    << ", *(*p+2): "<< *(*p+2) << endl
		<< "*p[2]: "   << *p[2]   << endl;
	return 0;
}
 

Wynik:

**p: 4206610
(*p)[1]: 4206636
p[1][1]: 1
*(p+2): 0x8049cf0, *(*(p+2)): 41
*p+2: 0x8049cdc, *(*p+2): 4206656
*p[2]: 41
 

Wielkie dzięki, bardzo mi to pomogło zrozumieć całe to zadanie. Problem polega na tym, że odpowiedzi się nie zgadzają, wg. mojego wykładowcy powinno być tak:

user image

Nie wiem teraz czy wykładowca ma błąd w zadaniu, czy po prostu ja źle liczę.

2

Sprosotowanie
Wykładowca prawidłowo podał odpowiedzi:

  1. *(*p = 4206616) = 3
  2. *((*p = 4206616) + 4) = 1
  3. (((p+1) = 4206636) + 4) = 15
  4. *(p+2 ) = 4206656
  5. (*p = 4206616) + 8 = 4206624
    6 . *(p+2 = 4206656) = 120
1

Jeżeli chcecie symulację to takie coś wydaje się działać:

#include<iostream>
using namespace std;

int main(){
    int p[5][4] = {
        { 3, 1 },
        { 41, 15, 27 },
        { 120, 250, 170 },
        { 2200, 1100 },
        { 5003,9004,6007,8001 }
    };

    cout << "Adresses:" << endl;
    for(int i = 0; i < 5; ++i)
        cout << "p[" << i << "]: " << (uintptr_t)(p + i) << endl;


    cout << "\nValues:" << endl
         << "**p: " << **p << endl
         << "(*p)[1]: " << (*p)[1] << endl
         << "p[1][1]: " << p[1][1] << endl
         << "*(p+2): " << (uintptr_t)(*(p + 2)) << endl
         << "*p+2: " << (uintptr_t)(*p + 2) << endl
         << "*p[2]: " << *p[2] << endl;
    return 0;
}

http://ideone.com/rSfBuQ

Oczywiście na przydzielenie adresów nie mamy wpływu ale arytmetyka wydaje się być w porządku.

0

Bardzo Wam dziękuję za pomoc, teraz już wszystko rozumiem.
Pozdrawiam i życzę wszystkiego dobrego

1 użytkowników online, w tym zalogowanych: 0, gości: 1