Video: Pointers and arrays 2024
De naam van de array is een verwijzing naar de array zelf. De array is een reeks variabelen die in het geheugen is opgeslagen. De arraynaam verwijst naar het eerste item.
Dit is een interessante vraag over pointers: kunt u een functieheader hebben, zoals de volgende regel, en gewoon sizeof gebruiken om te bepalen hoeveel elementen in de array zitten? Als dit het geval is, hoeft deze beller de grootte van de array niet op te geven.
int AddUp (int Numbers []) {
Overweeg deze functie te vinden in het voorbeeld Array01 en een main () die dit aanroept:
void ProcessArray (int Numbers []) { cout << "inside functie: Grootte in bytes is" << sizeof (Numbers) << endl;} int main (int argc, char * argv []) {int MyNumbers [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; cout << "buiten functie: Grootte in bytes is"; cout << sizeof (MyNumbers) << endl; ProcessArray (MyNumbers); return 0;}
Als u deze applicatie uitvoert, ziet u wat u ziet:
Buiten functie: Grootte in bytes is 40 Binnen functie: Grootte in bytes is 4
Buiten de functie weet de code dat de grootte van de array 40 bytes is. Maar waarom denkt de code dat de grootte 4 is nadat deze zich in de array bevindt? De reden is dat, hoewel het lijkt alsof u een array doorgeeft, u een aanwijzer echt doorgeeft aan een array. De grootte van de aanwijzer is slechts 4, en dat is dus wat de laatste cout-regel afdrukt.
int MyNumbers [5];
de compiler weet dat je een array hebt en de operator sizeof geeft je de grootte van de hele array. De arraynaam is dan
beide een aanwijzer en een array! Maar als u een functieheader declareert zonder een arraygrootte, zoals void ProcessArray (int Numbers []) {
behandelt de compiler dit als een
pointer en niets meer. Deze laatste regel is in feite gelijk aan de volgende regel: void ProcessArray (int * Numbers) {
Dus binnen de functies die door een van de regels worden aangegeven, zijn de volgende twee coderegels
equivalent <: Nummers [3] = 10; * (Nummers + 3) = 10; Deze gelijkwaardigheid betekent dat als u een externe verklaring op een array gebruikt, zoals
extern in MyNumbers [];
en neem dan de grootte van deze array, de compiler raakt in de war. Hier is een voorbeeld: als u twee bestanden hebt, nummers. cpp en main. cpp, waar getallen. cpp declareert een array en main. cpp verklaart het extern (zoals weergegeven in het voorbeeld van Array02), u krijgt een compileerfout als u sizeof aanroept:
# include namespace std; extern int MyNumbers []; int main (int argc, char * argv []) {cout << sizeof (MyNumbers) << endl; return 0;}
In Code:: Blocks geeft de gcc-compiler ons deze foutmelding:
fout: ongeldige toepassing van 'sizeof' op incompleet type 'int []'
De oplossing is om de grootte op te geven van de array tussen haakjes.Zorg ervoor dat de grootte hetzelfde is als in het andere broncodebestand! Je kunt de compiler nep maken door het nummer te veranderen, en je
krijgt geen fout
. Maar dat is een slechte programmeerstijl en alleen maar vragen om fouten. Hoewel een array
eenvoudigweg een reeks variabelen is die alle in het geheugen naast elkaar liggen, is de naam van een array eigenlijk slechts een verwijzing naar het eerste element in de array. U kunt de naam gebruiken als een aanwijzer. Doe dit echter alleen als u echt met een aanwijzer moet werken. Je hebt tenslotte echt geen reden om code te schrijven die cryptisch is, zoals * (Numbers + 3) = 10;. Het omgekeerde is ook waar. Kijk naar deze functie: void ProcessArray (int * Numbers) {cout << numbers [1] << endl;}
Deze functie neemt een pointer als een parameter, maar je hebt er toegang toe als een array. Nogmaals, schrijf geen code zoals deze; in plaats daarvan zou u
moeten begrijpen waarom deze code werkt
. Op die manier verkrijgt u een diepere kennis van arrays en hoe ze in de computer leven, en deze kennis kan u op zijn beurt helpen code te schrijven die correct werkt. Hoewel de arraynaam slechts een aanwijzer is, is de naam van een array van gehele getallen niet exact hetzelfde als een aanwijzer naar een geheel getal. Bekijk deze coderegels (te vinden in het voorbeeld van Array03): int LotsONumbers [50]; int x; LotsONumbers = & x;
Wijs met de LotsONumbers
-aanwijzer
iets anders aan: iets gedeclareerd als een geheel getal. De compiler laat je dit niet doen; je krijgt een foutmelding Dat zou niet het geval zijn als LotsONumbers als int * LotsONumbers werden verklaard; dan zou deze code werken. Maar zoals geschreven, geeft deze code je een compileerfout. En geloof het of niet, hier is de compileerfout die u krijgt in Code:: Blocks: fout: incompatibele typen in toewijzing van 'int *' in 'int [50]' Deze fout houdt in dat de compiler wel een definitief onderscheid tussen de twee typen, int * en int []. Desalniettemin is de arraynaam inderdaad een aanwijzer en kunt u deze als één gebruiken; je kunt er gewoon niet alles mee doen dat je kunt met een normale aanwijzer, zoals het opnieuw toewijzen.
Let bij het gebruik van arrays op de volgende tips. Deze zullen u helpen om uw arrays bug-vrij te houden:
Houd uw code consistent. Als u bijvoorbeeld een pointer naar een geheel getal declareert, behandel het dan niet als een array.
Houd uw code duidelijk en begrijpelijk. Als u pointers doorgeeft, is het ok om het adres van het eerste element te nemen, zoals in & (MyNumbers [0]) als hierdoor de code duidelijker wordt - hoewel deze gelijk is aan alleen MyNumbers.
-
Wanneer u een array declareert, probeer dan altijd een cijfer tussen de haakjes te zetten, tenzij u een functie schrijft die een array nodig heeft.
-
Wanneer u het externe sleutelwoord gebruikt om een array te declareren, moet u doorgaan en ook de array-grootte tussen haakjes plaatsen. Maar wees consistent! Gebruik het ene nummer niet één keer en een ander nummer een andere keer. De eenvoudigste manier om consistent te zijn is om een constante te gebruiken, zoals const int ArraySize = 10; in een gemeenschappelijk header-bestand en gebruik dat in uw array-declaratie: int MyArray [ArraySize];.