47
F28PL1 Programming Languages Lecture 8 Programming in C - 3

F28PL1 Programming Languages Lecture 8 Programming in C - 3

Embed Size (px)

Citation preview

F28PL1 Programming Languages

Lecture 8 Programming in C - 3

Arrays

• finite sequence of elements of same type• elements accessed by an integer index• declaration:type name [int];• allocate int * size for type on stack• elements numbered from 0 to int-1• e.g. int a[6]; - allocates 6 * 4 == 24 bytes• e.g. char b[6];- allocates 6 * 1 == 6 bytes• e.g. double c[6]; - allocates 6 * 8 == 48 bytes

Array size

• in type name[int];• size int must be a constant• cannot:– decide size at run-time– then declare correct size array

• must declare “too big” array• during use must check not exceeding amount

allocated

Array access

• e.g. int a[4];

• a[0] == a+0*4 a• a[1] == a+1*4 a+4• a[2] == a+2*4 a+8• a[3] == a+3*4 a+12

a

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

a[0] a[1] a[2] a[3]

Array access: expression

name = ... exp1[exp2]...;

1. evaluate exp1 to lvalue

2. evaluate exp2 to integer

3. return *(exp1+exp2 * size for type)– i.e. contents of offset for exp2 elements of type from

address of 1st byte

• exp1 is usually the name of an array

Array access: assignment

exp1[exp2] = expression;

1. evaluate exp1 to lvalue

2. evaluate exp2 to integer

3. evaluate expression to value4. set exp1+exp2 * size for type to value– i.e. address of exp2th element of type from address of 1st

byte

• name is alias for address of 1st byte• name is not a variable• i.e name == &name

int a[3];printf(“a: %x; &a: %x/n”,a,&a);

a: 80497fc; &a: 80497fc

Array name and address

a’s value a’s address

Array bounds

• no array bound checking• if try to access array outside bounds– may get weird values from bytes outside array

• or– program may crash

Array type for formal parameter

type name[] • size not specified

• same as: type * name

Constant

#define name text– pre-processor replaces all occurrences of name in

program with text– before compilation

• use to define constants once at start of program

e.g. #define SIZE 127

Formatted file I/O

• formatted inputint fscanf(FILE *,”format”,exp1,exp2...)– expi == lvalue

• formatted outputint fprintf(FILE *,”format”,exp1,exp2...)– expi == rvalue

Formatted numbers

• can precede format character with width/precision info

e.g. %3d – integer– at least 3 characters wide

• e.g. %4.2f – double– at least 4 chars wide – 2 chars after decimal point

Example: scalar product

• calculate V0[0]*V1[0]+...+V0[N-1]*V1[N-1]

$ scalar vecs.txt 1 2 3 4 5 6 7 8 9 10 11 12scalar product: 217

Example: scalar product

• file contains:– length of vector - N– 1st vector – V0[0]...V0[N-1]

– 2nd vector – V1[0]...V1[N-1]

• functions to:– read vector– print vector– calculate scalar product

Example: scalar product#include <stdio.h>#include <stdlib.h>

#define MAX 100

getVec(FILE * fin,int v[],int n){ int i; i = 0; while(i<n) { fscanf(fin,"%d",&(v[i])); i = i+1; }}

Example: scalar productprintVec(int v[],int n){ int i; i = 0; while(i<n) { printf("%2d ",v[i]); i = i+1; } printf("\n");}

Example: scalar productint scalar(int v0[],int v1[],int n){ int s; int i; s = 0; i=0; while(i<n) { s = s+v0[i]*v1[i]; i = i+1; } return s;}

Example: scalar productmain(int argc,char ** argv){ FILE * fin; int v0[MAX],v1[MAX]; int n; if(argc!=2) { printf("scalar: wrong number of arguments\n"); exit(0); } if((fin=fopen(argv[1],"r"))==NULL) { printf("scalar: can't open %s\n",argv[1]); exit(0); }

Example: scalar product fscanf(fin,"%d",&n); if(n>=MAX) { printf("scalar: %d vector bigger than %d\n",n,MAX); fclose(fin); exit(0); } getVec(fin,v0,n); printVec(v0,n); getVec(fin,v1,n); printVec(v1,n); fclose(fin); printf("scalar product: %d\n",scalar(v0,v1,n));}

Structures

• finite sequence of elements of potentially different types

• each element identified by a field name• like a Java object with no methods

Structures

struct {type1 name1; ... typeN nameN;} name;

• namei == field

• allocate: size of type1 + ... + size for typeN on stack • fields held left to right• NB name != &name– &name is address of 1st byte in sequence– name is value of byte sequence , depending on type context

Structure declaration: example

struct {char * name, float height,int age;} chris;

chris

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

name ageheight

Structure access

• in expressionexp.namei

*(&exp + size for type1 ...+ size for typei-1)

• i.e. contents of offset of preceding fields from start of structure

Structure access: example

struct {char * name,int age,float height;} chris;

chris.name = “Chris”; - byte 0chris.height = 1.75; - byte 0+4 == 4chris.age = 27; - byte 0+4+8 == 12

chris

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

name ageheight

1.75 27

C h r i s \0

Structure type definition

struct name {type1 name1; ... typeN nameN;}; • struct name is type of structure • defines type• does not allocate space

struct name1 name2;• allocates stack space• associate name2 with 1st byte of new sequence of

type struct name1

Example: character count

• count how often each distinct character appears in a file

• array of struct to hold character and count• for each character in file– if character already has struct in array then increment

count– if unknown character then add to array with count 1

Example: character count#include <stdio.h>#include <stdlib.h>

#define MAX 255

struct freq {int ch;int count;};

struct freq f[MAX];int fp;

• fp is index for next free entry in f

ch count

0

MAX-1

fp

‘v’ 2‘,’ 7‘0’ 4‘a’ 3‘ ’ 17‘1’ 1

Example: character countincFreq(int ch){ int i; i=0; while(i<fp) if(f[i].ch==ch) { f[i].count = f[i].count+1; return; } else i = i+1;

• search f for entry for ch• if found, increment count

and return

ch count

0

MAX-1

fp

‘v’ 2‘,’ 7‘0’ 4‘a’ 3‘ ’ 17‘1’ 1

e.g. ch ==‘a’

i

Example: character countincFreq(int ch){ int i; i=0; while(i<fp) if(f[i].ch==ch) { f[i].count = f[i].count+1; return; } else i = i+1;

• search f for entry for ch• if found, increment count

and return

ch count

0

MAX-1

fp

‘v’ 2‘,’ 7‘0’ 4‘a’ 4‘ ’ 17‘1’ 1

i

e.g. ch ==‘a’

Example: character count

if(fp==MAX) { printf("more than %d different characters\n",MAX); exit(0); } f[fp].ch = ch; f[fp].count = 1; fp = fp+1;}

• if ch not found– check for free entry in f– add ch /1 to next free entry– increment fp

ch count

0

MAX-1

fp

‘v’ 2‘,’ 7‘0’ 4‘a’ 4‘ ’ 17‘1’ 1

i

e.g. ch ==‘p’

Example: character count

if(fp==MAX) { printf("more than %d different characters\n",MAX); exit(0); } f[fp].ch = ch; f[fp].count = 1; fp = fp+1;}

• if ch not found– check for free entry in f– add ch /1 to next free entry– increment fp

ch count

0

MAX-1

fp

‘v’ 2‘,’ 7‘0’ 4‘a’ 4‘ ’ 17‘1’ 1

i

e.g. ch ==‘p’

‘p’ 1

Example: character countshowFreq(){ int i; i = 0; while(i<fp) { printf("%c : %d\n",f[i].ch,f[i].count); i = i+1; }}

Example: character countmain(int argc,char ** argv){ int ch; FILE * fin; if((fin=fopen(argv[1],"r"))==NULL) { printf("can't open %s\n",argv[1]); exit(0); } fp = 0; ch = getc(fin); while(ch!=EOF) { incFreq(ch); ch = getc(fin); } fclose(fin); showFreq();}

Example: character count$ freq freq.c# : 3i : 48n : 36c : 32l : 8u : 10d : 8e : 27 : 185< : 4s : 10t : 31o : 12. : 9

h : 22> : 2

: 54b : 1f : 35M : 4A : 4X : 42 : 15 : 2r : 23q : 6{ : 9; : 29

} : 9[ : 10] : 10p : 14F : 6( : 21) : 21= : 190 : 5w : 5+ : 41 : 7" : 8m : 2a : 10

% : 4\ : 3, : 6x : 2: : 1g : 6* : 3v : 3I : 1L : 3E : 2N : 1U : 1' : 1! : 1O : 1

Coercions

(type)expression1. evaluate expression to value 2. now treat value as if type• does not physically transform expression• as if overlaid template for type on value• also called cast

Coercions

• e.g. integer (4 bytes) as array of char (1 byte)int x;char * c;x = 0x01234567c = (char *)(&x); - c now points at x’s spaceprintf(“%x %x %x %x\n”, c[0],c[1],c[2],c[3]);

67 45 23 01

Coercions

• x is 4 hex bytes 01 23 45 67– stored from most significant to least significant

• &x returns address of 1st byte of int• (* char) coerces address of 1st byte of int to address of 1st byte of array of char– c[0] is 1st byte of x == 67– c[1] is 2nd byte of x == 45 etc

Structure coercion

struct {char a;char b;char c;char d;} m;m.a = ‘a’; m.b = ‘b’; m.c = ‘c’; m.d = ‘d’;

m

0 1 2 3

‘a’ ‘b’ ‘c’ ‘d’

Structure coercion

printf(“m: %x; &m: %x\n”,m,&m); m: 64636261; &m: 8049808• 61 == ASCII ‘a’ in hex; 62 == ASCII ‘b’ in hex ...• struct fields held left to right• but printing struct as hex:– coerces to int – accesses bytes right to left as most to least significant

String

• array of char• last char is ‘\0’• no length information

“characters”• string constant• allocates space for characters ending with ‘\0’• sets each byte to each character• returns address of first character

String variables

char name [int];• allocates space for int characters• cannot assign string constant to name– must copy character by character

char * name;• allocates space for pointer to characters• can assign string constant to name– changes pointer

• otherwise, must allocate space for characters...

Example: string length#include <stdio.h>

int slength(char s[]){ int i; i =0; while(s[i]!='\0') i = i+1; return i;}

Example: string length#main(int argc,char ** argv){ char * q; q = "how long is this string?"; printf("%s: %d characters\n",q,slength(q));}

$ slengthhow long is this string?: 24 characters

Example: string comparison

s0==s1

– same length: n– 0 <= i <= n-1: s0[i]==s1[i]

• e.g. “banana” == “banana”s0<s1

– 0<= i <j: s1[i]==s2[i]

– s0[j]<s1[j]

• e.g. “banana” < “banish”• e.g. “ban” < “band”

Example: string comparison

s0>s1

– 0<= i < j: s1[i]==s2[i]

– s0[j]>s1[j]

• e.g. “banquet” > “banana”• e.g. “bank” > “ban”• int scomp(char s0[],char s1[])– s0 == s1 0– s0 <= s1 -1– s0 >= s1 1

Example: string comparison#include <stdio.h>

int scomp(char s0[],char s1[]){ int i; i = 0; while(s0[i]==s1[i]) { if(s0[i]=='\0') return 0; i = i+1; } if(s0[i]=='\0' || (s0[i]<s1[i])) return -1; return 1;}

Example: string comparisonmain(int argc,char ** argv){ printf("banana banana %d\n",scomp("banana","banana")); printf("banana banish %d\n",scomp("banana","banish")); printf("ban band %d\n",scomp("ban","band")); printf("banquet banana %d\n",scomp("banquet","banana")); printf("bank ban %d\n",scomp("bank","ban"));}

$ scompbanana banana 0banana banish -1ban band -1banquet banana 1bank ban 1