Lexikala element mm
• Eftersom C är ett språk, har det ett alfabet och regler för
hur bokstäverna kan bilda ord och hur olika strukturella
enheter skiljs åt. Detta kallas språkets syntax.
• Kompilatorn kollar så att syntaxen i programmet är korrekt.
• För en människa så är en C-källkod en två-dimensionell
struktur, men för en kompilator är det en följd av bokstäver
som översätts till objektkod, som i sin tur blir översatt till
maskinkod för den aktuella maskinen.
• Efter att preprocessorn (som man kan tänka sig vara en del
av ”kompilatorn”) är klar, så samlas bokstäverna i
programmet till sk tokens.
15 September, 1999
1
Bokstäver och lexikala
element
• Exempel på bokstäver som kan användas i ett C-program är
följande:
små bokstäver
a b c...z
stora bokstäver
A B C...Z
siffror
0 1 2 3 4 5 6 7 8 9
övriga tecken
+ - * / = ( ) [ ] < > ’ ” ! @ #
$ % _ | \ . , ; : ?
”osynliga” tecken som mellanslag, nyradstecken och
tabulatortecken.
15 September, 1999
2
Syntax regler
• Vi ska använda ett grammatiksystem för att beskriva C:s
syntax (appendix B).
• Det kallas Backus-Naur Form (BNF) och är en kontext-fri
grammatik som utvecklades i början av 1960-talet av John
Backus och Peter Naur för att beskriva programmeringspråket ALGOL 60 (används numera inte alls).
• BNF räcker inte riktigt till att beskriva alla korrekta
strängar i C, men med vissa utökningar kan den användas.
• Grammatiken består bl.a. av produktioner (eller regler) som
producerar korrekta C strängar.
15 September, 1999
3
Symboler i vår grammatik
kursiv stil
Indikerar syntaktisk kategori
::=
”Ska skrivas som”-symbol
|
Eller
{}1
Välj en av posterna inom krullparenteserna
{}0+
Upprepa posten inom krullparenteserna 0 eller
fler gånger
{}1+
Upprepa posten inom krullparenteserna 1 eller
fler gånger
{}opt
Valfri post
andra poster är slutsymboler i språket
15 September, 1999
4
Exempel
• Kategorin letter_or_digit
letter_or_digit ::= letter | digit
letter ::= lowercase_letter | uppercase_letter
lowercase_letter ::= a | b | c |...| z
uppercase_letter ::= A | B | C |...| Z
digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
• Kategorin alphanumeric_string
alphanumeric_string ::= {letter_or_digit}0+
• Vi ser att t.ex. strängarna ”3”, ”ab777c” och null-strängen ””
är alla alfanumeriska strängar.
15 September, 1999
5
Kommentarer
• För att underlätta att läsa ett program och för att kunna
lägga in små förklaringar varför man gör som man gör, så
finns det i C möjlighet att lägga in kommentarer.
• En kommentar börjar med /* och slutar med */. Allt
däremellan ignoreras av kompilatorn.
• Kommentarer är viktiga och ska skrivas då man kodar sitt
program (första gången)
/* a comment */
/*****/
/*** another comment ***/
/*
* Yet another comment
*/
15 September, 1999
6
Nyckelord
• Vissa ord är reserverade och kan inte användas som t.ex.
variabelnamn
auto
do
goto
break
double if
sizeof void
case
else
int
static volatile
char
enum
long
struct while
const
extern register switch
continue float return
default for
short
signed unsigned
typedef
union
• Redan existerande funktionsnamn som t.ex. printf() bör
ej defineras om.
15 September, 1999
7
Identifierare
• En identifierare består av en sekvens av bokstäver, siffror
och/eller det speciella tecknet _ (eng. underscore).
• De flesta C system skiljer på små och stora bokstäver I
variabelnamn (case sensitive). Dvs. temp är inte samma
variabel som Temp eller tEmp osv.
identifier ::= {letter | underscore} 1 {letter | underscore |
digit}0+
underscore ::= _
• Exempel på identifierare är k, _id, iamanidentifier2, soami
men inte not#me, 101_south eller -plus.
15 September, 1999
8
Konstanter
• Det finns olika typer av konstanter i C. Heltalskonstanter
som t.ex. 0 och 17 och flyttalskonstanter som t.ex. 1.0 och
3.14159.
• Det finns dessutom teckenkonstanter som t.ex. ’a’, ’b’ eller
’+’. och som vi ska se i kapitel 3
• Vissa teckenkonstanter som ’\n’ (newline) har en speciell
mening. Trots att de skrivs med två tecken (\ och n) så
representerar de ett enda tecken i C.
decimal_integer ::= 0 | positive_decimal_integer
positive_decimal_integer ::= positive_digit {digit}0+
positive_digit ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
15 September, 1999
9
Konstanter
• Exempel på heltalskonstanter är 0, 77 och 1234567890.
• Men t.ex. 017 är inte samma sak som 17, därför att heltal
som börjar med 0 tolkas som skrivna med basen 8, dvs
oktala. Man kan också ange tal i hexadecimal form (bas 16),
t.ex. OxF3 eller OxA2.
• Negativa tal (t.ex. -33) räknas som konstanta uttryck.
15 September, 1999
10
Sträng konstanter
• En sekvens tecken omslutna av citationstecken räknas som
en strängkonstant. I kapitel 6 så kommer vi att se att
strängar lagras som en endimensionell vektor med tecken.
• Strängar med en bokstav är inte samma sak som tecken, dvs
”a” (sträng) är inte samma sak som ’a’ (tecken).
• Om man vill ha med ” i en sträng så måste den förekommas
av en \. Samma gäller om man vill ha med \ i en sträng, då
skrivs den som \\.
• Exempel på strängar är ”text”, ”” (tomma strängen), ” /*
not a comment” och ”\”hej\”” (”hej”).
• Däremot är t.ex. /* ”text” */ inte en sträng.
15 September, 1999
11
Operatorer
• De aritmetiska operatorerna är + (plus), - (minus),
* (multiplikation), / (division), % (modulus).
• Normalt så skriver man a + b (mellanslag för att öka
läsligheten) men det är tillåtet att skriva a+b.
• Vissa symboler har olika betydelse i olika sammanhang.
• T.ex. så har % olika betydelser i printf(”%d”, a);
och i a = b % 7;
• Parenteser, krullparenteser, komman och semikolon fungerar
som avdelare. T.ex. så kan parenteser bestämma prioriteten
vid beräkningar.
15 September, 1999
12
Prioritet och associvitet
• Det finns regler för vilken prioritet och associvitet olika
operatorer har.
• Eftersom uttryck inom parenteser utvärderas först kan
parenteser användas för att ändra eller klargöra i vilken
ordning operationer utförs.
1 + 2 * 3
1 + (2 * 3) (1 + 2) * 3
1 + 2 - 3 + 4 - 5 (((1 + 2) - 3) + 4) -5
15 September, 1999
13
Prioritet/Associvitet
Operatorer
()
Associvitet
++ (postfix)
+ (unary)
*
/
+
-
=
+=
-- (postfix)
– (unary) ++ (prefix)
%
vänster till höger
-- (prefix)
höger till vänster
vänster till höger
vänster till höger
-=
*=
15 September, 1999
/= etc
höger till vänster
14
Öka/Minska operatorer
• Vissa operationer är så vanliga att speciella operatorer har
skapats. Dessa operatorer är dessutom ofta implementerade
som endast en maskininstruktion => väldigt snabb
• ++ operatorn ökar värdet på en variabel med 1 och -operatorn minskar värdet med 1.
• Båda operatorerna kan användas som postfix eller prefix
operatorer.
• Om du använder postfix (t.ex. a++), så ökas värdet efter
satsen är utförd, medan ++a ökar värdet innan.
15 September, 1999
15
Exempel
1 #include <stdio.h>
2
3 int main() {
int a = 4, b = 4;
4
5
printf(”a: %d b: %d\n”, a++, ++b);
6
printf(”a: %d b: %d\n”, a, b);
7 }
Ger följande resultat:
a: 4 b: 5
a: 5 b: 5
15 September, 1999
16
Tilldelning
• Tilldelning är också en operator i C. = har låg prioritet och är
höger-vänster associativ.
b = 2;
c = 3;
a = b + c;
a = (b = 2) + (c = 3);
a = b = c = 0;
/* ovanligt men korrekt */
a = (b = (c = 0));
k = k + 2;
k += 2;
15 September, 1999
17
Tilldelnings-operatorer
• Som det nämnts tidigare så finns det många kombinationer
av tilldelning och beräkningsoperatorer.
=
+=
&=
-=
^=
*=
!=
/=
%=
>>=
<<=
int i=1, j=2, k=3, m=4;
Uttryck
Ekvivalent
Ekvivalent
Värde
i + = j + k
i += (j + k)
i = (i + (j + k))
6
j *= k = m + 5
j *= (k = (m + 5)) j = (j * (k = m + 5)))
15 September, 1999
18
18