470 likes | 603 Views
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 N D
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 intmust 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 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 a a[0] a[1] a[2] a[3]
Array access: expression name = ... exp1[exp2]...; • evaluate exp1 to lvalue • evaluate exp2 to integer • return *(exp1+exp2 * size for type) • i.e. contents of offset for exp2elements of type from address of 1st byte • exp1is usually the name of an array
Array access: assignment exp1[exp2] = expression; • evaluate exp1 to lvalue • evaluate exp2 to integer • evaluate expression to value • set exp1+exp2 * size for type to value • i.e. address of exp2thelement of type from address of 1st byte
Array name and address • 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 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 input intfscanf(FILE *,”format”,exp1,exp2...) • expi == lvalue • formatted output intfprintf(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 12 scalar 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) { inti; i = 0; while(i<n) { fscanf(fin,"%d",&(v[i])); i = i+1; } }
Example: scalar product printVec(int v[],int n) { inti; i = 0; while(i<n) { printf("%2d ",v[i]); i = i+1; } printf("\n"); }
Example: scalar product int scalar(int v0[],int v1[],int n) { int s; inti; s = 0; while(i<n) { s = s+v0[i]*v1[i]; i = i+1; } return s; }
Example: scalar product main(intargc,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; ... typeNnameN;}name; • namei== field • allocate: size of type1 + ... + size for typeN on stack • fields held left to right • NBname != &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; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 chris name age height
Structure access • in expression exp.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,intage,float height;} chris; chris.name = “Chris”; - byte 0 chris.height = 1.75”; - byte 0+4 == 4 chris.age = 27; - byte 0+4+8 == 12 name height age 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1.75 27 chris C h i s \0 r
Structure type definition structname {type1 name1; ... typeNnameN;}; • structnameis type of structure • defines type • does not allocate space structname1name2; • allocates stack space • associate name2with 1st byte of new sequence of type structname1
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 ch count #include <stdio.h> #include <stdlib.h> #define MAX 255 struct freq {intch;int count;}; struct freq f[MAX]; intfp; • fpis index for next free entry in f MAX-1 fp ‘1’ 1 ‘ ’ 17 ‘a’ 3 ‘0’ 4 ‘,’ 7 0 ‘v’ 2
Example: character count ch count incFreq(intch) { inti; 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 MAX-1 fp ‘1’ 1 ‘ ’ 17 i ‘a’ 3 ‘0’ 4 ‘,’ 7 0 ‘v’ 2 e.g. ch ==‘a’
Example: character count ch count incFreq(intch) { inti; 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 MAX-1 fp ‘1’ 1 ‘ ’ 17 i ‘a’ 4 ‘0’ 4 ‘,’ 7 0 ‘v’ 2 e.g. ch ==‘a’
Example: character count ch 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 MAX-1 fp ‘1’ 1 i ‘ ’ 17 ‘a’ 4 ‘0’ 4 ‘,’ 7 0 ‘v’ 2 e.g. ch ==‘p’
Example: character count ch 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 MAX-1 fp ‘p’ 1 ‘1’ 1 i ‘ ’ 17 ‘a’ 4 ‘0’ 4 ‘,’ 7 0 ‘v’ 2 e.g. ch ==‘p’
Example: character count showFreq() { inti; i = 0; while(i<fp) { printf("%c : %d\n",f[i].ch,f[i].count); i = i+1; } }
Example: character count main(intargc,char ** argv) { intch; 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 # : 3 i : 48 n : 36 c : 32 l : 8 u : 10 d : 8 e : 27 : 185 < : 4 s : 10 t : 31 o : 12 . : 9 h : 22 > : 2 : 54 b : 1 f : 35 M : 4 A : 4 X : 4 2 : 1 5 : 2 r : 23 q : 6 { : 9 ; : 29 } : 9 [ : 10 ] : 10 p : 14 F : 6 ( : 21 ) : 21 = : 19 0 : 5 w : 5 + : 4 1 : 7 " : 8 m : 2 a : 10 % : 4 \ : 3 , : 6 x : 2 : : 1 g : 6 * : 3 v : 3 I : 1 L : 3 E : 2 N : 1 U : 1 ' : 1 ! : 1 O : 1
Coercions (type)expression • evaluate expression to value • 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 = 0x01234567 c = (char *)(&x); - c now points at x’sspace printf(“%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;charb;charc;char d;} m; m.a = ‘a’; m.b = ‘b’; m.c = ‘c’; m.d = ‘d’; m ‘a’ ‘b’ ‘c’ ‘d’ 0 1 2 3
Structure coercion printf(“m: %x; &m: %x\n”,m,&m); m: 64636261; &m: 8049808 • 61 == ASCII ‘a’ in hex; 62 == ASCII ‘b’ in hex ... • structfields 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 charname [int]; • allocates space for intcharacters • 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> intslength(char s[]) { inti; i =0; while(s[i]!='\0') i = i+1; return i; }
Example: string length #main(intargc,char ** argv) { char * q; q = "how long is this string?"; printf("%s: %d characters\n",q,slength(q)); } $ slength how 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” • intscomp(char s0[],char s1[]) • s0 == s1 0 • s0 <= s1 -1 • s0 >= s1 1
Example: string comparison #include <stdio.h> intscomp(char s0[],char s1[]) { inti; 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 comparison main(intargc,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")); } $ scomp banana banana 0 banana banish -1 ban band -1 banquet banana 1 bank ban 1