PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Warum keine Klassen für Ein-/Ausgabe?



p_mork
16.03.2007, 20:16
Hallo,

die Frage ist wahrscheinlich etwas blöd, aber trotzem würd ich mal gerne wissen, warum immer "printf" oder wie es auch heist für die Ein-/Ausgabe über den UART verwendet wird und nicht "cout"? Habe mal irgendwo gehört, der Speicherverbrauch wäre sehr hoch, doch nachdem ich die Klassen istream und ostream(die halbwegs die Klassen istream und ostream am PC imitieren) geschrieben hab, kam da garnicht mal soo viel an Programmcode raus. Den RAM-Verbrauch hab ich mir nocht nicht angesehen. Ist er wirklich so exterm, wie das behauptet wird? Und wenn ja warum?

MfG Mark

SprinterSB
16.03.2007, 22:15
Hast du float-Unterstützung in deinen Stream-Klassen?

p_mork
17.03.2007, 09:41
Hast du float-Unterstützung in deinen Stream-Klassen?

Ja, float und double. Double aber nur für ostream, da ich keine "atod"-Funktion gefunden habe und keinen Sinn sehe, die selber zu schreiben, da float für die meisten Fälle genügt. Wenn ich die aber auch verwende, steigt der Speicherverbrauch so um die 1,6kb(für cout) bzw 800b(für cin) an, das liegt aber an der Funktion "dtostrf" bzw "atof" und nicht an meinen Klassen.

iostream.h:



#ifndef _IOSTREAM_H_
#define _IOSTREAM_H_

typedef void (*function) (void);
typedef void (*function_char) (char);
typedef char (*char_function) (void);

#define ESC 27

class ostream
{
private:
function_char _putchfunc;
char szBuff[16];

public:

ostream(function_char f)
{
_putchfunc=f;
};


ostream &operator<<(char*rhs)
{
output(rhs,_putchfunc);
return *this;
};

ostream &operator<<(char rhs)
{
_putchfunc(rhs);
return *this;
};

ostream &operator<<(int rhs)
{
output(itoa(rhs,szBuff,10),_putchfunc);
return *this;
};

ostream &operator<<(long rhs)
{
output(ltoa(rhs,szBuff,10),_putchfunc);
return *this;
}

ostream &operator<<(float rhs)
{
output(dtostrf(rhs,1,3,szBuff),_putchfunc);
return *this;
};
ostream &operator<<(double rhs)
{
output(dtostrf(rhs,1,3,szBuff),_putchfunc);
return *this;
};
};

class istream
{
private:
function_char _putchfunc;
char_function _getchfunc;
char szBuff[16];
public:

istream(char_function f0,function_char f1)
{
_getchfunc=f0;
_putchfunc=f1;
};

istream &operator>>(char &rhs)
{
rhs=_getchfunc();
_putchfunc(rhs);
return *this;
};

istream &operator>>(char*rhs)
{
input(rhs,_getchfunc,_putchfunc,istream_max);
return *this;
};

istream &operator>>(int &rhs)
{
input_number(szBuff,_getchfunc,_putchfunc,6);
rhs=atoi(szBuff);
return *this;
};

istream &operator>>(long &rhs)
{
input_number(szBuff,_getchfunc,_putchfunc,11);
rhs=atol(szBuff);
return *this;
};

istream &operator>>(float &rhs)
{
input_number(szBuff,_getchfunc,_putchfunc,15);
rhs=atof(szBuff);
return *this;
};


};

#endif


Und so verwendet man diese:


#include <avr\io.h>
#include "iostream.h"

void _putch(char rhs) //empfängt ein Zeichen über den UART
{
while (!(UCSRA & (1<<UDRE)));
UDR = rhs;
};

char _getch() //Sendet ein Zeichen über den UART
{
while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar
return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben
};

void Uart_Init(unsigned int baudrate) //initialisiert den UART
{

baudrate=(F_CPU/16/baudrate-1);

UBRRL=static_cast<char> (baudrate);
UBRRH=static_cast<char> (baudrate>>8);
UCSRC=(1<<URSEL)|(3<<UCSZ0);
UCSRB=(1<<TXEN)|(1<<RXEN);
};

ostream cout(&_putch);
istream cin(&_getch,&_putch);

int main()
{
Uart_Init(38400);
float f=123.456;

cout<<"Hallo Welt!"<<endl //Aubgabe von "Hallo Welt" über den UART
<<f<<endl; //Ausgabe von 123.456
while(1);
}



Selbstverständlich lassen sich die Funktionen _getch und _putch durch beliebige andere ersetzten. Das Argument für den ostream-Konstruktor muss aber immer vom Typ void(char) sein, für istream der erste char(void) und das zweite void(char) für das Echo.

MfG Mark

SprinterSB
17.03.2007, 14:42
Zu printf etc: Ob ein Programm "viel" Code braucht ist relativ. Auf einem kleinen µC tut 1k evtl schon möchtig weh, während aufm PC kein Hahn nach 100k kräht.

Das Problem mit printf ist, daß je nach Format-Spezifier ein malloc gebraucht wird, weil zur Compilezeit die Größe des gebrauchten Puffers (bzw. eine Obergrenze dafür ) nicht bekannt ist. Man kommt also vom hundertsten ind tausendste...

Aber irgendwo gibt's auch abgespeckte Versionen von printf.