Hallo zusammen, ich arbeite mich gerade für meine Diplomarbeit in C ein, habe noch keine große Erfahrung mit der Sprache und muss u.a. vorhandene Module verwenden. Jetzt wird in einer früheren Arbeit eine Funktion so deklariert: void aes(char *eingabepuffer) { } Der Aufruf wird folgendermaßen angegeben: char array[100]; aes(array); Meiner Meinung nach funktioniert das nicht und müsste doch so aussehen: aes(&array); Oder liege ich falsch? Gehen beide Varianten? Wenn ja, was ist der Unterschied? Wäre super, wenn mir jemand kurz helfen könnte. Danke und Gruß Markus
array liefert eine zeiger auf das erste element zurück. &array liefert die adresse des zeigers auf das erste element zurück, würde also in dem fall zu einem fehler führen...
Für den Compiler sind Felder und Pointer das gleiche. Der Unterschied besteht nur in der SRAM-Belegung. Ein Pointer belegt 2 Byte, worin die Adresse gespeichert wird, auf die er mal zeigen soll. Ein Feld belegt genau den Speicher für den Inhalt. Da die Adresse vom Linker aufgelöst wird, braucht ein Feld keinen extra Speicher für die Adresse. Der Zugriff erfolgt auf beides über die Adresse. (p+5) ist identisch mit &p[5] Peter
array zeigt auf das Element 0 des Feldes. Alternativ kann man noch schreiben &array[0].
> array liefert eine zeiger auf das erste element zurück. Genauer gesagt wird array beim Aufruf der Funktion in einen Zeiger auf das erste Element konvertiert. > &array liefert die adresse des zeigers auf das erste element zurück, Nein, tut es nicht, denn array ist kein Zeiger, sondern ein Array. Dementsprechend ist &array die Addresse des Arrays und nicht die eines Zeigers. Die Adresse des Arrays und seines ersten Elements sind zwar gleich, haben aber unterschiedliche Typen.
Hallo Markus, ja, da liegst Du falsch. aes(array) ist korrekt (einfach ausprobieren). Die Ausdrücke array und &array[0] sind identisch. Beispiel: void fkt(int *ptr, int i) ; int array[10] ; int main(int argc, char* argv[]) { fkt(&array[0], 2) ; for(int n=0 ; n< 10; n++) { printf("%d\n",array[n]) ; } getchar() ; return 0; } void fkt(int *ptr, int i) { for(int n=0 ; n<10; n++){ *ptr++ = n+i ; } } Gruß, DSP-Vision
>> &array liefert die adresse des zeigers auf das erste element zurück, >Nein, tut es nicht, denn array ist kein Zeiger, sondern ein Array. >Dementsprechend ist &array die Addresse des Arrays und nicht die eines >Zeigers. Die Adresse des Arrays und seines ersten Elements sind zwar >gleich, haben aber unterschiedliche Typen. also array und &array[0] ist dasselbe. aber ich hab immer gedacht das array und &array nicht dasselbe ist. char array1[100]; char *array2; array2 = (*char)malloc(100); hab des imemr so verstanden das ein array nix anderes ist als ein zeiger dem von anfang an ein speicherbereich zugwewiesen wird. deshalb muss es einen zeiger geben der auf daas erste element im array zeigt und dessen adresse müsste man mit &array bekommen, oder bin ich grad voll auf dem holzweg...
mit &array[0] bekommst Du die Adresse des ersten Elementes, mit &array[3] die des dritten Elementes, u.s.w.... Du könntest also mit array2 = &array1[3] dem Zeiger 2 die Adresse des dritten Elementes zuweisen (schön auf * , & und [] achten). Gute Nacht!
> hab des imemr so verstanden das ein array nix anderes ist als ein zeiger > dem von anfang an ein speicherbereich zugwewiesen wird. Dann hast du falsch gedacht. Du hast 2 Möglichkeiten * entweder du schreibst jetzt 100 mal: "Ein Array ist kein Zeiger. Ein Zeiger ist kein Array" * oder du besorgst dir aus der Bibliothek möglichst schnell mal etwas Literatur zu´m Thema C. Kernighaen&Richie ist immer noch eine empfehlenswerte Literatur. Wie Rolf weiter oben schon sagte: Unter bestimmten Umständen wird ein Array zu einem Zeiger auf das erste Element des Arrays konvertiert. Jedesmal wenn der Name des Arrays ohne Indizierung vorkommt (mit ein paar kleinen Ausnahmen) ist das der Fall. Das bedeutet aber nicht, dass ein Array ein Zeiger ist! Es wird nur bei Bedarf in einen konvertiert.
Vielen Dank für die vielen Antworten. Jetzt weiß ich Bescheid und bin auch schon ein großes Stück weitergekommen. Gruß Markus
Karl heinz Buchegger wrote: >> hab des imemr so verstanden das ein array nix anderes ist als ein zeiger >> dem von anfang an ein speicherbereich zugwewiesen wird. > > Dann hast du falsch gedacht. > > Du hast 2 Möglichkeiten > * entweder du schreibst jetzt 100 mal: > "Ein Array ist kein Zeiger. Ein Zeiger ist kein Array" > > * oder du besorgst dir aus der Bibliothek möglichst schnell > mal etwas Literatur zu´m Thema C. Kernighaen&Richie ist > immer noch eine empfehlenswerte Literatur. > > Wie Rolf weiter oben schon sagte: Unter bestimmten Umständen > wird ein Array zu einem Zeiger auf das erste Element des > Arrays konvertiert. Jedesmal wenn der Name des Arrays ohne > Indizierung vorkommt (mit ein paar kleinen Ausnahmen) ist > das der Fall. > Das bedeutet aber nicht, dass ein Array ein Zeiger ist! > Es wird nur bei Bedarf in einen konvertiert. Oha, wo wir gerade dabei sind. Bei welchem Beispiel wird denn der Name nicht in einen Zeiger konvertiert? Würde mich grad mal interessieren. Vielen Dank.
> Jedesmal wenn der Name des Arrays ohne Indizierung vorkommt (mit ein > paar kleinen Ausnahmen) ist das der Fall. Im Prinzip auch, wenn er mit Indizierung vorkommt.
> Oha, wo wir gerade dabei sind. Bei welchem Beispiel wird denn der Name > nicht in einen Zeiger konvertiert? char c[100]; sizeof(c);
sizeof ist keine Funktion, sondern wird bereits während des Compilierens durch den resultierenden Wert ersetzt.
Rufus T. Firefly wrote: > sizeof ist keine Funktion, sondern wird bereits während des > Compilierens durch den resultierenden Wert ersetzt. Die Rede war ja auch nicht nur von Funktionen. Auch in vielen anderen Kontexten (bspw. bei direkter Benutzung des Namens in einem Ausdruck) erfolgt ja eine implizite Konvertierung in den zugehörigen Zeiger.
Rufus T. Firefly wrote: > sizeof ist keine Funktion, sondern wird bereits während des Compilierens > durch den resultierenden Wert ersetzt. Wie ist das eigentlich bei C99? Da müsste sizeof ja sowohl zur Compiletime als auch zur Runtime ausgewertet werden können. (Hab lange bevor C99 auf C++ gewechselt, daher meine Wissenslücke). Bsp: size_t foo( int i ) { int test[i]; return sizeof( test ); } Ist ja seit C99 erlaubt. Oder darf man von solch 'dynamischen' Typen keinen sizeof machen (kann ich mir aber nicht vorstellen).
> Oha, wo wir gerade dabei sind. Bei welchem Beispiel wird denn der Name > nicht in einen Zeiger konvertiert? Versuch mal das:
1 | char string[] = "foo"; |
2 | |
3 | string++; |
und anschließend das:
1 | char * string = "foo"; |
2 | |
3 | string++; |
Du wirst einen Unterschied feststellen.
> Versuch mal das:
Dieses Beispiel ist nicht ganz zulässig.
Im ersten Beispiel ist nämlich der Pointertyp auf den
der char string[] konvertiert wird, ein
char * const
und damit ist klar, dass ein ++ auf diesen Pointer einen
Fehler ergeben muss.
Ja, das wollte ich damit ausdrücken. Beim ersten Beispiel gibts eine Fehlermeldung, denn Arrays werden implizit zu *const konvertiert. Deshalb kann man mit Arrays keine Pointerarithmetik machen.
@Karl Heinz: In dem von dir angesprochenen Fall wird in C99 sizeof tatsächlich erst zur Laufzeit ausgewertet. Die Norm selbst formuliert das so: 6.5.3.4 The sizeof operator Constraints [...] 2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant. Hier noch was zur impliziten Konvertierung von Arrays in Zeiger: 6.3.2.1 Lvalues, arrays, and function designators [...] 3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.