f28hs2 hardware-software interface lecture 3 programming in c - 3
DESCRIPTION
Character values characters have integer values ASCII (American Standard Code for Information Interchange) representation is international standard characters in usual sequences have sequential values charinthexcharinthexcharinthex ‘0’4830‘A’6541‘a’9761 ‘1’4931‘B’6642‘b’ ‘9’5739‘Z’905A‘z’1227ATRANSCRIPT
F28HS2 Hardware-Software Interface
Lecture 3 Programming in C - 3
Keyboard/display char I/O
• for keyboard inputint getchar() getc(stdin)
• for screen output int putchar(int) putc(int,stdout)
Character values
• characters have integer values• ASCII (American Standard Code for Information
Interchange) representation is international standard
• characters in usual sequences have sequential values
char int hex char int hex char int hex
‘0’ 48 30 ‘A’ 65 41 ‘a’ 97 61
‘1’ 49 31 ‘B’ 66 42 ‘b’ 98 62
... ... ...
‘9’ 57 39 ‘Z’ 90 5A ‘z’ 122 7A
Character values
• very useful for character processinge.g. char ch is:• lower case if: ‘a’ <= ch && ch <= ‘z’• upper case if: ‘A’ <= ch && ch <= ‘Z’• digit if: ‘0’ <= ch && ch <= ‘9’• if ch is a digit then it represents value: ch-’0’• e.g. ‘7’-’0’ 55-48 7
Example: input binary number
input value
11011 0
1011 2*0+1 1 – 1011 2*1+1 3 – 1111 2*3+0 6 – 1101 2*6+1 13 – 1101
2*13+1 27 – 11011
•initial value is 0•for each binary digit• multiply value by 2• add value of binary digit
Example: input binary number
• function to convert text from file to value• parameters for:– file– next character
• input each character from file into a non-local variable– pass address of character variable– access character indirect on address
Example: input binary numberbinary.c
#include <stdio.h>#include <stdlib.h>
int getBinary(FILE * fin,int * ch){ int val; val = 0; while (*ch=='0' || *ch=='1') { val = 2*val+(*ch)-'0'; *ch = getc(fin); } return val;}
Example: input binary numbermain(int argc,char ** argv){ FILE * fin; int ch; int val;
if(argc!=2) { printf("getBinary: wrong number of arguments\n"); exit(0); } if((fin=fopen(argv[1],"r"))==NULL) { printf("getBinary: can't open %s\n",argv[1]); exit(0); }
Example: input binary number ch = getc(fin); while(1) { while(ch!='0' && ch !='1' && ch!=EOF) – skip to binary digit ch=getc(fin); if(ch==EOF) break; val = getBinary(fin,&ch); printf("%d\n",val); } fclose(fin);}
Example: input binary number
bdata.txt011011100101...1111
$ binary bdata.txt012345...15
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
a0 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 lvalue2. evaluate exp2 to integer3. 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 lvalue2. evaluate exp2 to integer3. 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
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));}
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
Structures
• finite sequence of elements of potentially different types
• each element identified by a field name• like a Java object with no methods
Structuresstruct {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: examplestruct {char * name, float height,int age;} chris;
chris0 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: examplestruct {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
chris0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15name 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’ 1i
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’ 1i
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