f28pl1 programming languages lecture 8 programming in c - 3
TRANSCRIPT
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
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