C variabele declareren ?

trix

Golden Member

hallo,

AVR studio 7

ik heb een wat groter programma, wat ik voor de duidelijkheid heb op gedeeld in blokken.
zo'n blok is bijvoorbeeld: 4_create_beams.h
dat zorgt er voor dat die: create_beams in een appart tablad komt.

probleem is nu,als ik in zo,n tabblad een variabele declareer, dan kan ik die niet gebruiken in een ander tablad.

bij sommige variabele en tabbladen gaat dat wel, die declareer ik dan in het 1e tabblad waar die variabele gebruikt word (de tabbladen worden achter elkaar af gewerkt).

maar als de tabbladen niet achter elkaar komen werkt dat niet.
dus ik denk die declareer ik dan globaal (voor de main), dat werkt niet, o ja....dat moest volatile, maar dat werkt ook niet.

weet iemand hoe ik dit oplos ?
tnx.

eigenwijs = ook wijs
Arco

Special Member

Ik weet niet hoe dat in C gaat, maar bij Mikrobasic moet ik in meerdere sourcefiles wel aangeven dat die globale variabele extern is gedeclareerd...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
EricP

mét CE

Eh... Ik denk dat ik het probleem niet snap.

In een header file zet je headers (hey... die namen lijken op elkaar). Dus prototypes van functions en definities van data structuren - die je dan later gebruikt.

Bij een header files hoort een file (of meerderen, handiger voor libraries) waarin eea. uitgewerkt wordt. Je declareert in het headerfile een function. In het bijbehorende (doorgaans C) file staat die function.

Het doel is om de compiler te laten weten hoe definities eruit zien. Zodat je op 1 plek de definitie neer zet en die dan 'overal' kunt gebruiken (zonder die elke keer te moeten copieren).

Globals... Ja, het zou kunnen. Maar wel vies.

Een global HOEF je niet volatile te maken. Echter, soms gaat de optimization het bos in als er ondertussen ook nog ff wat anders aan trekt. Volatile is niks anders dan de optimizer vertellen dat je niet de enige bent die aan dit stukje memory trekt - en het werken met een copietje in registers dus niet handig is. Vooral gebruikt bij globals die in interrupt routines worden gebruikt (buffer, flags) of memory mapped I/O.

Wat eea. met tabbladen te maken heeft, dat weet ik niet. Ik spreek vloeiend C. Maar geen AVRstudios.

Dit geschreven hebbende... heb ik het idee dat je op een bijzonder ranzige manier je source in stukken hebt geknipt om die onafhankelijk van elkaar te kunnen editen.
Als dat al nodig is, doe het dan netjes en klus functions die bij elkaar horen in 1 file, maak er een header file voor en link het object file gewoon mee. Dat is hoe het werkt in C.

De vreselijke knutsel manier (windows gebruiker?) is een stel losse files maken en die includen in wat je 'main' is. Erg vies (over onleesbare code gesproken...), maar ja, het zou moeten kunnen werken. Een include is ook niks anders dan wat de naam zegt: lees hier de inhoud van het gespecificeerde file alsof het hier staat. Inderdaad bedoeld voor header files die definities van bevatten...

trix

Golden Member

dit is hoe ik het nu doe,

c code:


int main(void)
{

#include "find_A.h"
#include "find_B.h"			
#include "find_C.h"

}

dit is voor mij super overzichtelijk, eerst find_A dan find_B en als laatste find_c

afzonderlijke tabbladen voor afzonderlijke taken.

boven de tabbladen en onderaan hoe ik ze aanroep.

eigenwijs = ook wijs
EricP

mét CE

Ga naar de gevangenis. Ga niet langs start. U moet 10 beurten overslaan.

Kijk, C is nou niet de taal die de meeste structuur afdwingt. Maar om er een dergelijke puinhoop van te maken... Da's echt nergens voor nodig!

Als er afzonderlijke taken zijn, dan stop je die per taak bij elkaar. De declaraties netjes in een header file zodat de rest van de wereld het ook weet.

Waarschijnlijk kun je in zo'n integrated environment wel ergens vertellen welke files nog meer mee moeten, zodat het ding wel een make file voor je bakt en er voor zorgt dat de linker de juiste object files mee neemt.

Zoals jij nu - met alle respect - aan het modderen bent, ga je steeds verder het moeras in...

Daarnaast... includes staan helemaal boven in in principe. *Nooit* binnen een function. Zoals je ziet, laat C het wel toe. De compiler is geen schoolmeester: als jij een puinhoop wilt, dan kun je een puinhoop krijgen :). Nou, die heb je nu :+ .

trix

Golden Member

maar dit werkte zo lekker overzichtelijk voor het geen wat ik moet doen,......tot nu :(
ik heb hier al eens een topic over gehad dacht ik, maar dat werd zo onduidelijk (voor mij althans).
toen heb ik deze methode ontdekt, deed dus exact wat ik wilde.
ik ga die betrefende topic er eens bij bijzoeken, kijken of ik het nu wel snap.

eigenwijs = ook wijs
EricP

mét CE

maar dit werkte zo lekker overzichtelijk voor het geen wat ik moet doen

Dan kan ik alleen maar zeggen... Dan doe je het verkeerd! Ik snap dat je wel eens wat probeert, maar... heb je wel eens een boek 'C basics' ofzo gelezen? (zo nee: begin daar eens mee; het scheelt heel veel tijd als je ff kijkt hoe anderen het gedaan hebben en waarom.)

toen heb ik deze methode ontdekt, deed dus exact wat ik wilde.

Wat wil je dan eigenlijk?

Het lijkt erop dat je je eigen manier aan het uitvlooien bent om een stuk source in meerdere delen onder te brengen. Waarom ben je zelf het wiel aan het her-uitvinden? Er zijn al miljarden wielen. Kijk het kunstje gewoon ff af... Heus, het is geen rocket science. Als er nou 1 taal is die 'bouwen' goed overzichtelijk houdt zonder 'black magic', dan is het assembly. C komt erg dicht in de buurt.

EricP

mét CE

Daar had je je antwoord ook al... Enorme sourcefiles werkt niet.
Kleine files (waarbij 'klein' een rekbaar begrip is, erg afhankelijk van de context), stuk voor stuk door de compiler trekken en de linker maakt er wel wat moois van.

addFile.h:

c code:

#ifndef __ADDFILE_H__
#define __ADDFILE_H__

long int add(int a, int b);

#endif

addFile.c:

c code:

#include <addFile.h>

long int add(int a, int b)
{
  long int result=0;

  result=a+b;
  return(result);
}

multiplyFile.h:

c code:

#ifndef __MULTIPLYFILE_H__
#define __MULTIPLYFILE_H__

long int multiply(int a, int b);

#endif

multiplyFile.c:

c code:

long int multiply(int a, int b)
{
  long int result=0;

  result=a*b;

  return(result);
}

project.c:

c code:

#include <multiplyFile.h>
#include <addFile.h>

int main (int argc, char * argv[])
{

// Doe hier iets met de functies die je in de andere files gedefinieerd hebt.

}

Uiteraard ff opletten met de context van de variabelen. De files met C code 'zien' elkaar niet (wat fijn is, want zo heb je context en niemand heeft een probleem als je voor verschillende doelen dezelfde naam gebruikt (bijvoorbeeld verschillende programmeurs; binnen de context kan dat prima!).
De compiler ff vertellen waar de headerfiles staan.
De linker ff vertellen welke object files mee moeten. Met een beetje mazzel is make intelligent genoeg om zelf object files van source files te maken. In een IDE zeker!

Vervolgens doe je een build. De compiler gaat 3x aan het werk. Vervolgens komt de linker. En dan houd je je object code over. Dat zal voor jou wel Intel Hex format ofzo zijn.

Let wel: bovenstaande is een voorbeeld om uit te leggen hoe zoiets werkt. Het is niet bedoeld om syntactisch correct C te zijn en aan alles wat iedereen aan eigen standaards heeft te voldoen. Niks meer dan 'hoe douw ik functies in een eigen file' is het niet.

Het toverwoord heet "extern" ! Vb in file "main.c" definieer de variable int variabele var1=0;(=definitie)
In de andere file waar je ook deze variabele wilt gebruiken wordt deze variabele dan zo aangegeven : extern int var1;(=declaratie)
Opgelet, je hebt ook nog ".c files" en ".h files". In het algemeen wordt in de c-file alles "gedefinieerd", in de h-files wordt alles "gedeclareerd".
Maar, de ervaren programmeur gebruikt zo weinig mogelijk "globale variabelen". Deze vormen immers een probleem als je echt grote programmas gaat schrijven.

trix

Golden Member

eigenwijs = ook wijs

Trix, ik ben het eens dat het niet ok is wat je nu doet. Verklaarbaar is het wel. Jij hebt 1 hoofd-file (main.c ?) waarin je de rest include. Een include is niks anders dan het invoegen van een andere file. Je had dus net zo goed die 3 files copy-paste in main.c kunnen zetten, da's hetzelfde. Het klopt dus dat file2 wel de declares uit file1 ziet, maar andersom niet. Immers, file2 staat verder onderin het geheel. En in C is de scope zo dat een declare geldig is vanaf het punt waar het staat. Normaal bovenin, maar ergens halverwege kan ook.

Maar nu: even de boel herindelen zoals het hoort :7

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
bprosman

Golden Member

heb je wel eens een boek 'C basics' ofzo gelezen? (zo nee: begin daar eens mee; het scheelt heel veel tijd als je ff kijkt hoe anderen het gedaan hebben en waarom.)

Misschien heb je hier iets aan :
https://www.retrocomputing.nl/wp-content/uploads/Bookshelf/Programmere…
https://www.retrocomputing.nl/wp-content/uploads/Bookshelf/The%20C%20p…

De jongere generatie loopt veel te vaak zijn PIC achterna.
EricP

mét CE

Ik ken de boekjes war bprosman naar linked niet. Maar de titel doet vermoeden dat het voor TS in elk geval de moeite waard is om er een avondje in te steken.

En ja, iets afleren is moeilijker dan iets leren :) Wat dat betreft: succes! (en ja, we zijn allemaal wel eens op ons b*k gegaan met iets wat niet handig bleek. Vandaar het credo: beter goed gejat dan slecht zelf verzonnen! De volgende tegeltjes wijsheid: je moet vooral leren van de fouten van anderen. Je wordt niet oud genoeg om ze allemaal zelf te maken.)

Mijn insteek in deze zou zijn: opnieuw beginnen (met de indeling). En waarschijnlijk kun je 90% cut-pasten naar het juiste plekje en is het - als je eenmaal door hebt hoe het moet - een klusje van een uur.

[offtopic]Heel vroeger, toen ik nog helemaal geen grijze haren had, kwam ik binnen bij een groot bedrijf als knoppen bonker. Dat heette toen: junior software design engineer. Programmeren kon ik wel (diverse assemblies, Pascal, diverse basics), maar C kende ik nauwelijks. Dus van de baas een cursus C gekregen (waste of time. Programmeren kan ik wel, de taal ken ik niet!). Van een collega een crash course C gekregen (dat schoot meer op). Project van zo'n 150k lines. En dat moest ff opnieuw ingedeeld worden - in de loop der tijd veel dingen die niet handig (meer) waren. Uiteindelijk een dag lang een grote figuurlijke stofwolk bij ons in de kamer. Daarna bouwde het weer. En het deed ook nog hetzelfde. Dus uiteindelijk was het voor een 'novice' in C op een best behoorlijk stuk code ook wel goed te doen. En eh... internet om ff te vragen hoe het moet? Dat hadden we toen nog niet. Een BBS. En dan kon je (thuis!) inbellen met je razend snelle 14k4 modem. En dan snel zijn, want telefoontikken kosten geld.[/off topic]

big_fat_mama

Zie Paulinha_B

Voor wat het waard is, zo doe ik het:
* main.c bestaat bijna enkel uit includes
* de includes omvatten vooral functiedefinities, met elks hun eigen lokale variabelen
* toch heb ik nogal wat globale variabelen, die worden gedeclareerd in een aparte include ergens helemaal vooraan

hoe beter de vraag geschreven, zoveel te meer kans op goed antwoord
trix

Golden Member

voor iets wat eigenlijk heel simpel kan, vind ik het redelijk omslachtig en complex. zal wel zijn reden hebben, maar die zijn eigenlijk allemaal voor mij niet van toepassing.
gewoon een deel van de code op een appart tabblad.......meer vraag ik echt niet ;).

maar ja...waarom zou je simpel doen, als het ook moeilijk kan.

eigenwijs = ook wijs
bprosman

Golden Member

@EricP, link #2 ken je toch wel ? Het K&R boek waar het allemaal mee begon.

De jongere generatie loopt veel te vaak zijn PIC achterna.

de includes omvatten vooral functiedefinities, met elks hun eigen lokale variabelen

?? Snap ik niet. Lokale variabelen hebben niks te zoeken in een header file.
Die horen in de c/cpp en dan ook nog static;

Een header file is puur om interfaces te definieren.

O, wacht. Je voegt in je module nieuwe globale variabelen toe.
Dat kan, maar dat zijn dan geen locale variabelen.

trix

Golden Member

kijk, de termelogie die julie gebruiken maakt het moeilijk te bevatten, maar dat komt wel.
ik zal later eens proberen een tekeningetje maken om het wat overzichtelijker te krijgen.

eigenwijs = ook wijs
big_fat_mama

Zie Paulinha_B

Lokale variabelen hebben niks te zoeken in een header file.

Ik heb de term "header file" dan ook helemaal niet aangebracht. Lezen is een kunst.

voor iets wat eigenlijk heel simpel kan, vind ik het redelijk omslachtig en complex

Het hangt af van de totale omvang. Ooit werd mij aangeleerd dat een bestand broncode niet meer dan twee bladzijden zou mogen omvatten, zeg maar 100-120 regels tekst. Nog steeds probeer ik dat te handhaven, en #includes zijn daartoe in C een prima mechanisme. Maar als de complete broncode 400 of 500 regels omvat, dan is 1 enkel bestand wel zo overzichtelijk. Het leven is vol van compromissen, weet je wel...

hoe beter de vraag geschreven, zoveel te meer kans op goed antwoord
EricP

mét CE

voor iets wat eigenlijk heel simpel kan, vind ik het redelijk omslachtig en complex.

Eh... nou... eigenlijk is het heel simpel een eenvoudig...

zal wel zijn reden hebben, maar die zijn eigenlijk allemaal voor mij niet van toepassing.

Jij wilt met includes en sub files rommelen? Klinkt als erg omslachtig en complex :)

gewoon een deel van de code op een appart tabblad.......meer vraag ik echt niet ;).

Eh... Waarom zou je dat willen? Dat maakt het nodeloos ingewikkeld...

maar ja...waarom zou je simpel doen, als het ook moeilijk kan.

Nou, voorlopig doet de hele wereld het simpel en ben jij iets moeilijks aan het doen... Waarom zou je hetzelfde file in meerdere tabs willen hebben? Ik snap eigenlijk nog steeds je probleem niet...
Wat wellicht iets scheelt is dat toen ik begon, er geen tabs waren. Je had 1 editor. Met 1 file. Wilde je wat in een ander file? Close. Open. Edit. Save. De tabbed kwam gelukkig al vrij snel :) Maar eh... hetzelfde source file in meerdere tabs? Huh? Dan is je file gewoon te groot! (die hint kwam al een paar keer voorbij).
Wat wellicht ook scheelt is dat jij met een iets als IDE ingestapt bent. Dat is voor mij vaak heel veel nodeloze complexiteit. Soms werkt het handig. Meestal probeert het dingen 'makkelijk' te maken, waardoor je je helemaal het rambam zoekt als je nou net iets anders dan 'default' wilt.

@EricP, link #2 ken je toch wel ?

Ik druk me niet correct uit. Excuus. Uiteraard weet ik van het bestaan van het boek. En ja, ik heb het denk ik ook nog wel ergens. Ik 'ken' het niet 'by heart'. Dus als zodanig 'ken' ik het wel. Maar toch ook niet :) Je hebt gelijk. Zo zet ik mensen op het verkeerde been.

kijk, de termelogie die julie gebruiken maakt het moeilijk te bevatten

Elk werkgebied heeft z'n jargon. Soms heeft zelfs een afdeling z'n eigen uitdrukkingen (die een ander niks zeggen). Maar... de terminologie die ik tot op heden voorbij zie komen... is redelijk algemeen en gebruikelijk in 'programmeer land' - zelfs in andere talen. Als je nou een bepaald iets niet begrijpt... Wikipedia heeft best een hoop artikelen. En als je er met zelf zoeken niet uit komt, is er vast wel iemand alhier die het je in 2 woorden uit kan leggen.

Heb je nou al eens 5 minuten besteed aan ff naar het voorbeeldje kijken wat ik voor je getikt heb?

@bfm: Ik hecht niet zoveel waarde aan omvang. Wel aan zaken die bij elkaar horen bij elkaar houden. Soms is dat een file van 30 regels. En soms 3000.
Ik heb ooit eens een stel defines bij elkaar geharkt van een protocol specificatie waar men lekker los gegaan is. Het hoort echt bij elkaar. Toch een 2k aan entries om gewoon voor elk 'magic number' een define te hebben. Het schiet niet op om dat in 20 files te gaan splitsen - het voegt niks toe. Naamgeving is logisch (anders kun je het beter laten), dus als je wat zoekt, dan is een simpele search genoeg om daar te komen wat je zijn moet.
Ohja... Ik ben geen muis-gebruiker. Een editor moet met toetsen werken. En rete snel zijn - in elk geval zo snel dat-ie de auto repeat van toetsen bij houdt (niks zo irritant als PgDn ff vast houden en dan nog 3 seconden door scrollen als je los laat). Vele malen efficiënter dan gedoe met een muis...

Ik heb de term "header file" dan ook helemaal niet aangebracht. Lezen is een kunst.

Je hebt het wel over includes. Wil je nu zeggen dat je .c files include? Kan hoor, maar dat is volgens mij tamelijk ongebruikelijk.

Maar tegenwoordig is alles nogal aan het verschuiven. De hele boost library bestaat vrijwel alleen uit header files, met daarin cpp classes inclusief funktie implementatie.

En dat is vooral doordat het hele gebruik van header files nogal omslachtig is. Het bestaat ook alleen in C/C++ *. De meeste andere talen hebben veel elegantere oplossingen voor hum externe definities.

* Al wil ik niet zeggen dat ik alle programmeertalen ken.

trix

Golden Member

Heb je nou al eens 5 minuten besteed aan ff naar het voorbeeldje kijken wat ik voor je getikt heb?

heb ik, nog niet geheel duidelijk, maar komt wel. ik zal eerst een tekeningtje proberen te maken.

Op 27 maart 2021 20:39:17 schreef EricPIk snap eigenlijk nog steeds je probleem niet...

Dan is je file gewoon te groot! (die hint kwam al een paar keer voorbij).

ik heb een redelijk groot programma, die eigenlijk veel dingen na elkaar doet en eigenlijk niets tegelijk.
dan is het toch voor de duidelijkheid ideaal als je voor ieder ding een eigen tabblad hebt.

de file gewoon te groot ? er moeten natuurlijk wel dingen gedaan worden. ongetwijfeld zal door mijn gebrekkige programeer skils de code niet optimaal zijn wat grote betreft, maar hij word nooit de helft kleiner, past nog steeds niet op de eerder genoemde 1-2 A4-tjes.

eigenwijs = ook wijs

2 A4-tjes? Niks van aantrekken.

Komt volgens mij van een professor die nog nooit een echt programma heeft gemaakt. Alleen leuk voor op school in de les. :)

EricP

mét CE

heb ik, nog niet geheel duidelijk, maar komt wel. ik zal eerst een tekeningtje proberen te maken.

Ow. OK. Simpeler dan dit gaat het niet worden... Maar eh... snap je het samenspel tussen pre-processor, compiler en linker? Anders daar eens mee beginnen.

ik heb een redelijk groot programma, die eigenlijk veel dingen na elkaar doet en eigenlijk niets tegelijk.

Programma's die meerdere dingen tegelijk doen bestaan niet op single cores... Er is maar weinig software specifiek geschreven voor multi-core wat wel meerdere dingen tegelijk doet.

dan is het toch voor de duidelijkheid ideaal als je voor ieder ding een eigen tabblad hebt.

Waarom doe je dat dan niet? Het is je reeds meerdere keren aangegeven...

de file gewoon te groot ? er moeten natuurlijk wel dingen gedaan worden. ongetwijfeld zal door mijn gebrekkige programeer skils de code niet optimaal zijn wat grote betreft, maar hij word nooit de helft kleiner, past nog steeds niet op de eerder genoemde 1-2 A4-tjes.

Blijkbaar is het groter dan jij overziet. Dus te groot. Daarnaast: het is plain C. Weinig functions halen de 100 regels normaal gesproken.

Komt volgens mij van een professor die nog nooit een echt programma heeft gemaakt. Alleen leuk voor op school in de les.

Iemand die veel op een printer-terminal heeft gewerkt. Immers, een monitor was er toen nog niet. Alhoewel A4 daar weer niet bij past, dat was toen kettingpapier. Rare eenheid trouwens.
Aan de andere kant is er ook wel wat voor te zeggen om geen eindeloze files te hebben onder het motto 'pleur alles maar bij elkaar'. Wat logisch bij elkaar hoort bij elkaar. En als dat groot is, tsja, dan is dat zo.