Blandade C++ frågor, nybörjarnivå

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Mr Andersson
Inlägg: 1409
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Mr Andersson »

Du kan använda en initializer.

Kod: Markera allt

static int Counter = 12345;
Eller som standarden säger; c89 draft
If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

@lillahuset, zealotry & Mr Andersson:
Tackar för förklaringarna! Läste också igenom länken du gav z och nu är det mycket klarare.
Satt och funderade på varför jag inte visste det här innan men jag tror det är så illa att jag knappt aldrig innan gjort separata funktioner utan skrivit allt i main-loopen och (antagligen) inte behövt det här. I vilket fall så har jag lärt mig något nytt :tumupp:

Nu ska jag grotta ner mig i Icecap's inlägg. Tack för att du tog dig tid!
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Hänger med på det mesta du skriver Icecap och klasser är något jag inte gett mig på än.
Är dock väldigt undrande över en sak, och det är vad Jan Almqvist skrev tidigare; att inte använda globala variabler utan skicka parametrar till funktionerna...

Hmm, nä fasen, är rädd för att jag kanske förstår nu. Läste om inläggen samt lite i en bok om C.
Ska fortsätta programmet nu och se om jag får ihop det. Tack så länge :tumupp:
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av sodjan »

Fördelen med att ha hela "interfacet" mellan den anropande koden (t.ex. main() )
och den anropade funktionen i själva anropet, är att det är enklare att se vad
som är gemensamt, så att säga, mellan anroparen och det anropade.
Allt syns i funktions deklarationen.

Men visst, det är inte helt ovanligt att man har vissa flaggor eller status
eller något liknande som i princip används överallt, då kan det vara enklast
att helt enkelt ha dom globala för alla. Men kanske inte för parametrar som
är unika för en viss funktion.

Sen så är det så klart något snabbare att ha globala variabler som alla
rutiner och kan nå direkt utan att använda stack eller liknande. De globala
variablerna ligger ju där de ligger, så att säga...
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Det var skönt att höra, alltså att ibland använder även ruttade människor globala variabler :wink:

Om någon har tid så får ni gärna verifera att jag tänker rätt här:

doPrintDisplay() ska inte returnera något så därför valde jag void.
Funktionen ska dock använda en uint16_t parameter som heter sendBuffer.
Denna variabel initieras i while-loopen samt att jag därifrån anropar funktionen genom doPrintDisplay(sendBuffer);.
I nuläget får jag en kompileringsvarning pga att sendBuffer inte initierats riktigt men ger jag den ett värde så kompilerar filen ok. Kommer fortsätta imorrn då den kommer tilldelas det riktiga värdet.
Men det är alltså så här jag skickar parametrar mellan funktioner?

Kod: Markera allt

void doPrintDisplay(uint16_t sendBuffer) {
	
									//  LATCHCLK_PIN = 1
				
	for(int i=0; i<16; i++) {
			
		if(sendBuffer & (i)) {
				PORTB |= 1 << PB0;  //  SDO_PIN = 1
				PORTB |= 1 << PB2;	//  SHIFTCLK_PIN = 1
		}
		else {
				PORTB &= ~PB0;		//  SDO_PIN = 0
				PORTB |= 1 << PB2;  //  SHIFTCLK_PIN = 1
		}
	}
									//  LATCHCLK_PIN = 1
	
}

while(1) {

        uint16_t sendBuffer;
		
		doButtonDebounce();

		doCheckSerialCom();
		
		doDebug();
		
		switch (::ShowOnDisplay(showData)) {
			case 0:
				break;
			case 1:
				doCheckTemp();
				break;
			case 2:
				doCheckHVRail();
				break;
			default:
				break;

		}

		doPrintDisplay(sendBuffer);


	}
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av sodjan »

Ja, i princip. Jag skulle dock inte använda samma namn på
parametern i funktionen som den globala variabeln, det finns
igen anledning till det och det kan förvilla. Alltså t.ex.:

Kod: Markera allt

    void doPrintDisplay(uint16_t tmpbuf) {
    ...
    ...
            if(tmpbuf & (i)) {
    ...
    }
     
    while(1) {
     
            uint16_t sendBuffer;
            ...
            doPrintDisplay(sendBuffer);
        }
Det blir lite tydligare vad som är vad och mindre förvirrande
när man t.ex. söker i koden efter en variabel...
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Ahaa, det var så dom menade i boken. Förstod inte att man kunde ange ett nytt variabelnamn till parameter direkt när man "importerar" den till en funktion.

När jag såg ditt exempel så tyckte jag först att det kändes ologiskt att ha ett annat namn på den men nu när jag tänker efter så är det ju snarare skitbra. Då gör jag ju en separat funktion för att just "printa buffer" och sen kan jag skicka dit vilken buffer som helst i programmet.
Hade jag i detta läge använt samma parameternamn så skulle det ju bara bli rörigt.
Snyggt! Tackar för detta!
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av sodjan »

Exakt! :-)
Det enda intressanta är att data typerna stämmer överens.
I detta fall en uint16_t, men det är ofta t.ex. en pakare till char ("sträng").

Kompilatorn översätter ju allt till adresser i alla fall...

Ta t.ex en sådan funktion som fprint(), inte vet du vilka namn som den som
skrev fprint() använde, eller hur? Och inte spelar det någon roll vilka namn
som du själv använder i anropet till fprint()?
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Det här kanske blir lite mer IDE+MCU relaterat men gör ett försök.

Avsikten är att skriva över lite data till ett skiftregister men det är något jag missar.
Mest ligger felet i hur man skriver till en bit i PORT-registret, eller i alla fall har med det att göra.

Felet visar sig genom att jag försöker skriva ut 10101010101 på porten men får istället ut typ 110011000000000011001100.
Data.jpg

Kod: Markera allt

void doPrintDisplay() {

	uint16_t tmpBuffer;
	tmpBuffer = 0xAAAA;						// Ge variabeln ett värde med varannan 1:a
											// för att underlätta debugging
	
	for(int i=0; i<16; i++) {				// Loopa 16 ggr och öka i varje varv
			
		if(tmpBuffer & i) {					// AND:a i med variabeln. Är biten 1 så gör nedan, annars hoppa till else
				PORTD |= (1 << PD5);		//  SDO_PIN = 1
				PORTD |= (1 << PD2);		//  SHIFTCLK_PIN = 1
		}
		else {
				PORTD &= ~(1 << PD5);		//  SDO_PIN = 0
				PORTD |= (1 << PD2);		//  SHIFTCLK_PIN = 1
		}
		PORTD &= ~(1 << PD2);				//  SHIFTCLK_PIN = 0
	}
	
}
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Icecap
Inlägg: 26630
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Icecap »

Kod: Markera allt

#define Set_SDO_PIN()        PORTD |= (1 << PD5)
#define Set_SHIFTCLK_PIN() PORTD |= (1 << PD2)
#define Clear_SDO_PIN()      PORTD &= ~(1 << PD5)
#define Clear_SHIFTCLK_PIN PORTD &= ~(1 << PD2)

void doPrintDisplay(void)
  {
  uint16_t tmpBuffer;
  tmpBuffer = 0xAAAA;                     // Ge variabeln ett värde med varannan 1:a
                                                // för att underlätta debugging
  for(int i = 0; i < 16; i++)
    { // Loopa 16 ggr och öka i varje varv
    if(tmpBuffer & 0x01) Set_SDO_PIN();
    else Clear_SDO_PIN();
    Set_SHIFTCLK_PIN();
    tmpBuffer >>= 1; // Shifta ner bitsen 1 steg
    Clear_SHIFTCLK_PIN();
    }
  }
I mina ögon lite lättare att läsa och denna borde fungera. Den skickar LSB först.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Uppskattar verkligen hjälpen Icecap och menar verkligen inte att vara otacksam, men jag måste försöka förstå vad som händer också.

Om jag jämför våra två snuttar nu så tycker jag att den enda skillnaden är att jag läser en specifik bit i variabeln, medans du alltid läser LSB och skiftar.
Tvekar inte på att din snutt fungerar men jag försöker förstå vad jag gör fel.
Användarvisningsbild
Icecap
Inlägg: 26630
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Icecap »

Din version läser INTE en bit!

Du AND'er med ett värde som stegar genom 0-15.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Vad skulle jag göra utan er.
Det är ju klart att det blir så. Ibland kommer mitt "nummer" (i) matcha och ibland inte...

Lade till if(tmpBuffer & 0x01) och skiftar bitarna ett steg nedåt, som du visade. Och ja, det fungerar :bravo:

Känns bra att fläska över data i 1 Mhz!
Data1.jpg
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
ecenier
Inlägg: 1149
Blev medlem: 13 december 2007, 17:51:42
Ort: Älvsjö
Kontakt:

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av ecenier »

Magnus_K skrev:Uppskattar verkligen hjälpen Icecap och menar verkligen inte att vara otacksam, men jag måste försöka förstå vad som händer också.

Om jag jämför våra två snuttar nu så tycker jag att den enda skillnaden är att jag läser en specifik bit i variabeln, medans du alltid läser LSB och skiftar.
Tvekar inte på att din snutt fungerar men jag försöker förstå vad jag gör fel.
Du kan fixa din kod genom att endast ändra raden,

Kod: Markera allt

       if(tmpBuffer & i) {                 // AND:a i med variabeln. Är biten 1 så gör nedan, annars hoppa till else
till

Kod: Markera allt

       if(tmpBuffer & (1<<i)) {                 // AND:a i med variabeln. Är biten 1 så gör nedan, annars hoppa till else
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Blandade C++ frågor, nybörjarnivå

Inlägg av Magnus_K »

Ahaaa se där, det var ju så jag försökte göra :wink:
Tack ecenier!
Skriv svar