- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 4 von 4

Thema: Warum keine Klassen für Ein-/Ausgabe?

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    25.03.2006
    Ort
    Darmstadt
    Alter
    33
    Beiträge
    522

    Warum keine Klassen für Ein-/Ausgabe?

    Anzeige

    Praxistest und DIY Projekte
    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

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Hast du float-Unterstützung in deinen Stream-Klassen?
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    25.03.2006
    Ort
    Darmstadt
    Alter
    33
    Beiträge
    522
    Zitat Zitat von SprinterSB
    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:

    Code:
    #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:
    Code:
    #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

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    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.
    Disclaimer: none. Sue me.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress