Teoretycznie-po co są wskaźniki?

0

Jak wyżej.

2

Do dynamicznej alokacji pamięci.
Do przekazywania parametrów do funkcji przez referencję, nie przez wartość.

2

Do tworzenia i obsługi struktur danych: tablic, list, grafów, drzew, etc
Do modyfikacji tego samego obszaru pamięci z wielu różnych miejsc.

  • to co napisał Ktos.
2

Do wprowadzenia większej ilości bugów do kodu
Do zmniejszenia czytelności kodu
Do wprowadzenia zamętu, trudnego do debugowania kodu
Do przyprawiania programisty o ból głowy
Do wprowadzania wycieków pamięci
Do zabawy i stosowania w kodzie różnych sztuczek których nie powinno się stosować, chociaż czasami są dużo wydajniejsze

0

A referencja to licznik ile razy ma zostać wyświetlony dany obiekt w pamięci?

0
htm72 napisał(a):

A referencja to licznik ile razy ma zostać wyświetlony dany obiekt w pamięci?

a skąd taki pomysł?
Referencja to taki ładniejszy wskaźnik

0

Z wikipedii ,Lol.
To wychodzi na to że są ciągłe problemy z wskaźnikami.Lol

1
htm72 napisał(a):

Z wikipedii ,Lol.

Pics or it didn't happen. Wikipedia mówi:

Referencja w informatyce to wartość, która zawiera informacje o położeniu innej wartości w pamięci

Co nijak się ma do bzdury którą napisałeś. Referencja to taki opakowany wskaźnik i tyle.

To wychodzi na to że są ciągłe problemy z wskaźnikami

Problemy to ty masz z czytaniem ze zrozumieniem najwyraźniej, ale ponoć niektórzy ludzie nie mają tej części mózgu która odpowiada za rekurencje i wskaźniki (tak twierdzi Spolsky przynajmniej ;]). Wskaźniki w C/C++ są ci potrzebne do wszystkich dynamicznych struktur danych i właściwie zawsze kiedy potrzebujesz w programie pracować z większą ilością danych. Stos ma raptem kilka MB i za wiele tam nie pomieścisz.

1
bumcfkszz napisał(a):
htm72 napisał(a):

A referencja to licznik ile razy ma zostać wyświetlony dany obiekt w pamięci?

a skąd taki pomysł?
Referencja to taki ładniejszy wskaźnik

Yyy... nie.
Referencja to obiekt, dokładnie ten sam obiekt, do którego się odnosi. Jeśli masz referencję do danej zmiennej, to ta referencja jest tą zmienną (tylko pod inną nazwą). Jeśli pobierzesz adres tej referencji, to uzyskasz adres zmiennej, a nie referencji. Dlatego nie można stworzyć wskaźnika do referencji.

Wskaźnik natomiast przechowuje adres zmiennej. Jest osobną zmienną, która ma również swój własny adres.

Bardziej szczegółowo w FAQ

0

Ja po prostu inaczej rozumiem pewne rzeczy.Nie rozumiesz?Lol
Nie wiem jak sie cytuje.

1

Do polimorfizmu.

1

Chociażby przekazywanie tablic do funkcji. W c++ chodzi o to, że masz wiele rzeczy jawnych gdyż to programista ma mieć kontrole nad wszystkim.

2
trickle napisał(a):

Mógłbyś podać źródło twojej tezy? Bo taka przepychanka nie ma sensu. Ja jedno ze źródeł podałem w moim poście.

#include <iostream>
using namespace std;

void ref(int &r,int *ext=0)
  {
   cout<<&r<<'\t'<<r<<endl;
   int x=123456789;
   *(&ext-1)=&x;
   cout<<&r<<'\t'<<r<<endl;
   int y=987654321;
   *(&ext-1)=&y;
   cout<<&r<<'\t'<<r<<endl;
  }

int main()
  {
   int a=0;
   ref(a);
   return 0;
  }

Tylko wyłącz optymalizacje.

Albo tak:

#include <iostream>
using namespace std;
     
struct Ref
  {
   int &r;
   Ref(int &r):r(r) {}
   void change(int &r) { *((int**)this)=&r; }
   void show() { cout<<&r<<'\t'<<r<<endl; }
  };
     
int main()
  {
   int a=0;
   Ref r(a);
   r.show();
   int x=123456789; r.change(x); r.show();
   int y=987654321; r.change(y); r.show();
   return 0;
  }

http://ideone.com/axIZgc

0
_13th_Dragon napisał(a):
trickle napisał(a):

Mógłbyś podać źródło twojej tezy? Bo taka przepychanka nie ma sensu. Ja jedno ze źródeł podałem w moim poście.

#include <iostream>
using namespace std;

void ref(int &r,int *ext=0)
  {
   cout<<&r<<'\t'<<r<<endl;
   int x=123456789;
   *(&ext-1)=&x;
   cout<<&r<<'\t'<<r<<endl;
   int y=987654321;
   *(&ext-1)=&y;
   cout<<&r<<'\t'<<r<<endl;
  }

int main()
  {
   int a=0;
   ref(a);
   return 0;
  }

Tylko wyłącz optymalizacje.

To powiedz mi, jakiego efektu się spodziewasz, bo g++ 4.7.3 z -O0 daje taki efekt:

0x7fff9271565c 0
0x7fff9271565c 0
0x7fff9271565c 0

Co chyba nie było Twoim zamiarem.

0

Ja bym powiedział tak, prawdziwe programowanie nie obejdzie się bez wskaźników :)

1
_13th_Dragon napisał(a):
#include <iostream>
using namespace std;

void ref(int &r,int *ext=0)
  {
   cout<<&r<<'\t'<<r<<endl;
   int x=123456789;
   *(&ext-1)=&x;
   // (...)

&ext-1 to jest UB (5.7.5).

_13th_Dragon napisał(a):

Albo tak:

#include <iostream>
using namespace std;
     
struct Ref
  {
   int &r;
   Ref(int &r):r(r) {}
   void change(int &r) { *((int**)this)=&r; }
   // (...)

*((int**)this)=&r to jest UB (strict aliasing), poza tym nie można zmieniać this.

Fakt, że trzeba wyłączyć optymalizacje to niezła podpowiedź, że coś jest z tym nie tak. To po prostu nie jest poprawny C++.

6

Trzeba uściślić czy mówimy o referencji w sensie C++ czy referencji w znaczeniu klasycznym.

W znaczeniu klasycznym, referencja to coś pozwalającego pośrednio odwoływać się do innej zmiennej. W tym znaczeniu wskaźniki to /jeden z rodzajów/ referencji.

W terminologii/semantyce C++ referencja zachowuje się jak coś w rodzaju innej nazwy na tą samą zmienną, i trudno powiedzieć żeby zachowywała się podobnie do wskaźnika. Owszem, w praktyce jest implementowana jako wskaźnik, ale to nie jest dowód na nic (no i często kompilator może zamienić dostęp przez referencje (albo wzkaźnik) bezpośrednim czytaniem/pisaniem w odpowiednie miejsce - trudno wtedy mówić co jest implementowane jako co, a można porównywać jedynie zachowanie).

Ergo referencja to nie opakowany wskaźnik, najwyżej opakowany wskaźnik to całkiem niezłe porównanie na to jak referencje się zachowują.

(trochę się zaplątałem w argumentach, mam nadzieję że jest po polsku to co wyprodukowałem

0

Sugerowałbym napisanie 1 programu w assemblerze z wywoływaniem funkcji systemowych (np. WinApi), żeby zrozumieć do czego są wskaźniki i jak to wszystko dokładnie działa.

0

Patrz niedowiarku trickle,i doucz się miast pitolić

#include <iostream>
int main(int argc, _TCHAR* argv[])
{
	short variable1 = 1234;
	short variable2 = 4321;
	short &ref = variable1;
	short *const p = &variable2;//O jakie czary,tak zdefiniowany wskaźnik zachowuje się identycznie jak referencja ;]

	
	_asm
	{
		mov eax,ref; //średniki zbędne,ale bez tego nie skacze ładnie do nowej linii
		lea ebx,variable2;
		mov ref,ebx;

		mov eax,p;
		lea ebx,variable1;
		mov p,ebx
	}
	
	//No to patrz trickle cóż to za czary się tu dzieją...
	std::cout << "Referencja nastawiona na v1:" <<ref << std::endl;
	std::cout << "Staly wskaznik nastawiony na v2:"<<*p << std::endl;


	//A tutaj więcej czarów :] p = ref
	_asm
	{
		mov eax,ref;
		mov p,eax
	}
	std::cout << "Staly wskaznik nastawiony na v2:"<<*p << std::endl;
}

I co,dotarło w końcu że referencja to taki ukryty const wskaźnik?

Kompilator Visual Studio 2003.Na innych też pójdzie,aczkolwiek o ile pamiętam g++ do wstawek asemblerowych używa składni AT&T

0

@MasterBLB @_13th_Dragon
Mnie od początku nie chodziło o to, jak referencja jest zaimplementowana w poszczególnych kompilatorach, bo nie jest to określone przez standard. Chodziło mi cały czas o to, że koncepcyjnie w języku C++ referencja jest czym innym niż stały wskaźnik.
Podstawowe różnice: spróbuj utworzyć tablicę referencji, albo wskaźnik do referencji. Nie da się. Nie da się również zmienić odwołania referencji "bez mazania po pamięci", czyli legalnym i czytelnym kodem C++. Przez czytelny rozumiem kod, który jest łatwy w utrzymaniu i czytaniu.

Ze stałymi wskaźnikami da się to wszystko zrobić (oprócz zmiany adresu, na który wskazuje). Ba możesz zrobić stały wskaźnik do stałego wskaźnika do stałego wskaźnika itd.

Proszę nie wmawiajcie mi, że referencja jest tożsama ze wskaźnikiem, bo nie jest. To są tylko implementacje kompilatorów.

Równie dobrze w GCC można pobrać adres etykiety, ale nie świadczy to o tym, że jest to zgodne ze standardem czy że etykieta jest wskaźnikiem (np. na funkcję, gdyż w ten sposób też można to wykorzystać).

Podsumowując, referencja to nie jest wskaźnik i nie powinno się o niej w ten sposób myśleć. I nie istotne w tym miejscu, czy jesteście w stanie pobrać jej adres, zmodyfikować dane pod tym adresem, etc.

0

Nieprościej było napisać, że wskaźniki pozwalają na dostęp do wybranego obszaru pamięci i zapobiego zapychaniu pamięci niepotrzebnymi duplikatami?

1

Trickle,my ci nie wmawiamy że referencja jest tożsama ze wskaźnikiem.
My jedynie udawadniamy,że pod względem technicznym (czyli jakie bebechy w tym siedzą) nie ma między nimi różnicy.I być siłą rzeczy nie może,skoro zadaniem referencji jest operować na przypisanym obiekcie.
Co do czytania kodu,to akurat mój asemblerowy jest zrozumiały dla każdego po 15min lekturze podstaw asemblera.

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