C++ Array-Initialisierung

Donnidonis

Commander
Registriert
Apr. 2009
Beiträge
2.604
Ich hab ein kleines Problem, bin noch recht neu bei C++ dabei.
In C# und Java macht mir sowas keine Probleme, doch hier :D

Mein Problem:
Ich will ein Array initialisieren, doch bekomme dauernd den Fehler:
Error: Der Ausdruck muss ein Konstantenwert aufweisen.
Ist ja auch recht deutlich der Fehler, aber wieso klappt dieser Code nicht?

Code:
const int upperLimitTmp = initialize();

bool gestrichen[upperLimit] = { false };

In initialize wird lediglich ein cin >> VariablenName gemacht und ein return.
Ich benutze Visual Studio 2013 Ultimate!

Liebe grüße
 
Dann bekomm ich einen Fehler dass die {...} erwartet werden.
Wenn ich anstatt dem Variablennamen eine 100 rein schreib, funktioniert es...
Mit der Variable allerdings nicht. Es funktioniert nur wenn ich 'const int upperLimit = 10; schreibe.
Es müsste also an meiner Funktion initalize liegen, denke ich..
Hier der Code:
Code:
int initialize()
{
	cout << "Geben sie eine Obergrenze ein: ";
	int grenze;
	cin >> grenze;
	return grenze;
}
 
in welcher Zeile kommt welche Meldung? Welcher Compiler? C++98 oder C++11/0x?
 
Die Array-Größe muss laut C++ Standard zur kompilierzeit bekannt sein. Manche compiler wie der GCC sind da nicht ganz so zickig, VC++ allerdings schon. :)

Einfach stattdessen einen Vektor benutzen.
 
1.) klammern weg - das ist eine Variablenzuweisung.
2.) ist deine variable gestirchen denn überhaupt als boolsches Array deklariert?
Eventuell hilft es zu beschreiben was du machen möchtest & den bisherigen Code in CODE-Tags zu posten.

togepi war schneller: Vektor umgeht das Problem...
 
Code:
bool gestrichen[upperLimit] = { false };
Hier kommt der Fehler mit der oben Beschriebenen Fehlermeldung.
Wo kann ich denn sehen welcher Compiler benutzt wird? Platformtoolset ist Visual Studio 2013(v120).

Ich möchte ein Programm zum Primzahlen ausgeben schreiben (Sieb des Erastosthenes).
Hier mein Code:
Code:
#include "stdafx.h"
#include <iostream>

using namespace std;

void startScreen();
int initialize();

int _tmain(int argc, _TCHAR* argv[])
{

	startScreen();
	const int upperLimit = initialize();

	// Variablen initialisieren
	bool gestrichen[upperLimit] = { false };
	int count = 0;

	// Alle Vielfachen von Primzahlen eliminieren
	for (int i = 2; i < sqrt(upperLimit); i++)
	{
		if (!gestrichen[i])
		{
			cout << i << "\t";
			count++;
		}
		for (int j = i*i; j < upperLimit; j = j + i)
		{
			gestrichen[j] = true;
		}
	}

	// Übgrig gebliebene ausgeben
	for (int i = sqrt(upperLimit) + 1; i < upperLimit; i++)
	{
		if (!gestrichen[i])
		{
			cout << i << "\t";
			count++;
		}
	}

	// Anzahl ausgeben
	cout << endl << "Es gibt " << count << " Primzahlen!" << endl;

	system("pause");

	return 0;

}

void startScreen()
{
	cout << "################################################################################";
	cout << "#                                                                              #";
	cout << "#      ####    ####    #   #       #   ######       #       #   #   #          #";
	cout << "#      #  ##   #  ##   #   ##     ##      ##       # #      #   #   #          #";
	cout << "#      ####    ####    #   # #   # #     ##       #####     #####   #          #";
	cout << "#      #       # #     #   #  # #  #    ##       #     #    #   #   #          #";
	cout << "#      #       #  #    #   #   #   #   ######   #       #   #   #   #####      #";
	cout << "#                                                                              #";
	cout << "################################################################################";
	cout << endl << endl;
}  

int initialize()
{
	cout << "Geben sie eine Obergrenze ein: ";
	int grenze;
	cin >> grenze;
	return grenze;
}

Ok den Startscreen könnt ihr hier vernachlässigen, in der Konsole sieht er schicker aus :D
 
Zuletzt bearbeitet:
Ich weiß nicht genau, ob das wichtig ist: upperLimitTmp ist eine andere Variable als upperLimit.
Nach den 3 Zeilen ist upperLimit weder deklariert, noch initialisiert.
 
Ich glaube Dein Fehler ist die Annahme das C++ VLA = Variable Length Arrays kennt.
<code>
bool gestrichen[upperLimit] = { false };
</code>
geht nur wenn upperLimit zur Compilezeit bekannt ist.
Das ist ein C99 Feature das es in C++ nicht gibt.
 
Die Schreibweise in Zeile 3 versucht bereits zur Compile-Zeit den Speicher für das Array festzulegen. Das klappt aber nicht mit Größen, die erst zur Laufzeit ermittelt werden - daher wird in diesem Fall ein Literal oder eine Konstante die mit einem Literal initialisiert wurde als Größe des Array verlangt.

In C++ kann man dynamisch dimensionierte Array so deklarieren:

Code:
bool *gestrichen = new bool[upperLimit];

Die Variable gestrichen ist dann natürlich ein Pointer, da dynamische Arrays nur auf dem Heap erstellt werden können.
 
Ja das mit dem upperLimitTmp war nur ein kleiner Fehler den ich nicht Rückgängig gemacht habe, es sollte upperLimit heißen.

Wie umgeh ich dann das Problem? Also kann ich nicht mit einem Array arbeiten?
 
Du solltest dich daran gewöhnen, dass C++ ein wenig anders funktioniert als Java/C#.

Auch wenn das vom Namen her verwirrend ist, so haben Java und C# mehr gemeinsam als C++ und C#.

Wenn man ein Array mit einer variablen Länge erstellen will, muss man einen Speicherbereich mittels "new" allozieren. Wie das im einzelnen funktioniert, ist hier beschreiben: http://www.cplusplus.com/doc/tutorial/dynamic/
 
Danke an Alle! Werde mich wohl noch ordentlich reinhängen müssen :p
Die Lösung von NeoTiger funktioniert, vielen Dank!
 
Lunke schrieb:
Du solltest dich daran gewöhnen, dass C++ ein wenig anders funktioniert als Java/C#.

Auch wenn das vom Namen her verwirrend ist, so haben Java und C# mehr gemeinsam als C++ und C#.

Wenn man ein Array mit einer variablen Länge erstellen will, muss man einen Speicherbereich mittels "new" allozieren. Wie das im einzelnen funktioniert, ist hier beschreiben: http://www.cplusplus.com/doc/tutorial/dynamic/

Dann aber doch lieber einen std::vector verwenden. Allerdings würde ich keinen std::vector< bool > sondern stattdessen lieber einen std::vector< unsigned char > nutzen, da das vector-Template, wenn es für bool instanziiert wird, dummerweise eine Spezialisierung verwendet, die sich in einigen Punkten signifikant anders verhält, als vektoren das normalerweise tun. Details hier: http://www.cplusplus.com/reference/vector/vector-bool/
Ergänzung ()

der dödel =D schrieb:
Danke an Alle! Werde mich wohl noch ordentlich reinhängen müssen :p
Die Lösung von NeoTiger funktioniert, vielen Dank!

Klar funktioniert es, aber in modernem C++ sollte man nackte, dynamische Arrays weitestgehend meiden und wo immer möglich lieber auf std::vector ausweichen. Gerade als Anfänger bieten dir nackte Arrays (bzw. Pointer darauf) zu viele Möglichkeiten, dir selbst in den Fuß zu schießen.


Besser als nackte Arrays:

Code:
const int upperLimitTmp = initialize();
     
std::vector< unsigned char > gestrichen( upperLimitTmp, false );
 
Zuletzt bearbeitet:
GrafZaal schrieb:
Es handelt sich dabei um Initialization Lists aus C++11.

C++11 hat initialization lists zwar enorm erweitert, aber in dieser Form gab es sie auch schon vorher. Code wie

Code:
bool gestrichen[10] = { false };

int numbers[ 200 ] = { 0, 1, 2, 3, 4 };

char myString[] = { 'f', 'o', 'o', 'b', 'a', 'r', '\0' };

char theSameString[] = "foobar";

war schon immer ok.
 
Zurück
Oben