Video: Pekare och pekararitmetik i C 2024
Namnet på arrayen är en pekare till själva matrisen. arrayen är en sekvens av variabler som lagras i minnet. matrisnamnet pekar på det första objektet.
Detta är en intressant fråga om pekare: Kan du ha en funktionhuvud, till exempel följande rad, och använd bara sizeof för att bestämma hur många element som finns i matrisen? Om så är fallet behöver den här funktionen inte kräva att anroparen anger storleken på matrisen.
Tänk på den här funktionen i Array01-exemplet och en huvud () som kallar det:void ProcessArray (int Numbers []) { cout << "inside function: Storlek i byte är" << sizeof (Numbers) << endl;} int huvud (int argc, char * argv []) {int MyNumbers [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; cout << "utanför funktion: Storlek i byte är"; cout << sizeof (MyNumbers) << endl; ProcessArray (MyNumbers); returnera 0;}
När du kör den här applikationen är här vad du ser:
Utanför funktionen vet koden att storleken på arrayen är 40 byte. Men varför tycker koden att storleken är 4 efter att den är inne i matrisen? Anledningen är att även om det verkar som om du passerar en array passerar du verkligen en
pekare till en array. Pekarens storlek är bara 4, och så är det vad den slutliga coutlinjen skriver ut.
int MyNumbers [5];
kompilatören vet att du har en array, och storleken på operatören ger dig storleken på hela arrayen. Matrisnamnet är då
båda en pekare och en matris! Men om du förklarar en funktionhuvud utan en arraystorlek, till exempel void ProcessArray (int Numbers []) {
, behandlar kompilatören detta som enbart en
pekare och inget mer. Den här sista raden motsvarar faktiskt följande rad: void ProcessArray (int * Numbers) {
Således, inom de funktioner som endera linjen deklarerar, är följande två kodkoder
ekvivalent <: Numbers [3] = 10; * (Numbers + 3) = 10; Denna ekvivalens innebär att om du använder en extern deklaration på en array, till exempel
extern int MyNumbers [];
och sedan ta storleken på denna array kommer kompilatorn att bli förvirrad. Här är ett exempel: Om du har två filer, siffror. cpp och main. cpp, var siffror. cpp förklarar en array och main. cpp externt deklarerar det (som visas i Array02-exemplet) får du ett kompilatorfel om du ringer sizeof:
#include med namespace std; extern int MyNumbers []; int main (int argc, char * argv []) {cout << sizeof (MyNumbers) << endl; returnera 0;}
I kod:: Block, ger gcc-kompilatorn oss det här felet:
Fel: Ogiltig tillämpning av 'sizeof' till ofullständig typ 'int []'
Lösningen är att ställa in av matrisen inom parenteserna.Se bara till att storleken är densamma som i den andra källkodsfilen! Du kan förfalska kompilatorn genom att ändra numret, och du
får inte ett fel
. Men det är dåligt programmeringsstil och bara frågar efter fel. Även om en array
helt enkelt är en sekvens av variabler som alla ligger intill varandra i minnet, är namn för en array verkligen bara en pekare till det första elementet i matrisen. Du kan använda namnet som en pekare. Gör emellertid bara när du verkligen behöver arbeta med en pekare. När allt kommer omkring har du verkligen ingen anledning att skriva kod som är kryptisk, till exempel * (Numbers + 3) = 10;. Det omvända är också sant. Titta på den här funktionen: void ProcessArray (int * Numbers) {cout << nummer [1] << endl;}
Den här funktionen tar en pekare som en parameter, men du får tillgång till den som en matris. Återigen, skriv inte kod så här; istället borde du förstå
varför kod så här fungerar
. På det sättet får du en djupare kunskap om arrays och hur de bor i datorn, och denna kunskap kan i sin tur hjälpa dig att skriva kod som fungerar ordentligt. Även om arraynamnet bara är en pekare är namnet på en rad heltal inte exakt samma sak som en pekare till ett heltal. Kolla in dessa rader med kod (finns i Array03-exemplet): int LotsONumbers [50]; int x; LotsONumbers = & x;
Peka på LotsONumbers
pekaren
på något annat: något deklarerat som ett heltal. Kompilatorn låter dig inte göra det här; du får ett fel Det skulle inte vara fallet om LotsONumbers förklarades som int * LotsONumbers; då skulle den här koden fungera. Men som skrivet ger den här koden ett kompilatorfel. Och tro det eller inte, här är det kompilatorfel du får i Kod:: Block: fel: inkompatibla typer i tilldelning av 'int *' till 'int [50]' Denna fel innebär att kompilatorn ser en bestämd skillnad mellan de två typerna, int * och int []. Ändå är matrisnamnet verkligen en pekare, och du kan använda den som en; du kan inte bara göra allt med det som du kan med en normal pekare, till exempel omdirigera den.
Notera sedan följande tips när du använder arrayer. Dessa hjälper dig att hålla dina arrayer buggfria:
Håll din kod konsekvent. Om du förklarar till exempel en pekare till ett heltal, behandla det inte som en matris.
Håll din kod klar och förståelig. Om du passerar pekare är det okej att ta adressen till det första elementet, som i & (MyNumbers [0]) om det här gör koden tydligare - men det motsvarar bara MyNumbers.
-
När du försäkrar en matris, försök alltid att sätta ett tal inom parentesen, om du inte skriver en funktion som tar en matris.
-
När du använder det externa sökordet för att deklarera en matris, fortsätt och sätt in arraystorleken inom parentes. Men var konsekvent! Använd inte ett nummer en gång och ett annat nummer en annan gång. Det enklaste sättet att vara konsekvent är att använda en konstant, till exempel const int ArraySize = 10; i en gemensam headerfil och använd sedan det i din arraydeklaration: int MyArray [ArraySize];.