Array fixer Länge an Funktion übergeben

So ist es.
Der sizeof-Operator lässt sich noch anwenden und die Größenangabe kann 
das Lesen des Codes erleichtern. Ich kann mich allerdings nicht daran 
erinnern, dass ich dieses Konstrukt in eigenem Code mal eingesetzt 
hätte. Pointer beißen nicht!
Gast
Gut, es handelt sich um 2 charakter Zeichen. Immer 2, nicht mehr und 
nicht weniger. Der Aufruf erfolgt mit Test("AB");, schade das sich das 
nicht belassen lässt.
Konrad S. schrieb:
> void f( int a[42] );

*Vorsicht!*
Das ist nichts anderes als eine glorifizierte andere Schreibweise für
1
void f( int* a);
nicht mehr und nicht weniger.
Da steckt NICHT mehr dahinter, auch wenn die Schreibweise da was anderes 
suggeriert.
1
#include <stdio.h>
2

3
void f( int a[42] )
4
{
5
  printf( "%d\n", sizeof( a ) );
6
}
7

8
int main()
9
{
10
  int b[9];
11

12
  f( b );
13
}

Die Ausgabe ist 4, weil auf meinem System ein Pointer 4 Bytes groß ist! 
Die Ausgabe hat nichts mit der tatsächlichen Größe von a innerhalb der 
Funktion oder gar mit der Arraygröße des Aufrufers zu tun!

Arrays werden in C an Funktionen übergeben, in dem die Startadresse des 
Arrays übergeben wird und die empfangende Funktion hat dafür eine 
passende Pointer Variable bereitzustellen. Punkt.


Meine persönlichen Meinung nach, sollte man um sowas
1
void f( int a[42] );
einen Bogen machen. Auf den ersten Blick mag das für Neulinge einfacher 
erscheinen. Ist es aber nicht. Denn hier werden unterschwellig Dinge 
suggeriert, die einfach nicht zutreffend sind. Die Arrayangabe oder gar 
die Angabe der Arraygröße haben an dieser Stelle absolut nichts zu 
sagen! Dei Arrayangabe kann an den Aufrufer noch ein gewisses Signal 
sein, wie der Parameter von der Funktion verwendet werden wird, was 
gegenüber Pointer ein gewisser dokumentarischer Vorteil sein kann. Aber 
wir wissen alle, wie das mit derartigen Konventionen ist .... man kann 
sich einfach nicht auf sie verlassen, solange sie nicht vom Compiler 
eingefordert und überprüft werden.
Gast
Hallo, ich habe mit den Pointern doch ein Problem.

Prototyp ist z. B. der
1
void test( char *);


Funktionsaufruf

1
test("ABCD");

wird automatisch die Addresse der Speicherstelle von "A" übergeben oder?

wie muss jetzt die Funktion selbst aussehen?
1
void test(char foo[5])
2
{
3
    char lokales_arr[5];
4

5
    hier dann ursprüngliches array in neues array kopieren;
6
}
funktioniert, ich vermute aber das das Ganze nicht sauber ist, weil ich 
ja ein Array in den Funktionsparameter angebe, aber ein Pointer 
übergeben wird? Wie muss das Ganze stattdessen aussehen?

Ich möchte quasi die übergebenen Zeichen ABCD in ein anderes Array 
kopieren, welches noch andere Daten enthält.
Gast
Da reinkopieren ist sicher kein Problem, da es immer eine bestimmte 
Länge ist und ich den Nullterminierung nicht brauche.

Ich habe ein Array "01234567890" und an Position 4 soll die 
Zeichenfolge, die an die Funktion übergeben wurde, kopiert werden. 
"0123ABCD890".

Allerdings geht es mir um den Funktionskopf,
1
void test(char foo[5])
 da ist meiner Meinung nch etwas faul, weil sie ja nicht mit dem 
Funktionsprototypen übereinstimmt.
Gast
Malte S. schrieb:
> Der lautet dann auchvoid test(char* foo)
> Warum willst du die vereinbarte Länge da unbedingt drin haben. Mehr als
> eine Vereinbarung ist sie eh nicht.

Muss nicht zwingend drinn sein, ist aber übersichtlicher.


Ok also void test(char* foo) und der Zugriff auf die einzelnen Elemente 
wie?
Willkommen in der wunderbaren Welt der Arrays und Pointer in C. Sie kann 
dir zu Füßen liegen oder unter selbigen zusammenbrechen. Das 
vollständige Verständnis jeder Indizierung und jeder Dereferenzierung, 
der Überblick über Herkunft und Zuverlässigkeit der Daten (Strings z.B.) 
und entsprechendes Einhalten der Grenzen des jeweiligen Speicherbereichs 
- ob in Gestellt eines Arrays oder eines blanken Pointers - helfen dir, 
dass am Ende nicht alles zusammenbricht ;)
Gast
Malte S. schrieb:
> Aber nur, wenn du absolut garantieren kannst, dass test() immer ein
> ausreichend langes Array übergeben wird.

Seit C99 geht das teilweise:
1
char test(char foo[static 2]) {
2
    return foo[1];
3
}
So deklariert darf man keinen Nullpointer und kein Array mit einer Länge 
von weniger als zwei Elementen an die Funktion übergeben.
Gast
Arne Nonymous schrieb:
> So deklariert darf man keinen Nullpointer und kein Array mit einer Länge
> von weniger als zwei Elementen an die Funktion übergeben.

und woher soll der compiler die länge wissen?

int i = rand(10);
int* a = (int*)malloc(sizeof(int)*i);
//oder c++ int[] a  = new int[i];

test(a) {
}
Moderator
Peter II schrieb:
> Arne Nonymous schrieb:
>> So deklariert darf man keinen Nullpointer und kein Array mit einer Länge
>> von weniger als zwei Elementen an die Funktion übergeben.
>
> und woher soll der compiler die länge wissen?

Der Compiler weiß das nicht und muss es auch nicht wissen. Das [static 
2] ist lediglich eine Zusicherung des Programmierers, dass das Array 
mindestens 2 Elemente enthält und kann vom Compiler zu 
Optimierungszwecken verwendet werden. Für die Einhaltung dieser 
Zusicherung ist der Programmierer aber selber verantwortlich. Der 
Compiler überprüft sie nicht notwendigerweise.
Gast
Suchst Du so was?
1
#include <stdio.h>
2
#include <string.h>
3

4
typedef struct
5
{
6
  char ch[3];
7
} String3_s;
8

9
void func( String3_s string3 )
10
{
11
  printf( "%s\n", &string3.ch[0] );
12
  printf( "%lu\n", sizeof( string3 ) );
13
}
14

15
int main( void )
16
{
17
    // C89
18
    //String3_s string3;
19
    //strcpy( &string3.ch[0], "AB" );
20
  
21
    // C99
22
    String3_s string3 = { .ch = "AB" };
23
  func( string3 );
24
}
25
  
26
  
27
}

Ausgabe:
fjhf@hjhgjk:~/test$ ./a.out
AB
3

Gruss,
Manni
Gast
Elegant & sicher geht so:
1
#include <iostream>
2
#include <array>
3

4
void fun (std::array<int,7> arr) {
5
  for(auto x : arr) {
6
    std::cout << x;
7
  }
8
}
9

10
void fun2 (const std::array<int,7>& arr) {
11
  for(auto x : arr) {
12
    std::cout << x;
13
  }
14
}
15

16
int main () {
17
  fun ({{1, 2, 3, 4, 5, 6, 7}});
18
  fun2 ({{1, 2, 3, 4, 5, 6, 7}});
19
}
So ist auch sichergestellt dass man nicht zu viel übergibt, und dass, 
falls man zu wenig übergibt, die anderen Elemente default-initialisiert 
werden (Integer auf 0, Klassen per Default-Konstruktor) - somit keine 
Speicherfehler möglich. Die 1. Variante kopiert dabei den kompletten 
Inhalt in den Funktions-scope, die 2. übergibt nur eine Referenz 
(normalerweise schneller).
Gast
Also bei mir würde die Funktion auch so aussehen:
1
char* teilstring(const char* string, unsigned int groesse)
2
{
3
  char *teilstring = (char*)malloc(sizeof(char)*(groesse+1));
4
  teilstring[groesse]='\0';
5

6
  for(unsigned int counter=0;counter<groesse; counter++) teilstring[counter]=string[counter];
7

8
  return teilstring;
9
}

Man übergibt einen String als Pointer und eine Variable für die Größe 
des Rückgabestrings.
Übergibt man also ein String/Array mit Inhalt "Hallo Welt!" und Größe=4 
dann wird "Hall" zurückgegeben... Da ist aber noch nicht die mögliche 
Überlänge von int groesse in Bezug auf die tatsächliche Länge des Arrays 
berücksichtigt!
Gast
Hier mit Überlängenkorrektur:
1
char* teilstring(char* string, unsigned int groesse)
2
{
3
  char *teilstring = (char*)malloc(sizeof(char)*(groesse+1));
4
  teilstring[groesse]='\0';
5

6
  for(unsigned int counter=0;counter<groesse; counter++)
7
  {
8
    teilstring[counter]=string[counter];
9
    if (string[counter]=='\0') break;
10
  }
11

12
  return teilstring;
13
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.