Förstår inte vad som är "invalid expression" i C

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Förstår inte vad som är "invalid expression" i C

Inlägg av Magnus_K »

Hej på er,

Sitter med MikroC Pro for PIC som IDE och skriver i C.

Kan ni se något direkt fel med att jag först skriver ett macro (tror det heter så i alla fall) som ser ut så här:

Kod: Markera allt

#define HOURS timeCounter / 60;
Sen försöker jag tilldela en variabel (D1) följande värde:

Kod: Markera allt

D1 = HOURS / 10;
Raden ovan får då "Invalid Expression" vid kompileringen och det hjälper inte att sätta parentes runt heller.
Ser ni något direkt tok eller krävs det mer kod?
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av datajompa »

semikolonet i #definen
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av Magnus_K »

Perfekt, nu kompilerar det likt ett smäck! :tumupp:

Nu ser mina defines ut som nedan, har någon då lust att förklara när/varför man ska använda semikolon vid defines?
Kan säga att om inte datajompa hade sagt det här så hade det antagligen tagit mig hela natten att klura ut det här...

Kod: Markera allt

#define pushButton PORTB.B4;
#define rotarySwitch PORTC.B3;
#define secPulse PORTC.B7;
#define HOURS timeCounter / 60
#define MINUTES timeCounter
EDIT: Svarar mig själv med hjälp av IDE:ts hjälp (med andra ord jag aldrig skriva semikolon här...):
No semicolon (;) is needed to terminate a preprocessor directive. Any character found in the token sequence, including semicolons, will appear in a macro expansion.token_sequence terminates at the first non-backslashed new line encountered. Any sequence of whitespace, including comments in the token sequence, is replaced with a single-space character.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av datajompa »

#define stoppar bara in texten som den är, den struntar helt i C-syntaxen. Från början var preprocessorn i C helt separat från språket, och något som mer liknade sed eller awk. Detta är ett av de största problemen med C och C++, eftersom preprocessorn låter en göra en massa hack för att fixa problem, men som sedan kommer tillbaka och skjuter en i foten på oväntade sett eftersom det är en ren textbehandlare. Därför kan C-kompilatorn inte förstå vad som blev fel, vilket lätt kan förvandla små misstag till icke debuggbara obegripligheter! C++ lyckas kombinera detta med det troligen dummaste templatesystem som finns och tar idiotin till en helt annan nivå (det är det ++ betyder).

Jag kan inte på rak arm komma på något legitimt skäl att ha semikolon i slutet på #define-rader, men det finns säkert. Kanske för att hindra att man använder makrot som en del i ett expression? Man kan också simulera statements som inte är i C-syntax med makrona, svårt att säga att det skulle vara ett legitimt användningsområde dock! Det finns bland annat en implementation av ett funktionellt språk skriven helt i #defines, som alltså kompileras i huvudsak av preprocessorn. Det är ju dock snarare missbruk av C.

Det finns ett annat misstag du vill undvika, nämligen att glömma att omge makroparametrar med paranteser:

#define foo(x,y) x * y

är inte alls bra, utan

#define foo(x,y) ((x)*(y))

ska det vara. Annars kan du drabbas av väldigt svårbegripliga fel när du använder makrot på grund av operator precedence. Detta gäller bara om du vill ha ett makro som fungerar som en funktion skulle göra. Tänk på vad som händer i de båda fallen om man skriver int a = foo(1+2, 3); och förväntar sig att a blir 9.

Över huvud taget bör man vara misstänksam mot varje rad i ett C-program på grund av makron.

En klassikt hyss att smyga in i kollegans .h-fil:

#define return if (!(rand() % 256)) return 0; else return
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av Magnus_K »

Tack så hemskt mycket för förklaringen! Ska försöka komma ihåg att texten "bara byts ut" i programmet.
Borde jag även sätta timeCounter / 60 inom parentes så det blir som nedan?

Kod: Markera allt

#define HOURS (timeCounter / 60)
Är det samma prioriteringsregler inom programmering som i matte; dvs att man räknar parentes, *, /, +, -?
I så fall skulle ju även mitt fall nästan kunna trilla dit om jag struntar i parentesen. Hade jag använda tex addition för och skrivit #define HOURS timeCounter + 60 och sedan D1 = HOURS / 10;. Om samma prioriteringsregler används så blir ju värdet på D1 väldigt fel...
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av Mr Andersson »

> Är det samma prioriteringsregler inom programmering som i matte; dvs att man räknar parentes, *, /, +, -?

Jo alla programmeringspråk som jag har sett har de 5 operatörerna i den ordningen. Men det finns betydligt fler än 5. :)
Här har du en lista på alla operatörer i C och deras prioriteter.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45304
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av TomasL »

Å andra sidan är det väldigt osmart att ha funktionsakron.
I mitt tycke skall man helst undvika makron, och enbart använda dem om man vill ha villkorlig kompilering, samt i include-filer.

Exempelvis en include-fil skall man alltid börja med


#ifndef SOMEFILE.H
#define SOMEFILE.H
// diverse prototyper och annat jox
#endif

Behöver man en massa konstanter är det bättre att enumrera dem, eller typa dem som const, så kompilatorn har en chans att varna för fel.
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av bit96 »

TomasL:
Ett tips är att också lägga till inculdefilens namn efter #endif som en kommentar.

Och det gäller alla #if-#endif-kombinationer.
Det som står efter #if skrivs också som kommentar efter tillhörande #endif.

Det blir mycket lättare att läsa koden när man vet var #endif 'hör hemma'.

Kod: Markera allt

#ifndef SOMEFILE.H
#define SOMEFILE.H
// diverse prototyper och annat jox
#endif /* SOMEFILE.H */
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45304
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av TomasL »

Naturligtvis, detsamma gäller ju i koden efter långa klammrar
kodar-holger
EF Sponsor
Inlägg: 920
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av kodar-holger »

ett till tips är att använda

#pragma once

istället för #ifdef/#define som föreslaget tidigare.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av Magnus_K »

Mr Andersson skrev:> Är det samma prioriteringsregler inom programmering som i matte; dvs att man räknar parentes, *, /, +, -?

Jo alla programmeringspråk som jag har sett har de 5 operatörerna i den ordningen. Men det finns betydligt fler än 5. :)
Här har du en lista på alla operatörer i C och deras prioriteter.
Får tacka för länken Mr Andersson. Den tabellen åker raka vägen in i programmeringspärmen! :tumupp:

Angående ifndef etc så förstår jag lite av det där men aldrig gjort ett så komplext program så det behövts, tror jag.
Tackar ändå för informationen!
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45304
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av TomasL »

Du behöver det om du skriver ett program som har fler än en C-fil och funktioner/variabler skall vara tillgängliga i de andra C-filerna och vissa funktioner/variabler inte skall vara tillgängliga
Orsaken är att man bara kan ha en definition av en prototyp/variabel etc i ett program.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av datajompa »

Magnus_K skrev:Den tabellen åker raka vägen in i programmeringspärmen! :tumupp:
Kompetenta och erfarna programmerare löser det hela genom att helt enkelt sätta så många parenteser vi kan överallt.

Seriöst så finns det så många lurigheter att det faktiskt är bättre att göra det än att förlita sig på sin förmåga att komma ihåg listan, och det är ingen annan som kommer ihåg den så parenteserna behövs ändå för deras skull!

Jag är inte säker på att alla språk verkligen har exakt samma prioriteringar som C, men jag vet att flera språk har subtila skillnader vad gäller associativitet. Som exempel så är Pythons regler lite mer intuitiva än C, medan PHP som vanligt är helt idiotiskt.

Det klassiska exemplet i C är
if(a & b == TRUE)
vilket inte alls gör det man lätt förleds att tro, så
if((a&b) == TRUE)
är inte bara lättare att läsa utan dessutom troligen korrekt.

I Python, som ju är ett mycket vanligt språk idag som man måste ta hänsyn till, så utvärderas
if a<b<c:
inte på samma sätt som
if (a<b<c)
i C.

Och det finns fler exempel på liknande. Därför använder man istället onödigt mycket parenteser.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av Magnus_K »

@TomasL:
Tror inte jag har gjort något program än med fler c-filer än en men jag ska försöka ha det här i minnet.

@datajompa:
Point taken :tumupp: Parenteser, parenteser, parenteser :)

När vi ändå diskuterat om hur bra det är med makron... Hur kan jag skriva ett som "skapar ett fiktivt portregister"?

Vad jag menar med det är jag skulle vilja slå på/av specifika I/O's med andast ett makro men då dom inte tillhör samma portregister så kan jag tex inte skriva "LATA = 0" utan skulle vilja göra något i stil med #define GRIDS PORTA.B5, PORTB.B4, PORTC.B0.
Måste jag göra en array av det eller räcker det att separera med kolon eller semikolon?

Kanske saknar viktig information för att ni ska kunna svara på frågan men säg då gärna till.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1339
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Förstår inte vad som är "invalid expression" i C

Inlägg av baron3d »

Det är bra att dela upp projektet i flera filer. Det är opraktiskt när filer passerar 4000 rader.
När du börjar se att radnumret passerar 2000 så är det dags att dela. Där det går bör man inte låta filerna få mer rader än 1000.
Vilket innebär att du får ett par hundra filer eller så. :humm: :shock:

I mitt jobb så hände det nyligen, ops, 4000 rader. Delning var oundvikligt, det fick bli 2500 och 1500. Chefen blev lättad.
Skriv svar