Konvertieren des Parameters von Float[] ind Float nicht möglich

Matz3

Grünschnabel
Guten Tag,

ich bin neu hier und hoffe durch diese Community ein besseres Verständnis für die Programmiersprache C++ zu bekommen.

Zu dem Programm:
Ich habe als Aufgabenstellung (Fachhochschule) ein Programm zu erstellen, welches die Y-Werte für ein Polynom n-ten Grades ausrechnet und damit dann eine Kurvendiskussion anfertige.

Zu meinem Problem.
Ich möchte einen Vektor mit den X-Werten an eine Funktion übergeben. In der Funktion soll dann mit den X-Werten, die entsprechenden Y-Werte ausgerechnet werden.

Beim Übergeben des Vektors (vektorx) an die Funktion (BerechnungY) erhalte ich folgenden Fehler:

error C2664: 'BerechnungY': Konvertierung des Parameters 1 von 'float [21]' in 'float' nicht möglich

Das selbe ist beim Rückgabewert der Fall. Hier erhalte ich einen ähnlichen Fehler wenn ich die Y-Werte (vektory) zurückgeben möchte:

error C2440: 'return': 'float [21]' kann nicht in 'float' konvertiert werden


Die Main-Funktion:
C++:
#include <stdio.h>
#include <math.h>

float BerechnungY (float, int, int);

void main (){

int a_n, i;
  
////////////////////////Eingabe von a

    printf("Polynomberechnung n-ten Grades \n\n");
    printf("Polynom welchen Grades?: "); scanf_s("%d", &a_n);   //Eingabe welchen Grades das Polynom ist
    a_n=a_n+1;
    int* a= new int[a_n];
    i=a_n;
   
    while(0<i){
        i--;
        printf("Eingabe der %d", i); printf(". Stelle:"); scanf_s("%d", &a[i]);  
    }
  
////////////////////////Eingabe von X
    int x_n;
    int range;
    printf("\nBitte Wert fuer x eingeben \n\n");
    scanf_s("%d", &x_n);
    int x=x_n;
    x_n=2*x_n+1;
    range=x*(-1);
  

////////////////////////Werte für X in Vektor schreiben
  
    i=-1;
    x=x+1;
    float vektorx[21];

    while (range<x){
        x--;
        i++;
        vektorx[i]=x;
    }


///////////////Werte für Y ausrechnen

    BerechnungY (vektorx, a, a_n);
       

    return;
}


Die Unterfunktion:
C++:
#include<stdio.h>
#include<math.h>

float BerechnungY (float vektorx[21], int a[5], int a_n){

    float vektory[21];
    int i=22;
    float yn;
    int ycount;
    int test;

while (0<i){
        yn=0;  
        i--;
        vektory[i]=0;
        ycount=a_n;

            while (ycount>0){
               ycount--;
               test=pow(vektorx[1], ycount);
   
               yn=a[ycount]*test;
               vektory[i]=vektory[1]+yn;
        }
        return vektory;
    }


Ich wäre für jeder Hilfe, zu der Lösung dieses Problems dankbar.


Mit freundlichen Grüßen
Matze
 
Zuletzt bearbeitet:
Hi und Willkommen bei tutorials.de,

erste Gegenfrage: C oder C++?
Du schreibst zwar C++, dein Code schaut aber nach lupenreinem C aus
(na gut, mit Fehlern, aber C :))

Ein C-Programm ist in vielen Fällen zwar auch ein gültiges C++-Programm,
aber kein schönes C++-Programm, um es so auszudrücken.
Und so Sachen wie Arrays (bei dir "Vektoren") mit veränderbarer Größe gibts zumindest
einfacher für den Programmierer, zB. mit einer Klasse "vector" (da heißts wirklich Vektor)
 
Also nach den Angaben unseres Lehrbeauftragten lernen wir C++ ;-)
Und in Visual Studio wähle ich auch ein "Visual C++ Projekt", wenn ich ein neues Projekt erstelle.
Ich kenne den Unterschied leider nicht, aber Sachen wie

C++:
 std::vector

sagen mir z.B. überhaupt nichts.
Klassen hatten wir leider noch nicht behandelt (Nur in Matlab, aber da war sowieso alles viel einfacher :D)

Ist das Problem nicht so einfach zu lösen?
 
Moin,

von dem was Shell schrieb mal abgesehen:
Deine Signaturen von "BerechnungY" stimmen bei den ersten beiden Parametern nicht über ein !!
C++:
float BerechnungY (float, int, int);
....
float BerechnungY (float vektorx[21], int a[5], int a_n)

Zudem ist hier Dein Rückgabewert als "float" deklariert, Du versucht aber "vektory" von Typ "float vektory[21]" zurückgeben!

Bzgl.
C++:
std::vector
solltest Du mal einen Blick in die API werfen!

Gruß
Klaus
 
Zum Lehrbeauftragten: Das ist leider häufig so :/
Nur mit dem Wissen von Lehrern würde ich heute auch noch immer glauben,
dass C mit Klassen das Selbe wie C++ ist :)

Zum Projekttyp: Wie gesagt, C++ inkludiert C zu großen Teilen.
Bei Visual Studio gibt es nur einen Compiler (und Projekttypzeug usw.) für C und C++ zusammen,
und C wird eben wie C++ behandelt (dem Compiler ist es natürlich egal, ob es ein "schönes" C++-Programm ist)
Für die paar Sachen, die in C gültig sind und in C++ nicht bzw. anders
wird nach der Dateiendung entschieden, was es sein soll
(also meinprogramm.c oder meinprogramm.cpp)

(Zum vector: Das std:: hatte ich noch nicht erwähnt, also irgendwie kennst es ja doch :p)
Also vorerst Annahme C.

Zuerst BerechnungY:
C++:
float BerechnungY (float vektorx[21], int a[5], int a_n)
Angefangen mit a (warum nicht polynom?): Du übergibst ein Array a und die Werteanzahl in a_n,
aber bei a schreibst du trotzdem fix 5 als Größe. Warum? Der Compiler ignoriert die 5 zwar
(zumindest bei eindimenionalen Arrays), man kann also beliebige Größen übergeben,
aber "int *a" (oder "int a[]") wären wohl angebrachter.

Selbes mit vektorx, wobei hier ein x_n noch ganz fehlt (und der Inhalt der Funktion
entsprechend angepasst werden sollte. Kein fixes 22 usw.)

Eine wichtige Zwischenbemerkung zu Parameterübergabe:
Theoretisch werden alle Variablen beim Übergeben kopiert, zB. das a_n vom Main.
Wenn das a_n in der Funktion geändert wird wird nur die Kopie geändert,
und diese verschwindet m Funktionende wieder. Bei Arrays wird aber nicht
das ganze Array kopiert, sondern die Pointeradresse, die noch immer auf die
selben 21 Werte (oder wie viel es eben sind) zeigt. Änderungen der Arrayelemente
wirken sich also auch auf die Daten im main aus.

Noch zum Returnwert: "float" bedeutet ein einzelnes float. "float *" wäre wieder ein Array, ABER:
Normale lokale Variablen innerhalb der Funktion verschwinden auch an deren Ende wieder.
SObald das returnte vektory im main ankommt existiert vektory nicht mehr,
und das Verwenden der Arrayelemente im main kann Probleme machen
(kann aber auch gut gehen, ist nicht voraussagbar).

Die einfachste Lösung wäre, das Zielarray auch als Parameter zu übergeben und einfach nichts (void) zu returnen
(Änderungen bei Arrays bleiben ja auch nach Funktionende...).
vektory braucht dabei keinen geonderten Größenparameter, man kann ja einfach annehmen,
dass es gleich größ wie vektorX ist (dass es auch so ist ist die Aufgabe von main)
In der Funktion entsprechend das return weg.

Und der Berechnungsteil schaut programmatisch richtig, aber mathematisch falsch aus.
Ein möglicher Pseudocode:
Code:
für alle i von x_n-1 bis 0
{
    y[i]=0;
    float potenz = 0.0
    für alle j von a_n-1 bis 0
    {
        y[i] += a[j] * potenz;
        potenz *= x[i];
    }
}

Main kommt später noch...
 
Vielen Dank erst einmal für die Hilfe :)

Ich habe jetzt den Code so umgeschrieben wie ihr mir das empfohlen habt.
Ich weiß nicht ob die jetzigen Fehlermeldungen die davor aufgehoben haben, aber die ersten Fehlermeldungen sind jetzt (anscheinend) erst einmal behoben.

Jetzt zu den neuen Fehlermeldung:
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""float __cdecl BerechnungY(float *,int *,int,int,int)" (?BerechnungY@@YAMPAMPAHHHH@Z)" in Funktion "_main".
error LNK1120: 1 nicht aufgelöste Externe


Wenn ich die Fehlermeldung richtig interpretiere, dann hat er ein Problem mit dem ersten float-Array, welches übergeben wird. Aber was genau da jetzt falsch ist, wisst ihr bestimmt ;-)

Das ist der neue Code:
C++:
#include <stdio.h>
#include <math.h>

float BerechnungY (float*, float*, int, int*, int, int);


void main (){

int a_n, i;
  

////////////////////////Eingabe von a

    printf("Polynomberechnung n-ten Grades \n\n");
    printf("Polynom welchen Grades?: "); scanf_s("%d", &a_n);
    a_n=a_n+1;
    int* a= new int[a_n];
    i=a_n;
    while(0<i){
        i--;
        printf("Eingabe der %d", i); printf(". Stelle:"); scanf_s("%d", &a[i]);

    }
  
////////////////////////Eingabe von X
    int x_n;
    int range;
    printf("\nBitte Wert fuer x eingeben \n\n");
    scanf_s("%d", &x_n);
    int x=x_n;
    x_n=2*x_n+1;
    range=x*(-1);
  

////////////////////////Werte für X in Vektor schreiben
  
    i=-1;
    x=x+1;
    float* vektorx= new float[x_n];
    float* vektory= new float[x_n];
    float yn;
    int ycount;
  

    while (range<x){
        x--;
        i++;
        vektorx[i]=x;
        printf("%f", vektorx[i]);
        printf("%d", x);
    }

///////////////////////////Werte für Y ausrechnen

    BerechnungY(vektorx, vektory, x_n, a, a_n, range);
   
    return;
}

Funktion:
C++:
#include<stdio.h>
#include<math.h>

void BerechnungY (float *vektorx, float *vektory, int x_n, int *a, int a_n, int range){


    int i=-1;
    float yn;
    int ycount;
    int xpotenz;
    x_n=(x_n-1)/2;
  
while (range<x_n){
        yn=0;
        x_n--;
        i++;
        vektory[i]=0;
        ycount=a_n;
      
        while (ycount>0){
            ycount--;
            xpotenz=pow(vektorx[i], ycount);
            //////////////////////////////////////Ausrechnen von yn
            yn=a[ycount]*xpotenz;
            vektory[i]=vektory[i]+yn;
          
        }
    }
}
 
Der Teil
C++:
while (ycount>0){
            ycount--;
            xpotenz=pow(vektorx[i], ycount);
            //////////////////////////////////////Ausrechnen von yn
            yn=a[ycount]*xpotenz;
            vektory[i]=vektory[i]+yn;
         
        }
macht noch immer nicht wirklich Sinn; sonst schaut alles in der Funktion bisher gut aus.

Zum Fehler: Main und die Funktion hast du ja in verschiedenen Dateien,
und die Funktion in ihrer Datei kann nicht mit dem Aufruf in main in Verbindung gebracht werden
(dass das BerechnungY, das im main aufgerufen wird, das Selbe ist wie das in der Funktion)
Wie/womit schreibst und kompilierst du dein Programm?

Was im main sonst nicht passt wird jetzt gechrieben...
 
Hallo Matz3, hallo Shell :))),
die Funktion BerechnungY hat nun den Rückgabetyp void, das ist gut, allerdings muss der Prototyp dann natürlich auch den gleichen Typ haben.
Also musst du das:
C++:
float BerechnungY (float*, float*, int, int*, int, int);
zu dem ändern:
C++:
void BerechnungY (float*, float*, int, int*, int, int);

@sheel: In deinem Pseudocode hat sich noch ein kleiner Fehler eingeschlichen :):
Code:
für alle i von x_n-1 bis 0
{
    y[i]=0;
    float potenz = 1.0; // muss mit 1 initialisiert werden
    für alle j von a_n-1 bis 0
    {
        y[i] += a[j] * potenz;
        potenz *= x[i];
    }
}

Viele Grüße
Technipion
 
Also, bei der Zeile über main gibt BerechnungY noch ein float statt void zurück.

Der Rückgabetyp von main selber darf nicht selbst ausgesucht werden und nicht void sein,
sondern int, und der Wert beim return sollte 0 sein (man kann es genauer differenzieren,
dass 0 "OK" und alle andere verschiedene Fehler bedeutet, aber das ist erst wichtig,
wenn das Programm automatisch von anderen Programmen verwendet werden soll).

Das:
C++:
int* a= new int[a_n];
wäre in C++ ok (einfacher mit std::vector), existiert so in C aber nicht.
Für eine reine C-Lösung malloc verwenden:
C++:
int* a = (int*)malloc(a_n * sizeof(int));
Analog dazu für VektorX:
C++:
float* vektorx = (float*)malloc(a_n * sizeof(float));
Mit VectorY natürlich das Selbe.

Und Speicher, den man mit malloc/new erzeugt hat, muss man mit free/delete auch
wieder wegräumen: Irgendwo vor Programmende, wenn die Arrays nicht mehr gebraucht werden:
C++:
free(vektorx); /*wenn malloc verwendet*/
delete[] vektorx; //wenn new verwendet
Selbes wieder auch mit den anderen Arrays.

Bei scanf (scanf_s usw.) bekommt man ein Problem, wenn man zB. mit %d ein int
einlesen will und der Benutzer Buchstaben eingibt. Dafür kann man den Returnwert
von scanf prüfen: Das ist die Anzahl der erfolgreich eingelesenen Variablen.
Wenn man ein %d haben will, also im Idealfall 1. Sonst dem Benutzer sagen,
dass die EIngabe nicht gepasst hat oder in einer schleife eine Wiederholung
der Eingabe verlangen oder...

Und bei Range bin ich mir nicht ganz sicher, wozu das gut ist :)

edit @Technipion: Danke, stimmt :)

edit2: Wenn man ganz pedantisch sein will:
An ein paar Stellen gibts mögliche int-Overflows, also das die Zahl durch Addieren/Multiplizieren
von Etwas zu groß/klein für die Variable werden könnte.
(dann bekommt man irgendeinen Wert, nur nicht den, den man gern hätte).
Aber das ist vorerst wohl eher zu vernachlässigen, und verwirrt sonst noch sehr :)
 
Vielen Dank erst einmal für eure Hilf bis hierher :)

Ich wollte mich nur mal melden und eine kleine Zwischenbilanz abgeben.
Also ich habe es jetzt hinbekommen.
Der mathematische Teil müsste eigentlich so stimmen, wie ich ihn niedergeschrieben habe, da ich die Ergebnisse von C/C++ mit meinem Taschenrechner noch einmal nachgerechnet habe.

Nun werde ich mich an den Rest, der Kurvendiskussion machen.

Hierzu noch eine Frage:
Kann ich irgendwie die Größe/Länge eines Vektors auslesen?
Denn die Aufgabenstellung verlangt, dass ich nur die x-Werte und die y-Werte an die Funktion für die Extremwertbestimmung übergebe und somit weiß man in der Funktion ja nicht wie viele Einträge das Array besitzt.
 

Neue Beiträge

Zurück