2015-08-05 2 views
5

Ich bin lernen C++ in diesen Tagen von mir selbst und ich habe ein Problem zu verstehen, warum dieser Code nicht kompiliert mit #g++ -std=c++11 source.cpp. Eigentlich ist es egal, welchen spezifischen Standard ich verwende, es kompiliert einfach nicht.Range basierte für Schleife in Funktion, die ein Array als Wert

#include <iostream> 
#include <string> 
using namespace std; 
int print_a(char array[]) 
{ 
    for(char c : array) 
     cout << c; 
    cout << endl; 
    return 0; 
} 
int main(void) 
{ 
    char hello[] {"Hello!"}; 
    print_a(hello); 
    return 0; 
} 

Die Fehlermeldung:

[email protected]:~/Documents$ g++ -std=c++11 source.cpp 
source.cpp: In function ‘int print_a(char*)’: 
source.cpp:6:15: error: ‘begin’ was not declared in this scope 
    for(char c : array) 
      ^
source.cpp:6:15: note: suggested alternatives: 
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0, 
       from /usr/include/c++/4.9/string:52, 
       from /usr/include/c++/4.9/bits/locale_classes.h:40, 
       from /usr/include/c++/4.9/bits/ios_base.h:41, 
       from /usr/include/c++/4.9/ios:42, 
       from /usr/include/c++/4.9/ostream:38, 
       from /usr/include/c++/4.9/iostream:39, 
       from source.cpp:1: 
/usr/include/c++/4.9/initializer_list:89:5: note: ‘std::begin’ 
    begin(initializer_list<_Tp> __ils) noexcept 
    ^
/usr/include/c++/4.9/initializer_list:89:5: note: ‘std::begin’ 
source.cpp:6:15: error: ‘end’ was not declared in this scope 
    for(char c : array) 
      ^
source.cpp:6:15: note: suggested alternatives: 
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0, 
       from /usr/include/c++/4.9/string:52, 
       from /usr/include/c++/4.9/bits/locale_classes.h:40, 
       from /usr/include/c++/4.9/bits/ios_base.h:41, 
       from /usr/include/c++/4.9/ios:42, 
       from /usr/include/c++/4.9/ostream:38, 
       from /usr/include/c++/4.9/iostream:39, 
       from source.cpp:1: 
/usr/include/c++/4.9/initializer_list:99:5: note: ‘std::end’ 
    end(initializer_list<_Tp> __ils) noexcept 
    ^
/usr/include/c++/4.9/initializer_list:99:5: note: ‘std::end’ 
+0

Was ist die Fehlermeldung der Compiler geben wird? – Iowa15

+0

@Davycc, wird es besser sein, die Fehlermeldung auf die Frage hinzuzufügen. Sie können den Kommentar danach entfernen. –

Antwort

7

Der Grund ist es nicht kompiliert ist, dass in C einen Funktionsparameter ++ wie char array[] zu char* array eingestellt ist. Ihre Funktion sieht wirklich wie

int print_a(char* array) 
{ 
.... 
} 

und den Bereich basiert Schleifen können nicht mit einem Zeiger umgehen.

Eine Lösung ist das Array durch Bezugnahme passieren. C++ erlaubt es nicht, einfache Arrays nach Wert zu übergeben. Zum Beispiel würde dies eine Reihe von 5 char s akzeptieren:

int print_a(const char (& array)[5]) 
{ 
    for(char c : array) cout << c; 
    cout << endl; 
    return 42; 
} 

Um dies zu Arrays unterschiedlicher Größe zu verallgemeinern, können Sie eine Vorlage verwenden:

template <std::size_t N> 
int print_a(const char (& array)[N]) 
{ 
    for(char c : array) cout << c; 
    cout << endl; 
    return 42; 
} 

Natürlich gibt es leichter Möglichkeiten zum Drucken einer nullterminierten Zeichenfolge:

Und es gibt Standard-Bibliothekstypen, die das Übergeben von String- oder Zeichenpufferobjekten vereinfachen. Zum Beispiel std::string, std::vector<char>, std::array<char, N> (wo N eine Kompilierung konstant ist.)

+0

Danke! spiele ich nur mit ihm. Es ist eine Art Übung für mich.Ich stimme zu, es gibt viele bessere Möglichkeiten, das Gleiche zu tun, aber es ist der einfachste Weg, um über range-based Loops und Array Decaying herauszufinden, nicht wahr ?! P.S. Danke euch allen, Leute. Ich schätze Ihre Hilfe! – Davycc

+1

@Davycc Es ist wirklich Typanpassung. Verfall ist der Fall, wenn Sie einen Zeiger von einem Array initialisieren. – juanchopanza

3

Hier

int print_a(char array[]) 
{ 
    for(char c : array) 
     cout << c; 
    cout << endl; 
    return 0; 
} 

Das Array zu einem pointer abgeklungen ist, weil, wenn Sie ein Array-Wert sein passieren, was genau Sie tun passieren der Zeiger auf das erste Element des Arrays und Bereich basierend Schleifen können nicht mit Zeigern arbeiten, daher der Fehler, den Sie bekommen.

See this für wie Arrays sind zerfallen und was ist die Lösung.

Sie müssen übergeben durch Referenz oder Zeiger.

3

Wenn Sie das Array an die Funktion übergeben, es „Zerfälle“ auf einen Zeiger. Wie in der Funktion sieht das wirklich so aus: int print_a(char *array) {...} Die Art der Schleife, die Sie verwenden, eine Bereichsschleife genannt, kann Zeiger nicht behandeln, die die Quelle des Fehlers ist (Versuch, über einen Zeiger zu iterieren, macht keinen Sinn).

Entweder Sie müssen das Array als Referenz übergeben oder verwenden Sie einfach eine normale for-Schleife.

Ehrlich, wenn Sie C++ verwenden, verwenden Sie C++. Verwenden Sie std::string, or std::vector.

+0

Das Array * verfällt nur *, wenn Sie es übergeben, da der Funktionsparameter ein Zeiger ist. – juanchopanza

Verwandte Themen