/\P5C I6O
DeMorgans Law for boolean expressions
!(p||q) = (!p && !q) !(p&&q) = (!p||!q)
code for digitalWrite
#define LED 0 //... #define ON1 OFF 0 //... digitalWrite(LED,ON);
to read a string format specifier: %s no & in variable call
#define LINEMAX 8 char line [LINEMAX]; ex. scanf ("%s",line); testing → line = testing ex. scanf ("%4s",line); testing → line = test ex. scanf ("%s",line); two words → line = two careful as user may enter more text than can be stored in the string
when using PI ..
#define PI acos(-1.0) -> more accurate
code for digitalRead
#define SWITCH0 //... int switch_status; //... switch_status=digitalRead(SWITCH);
String Functions for normal arrays, we'd have to write size as a parameter in fncs, but for strings with the \0, this is not required
#include <string.h> strlen(s) returns length of s (not incl \0) strcopy(s,t) copies string t to string s
printf( "Error: "%s", "data.txt");
%s for imputing strings of characters, like file name
string constants ex. "sensor.txt" since its a string, the last element is assumed to be \0
' single quote=character constant " double quote = string constant -the null character has n ASCII integer eq of 0
void scanline(char str[ ], int size) this fnc reads a line from standard input and stops if \n, EOF, or index size-1 reached
'if' statement in while loop checks if value returned from getchar() = EOF or \n. if true, break. str[len++]=(char)c //c = retval, (char)=cast note: len++ here increments starting at 0 since ++ coming after means the value BEFORE incrementation is used.
ex. cargo.dat = weights of cargo. write program for total weight # unknown
(start) → [totWeight=0]→<more data in file?> →/input(file):weights/→[totWeight+=weights] for <more data in file?> use fscanf since it returns # data read from file code: while (fscanf(inputFile,"%lf",&itemWeight==1) fscanf will return -1 or 0(in case where data cant be read as double)
when var first declared, contains garbage value
--
scope of a variable defn
-block of code {} within which that variable is declared → defines which part of code has access to that var -variables are said to be *local* to that scope
global variable defn
-declared outside body of any fncs -has *global scope* accessible by all fncs in the program -hard to debug since all fncs use it
lifetime of local vars -timeframe in which memory is allocated
-have *automatic* storage class by default ie. memory automatically allocated to these cars when corresponding fnc is called and de-allocated when fnc call ends (return 0; ex. )
2. array indexing
-initially each index has garbage val -access indiv elements within an array by using indexes
benefits of using fncs
-prob decomp reflected in code -each fnc can be developed/tested indiv by diff ppl → efficient -easy to debug bc each fnc small part -abstraction makes program easy to read -reduces length of code
steps for solving function problems
1) algorithm 2) modular structure chart 3) write main code 4) write functions
good programming style
1) opening comments 2) clear variable names c) CAPITALIZED symbolic constants d) body of function made to look easy to see start/end e) blank lines btwn parts of code doing distinct tasks f) include units ex. m/s when prompting for input g) output (ex. range) labelled so user knows that it is
file IO and functions
1. define symbolic constant ex. INPUTFILE "runScores.txt" 2. declarations: FILE* inFile; (FILE* can be seen as "int" or "double") 3. inFile=fopen(INPUTFILE,"r"); 4. calling in fnc: use inFile, outFile instead of symbolic constants
4 steps for reading from a file
1. open file 2. verify file opened correctly 3. read files' data 4. close file
Writing data to a file (instead of screen) 4 steps
1. open file for writing 2. verify its opened correctly 3. write data to file 4. close file
double num = 1.0/10.0 + 1.0/10.0 + 1.0/10.0 cant do tests of equality (num ==0.3) for floating point values (double) because...
1/10 cant expressed as a floating point value in computer ∴ make boolean to see if num is 'close enough' → (fabs(num-0.3)<0.0001?) fabs = absolute value function
binary -> dec
1011₂ = 1(2³)+1(2²)+0(2¹)+1(2⁰) =13₁₀
dec -> binary
14 / 2 R0 7 / 2 R1 3 / 2 R1 1 / 2 R1 14₁₀ = 1110₂
"distance" btwn 2 arrays algorithm
2 loops outer one controlling which index in arrA to compare with inner loop actually calculating the distance inner - min distance of all indexes of arrB to one index in arrA outer - min of these mins
dec -> hexadec
250/16 R10 15/ 16 R15 =FA
hexadec -> dec
7A,50,E6 each pair - 1 btye ( 8 bits) data A - 10, B-11,C-12, D-13,E-14, F-15 3E = 3(16¹)+E(16⁰) =62₁₀
double analogRead( int analogChannelNumber) for when values vary widely, not just 0 or 1 discrete signals - digital analog signals - continuous values
CD player - accepts digital ata from CD drive and converts it to analog signal to be used by speakers
1. open file for writing
FILE*outputFile; before int main (void); outputFile=fopen("results.txt","w"); after variable declarations NOTE: if file alr contains data, it will be erased outputFile=fopen("results.txt","a") to 'append' and add new info after old
arrays cannot be target of an assignment
NOT ALLOWED: arr2=arr1 data2=data2+data1
arrays cant be return type of a fnc
NOT ALLOWED: int [] getValues(void);
2 switches , switch 0 and 1
S0 on → LED 0 on S1 on → LED 1 on both on → LED 2 on
rmbr to define
TRUE FALSE I/O CHANNELS SWITCH_ON SWITCH_OFF NUM_DISPLAYS SPACE_CHAR DELAY_TIME SIMULATOR -need to assign a variable to assign to status of switches for digitalRead, analogRead
What is necessary if you want to read a bunch of integers from a file?
That they're all diff lines, ie. seperated by white space ex. blank / new line If integers are separated by comma, need to call "%d," in fscanf =: the way you input data into file is important when you want to read it
some functions in standard C library and process of abstraction
abstraction: calls a fnc without understanding how it works ex. double sin(double angle); double pow (double base, double exponent); if a fnc doesnt take any parameters, it's 'void' ex. int main (void) returns an integer and takes no parameters
ex. of using nested loops for incremental coding problem: prompts user for size -> prints out * triangle ex. 3: * ** ***
algorithm: row#=#stars outer loop (row <= size?) → # rows inner loop (star <= row?) → # stars variables: row, star, size
character array
an array in which the indiv elements are character ( are type char) ex. char filename[4]={'t','e','s','t'};
for functions that return an array
array returned is a parameter, just write "return;" at the end -everytime array indexes need swapping, use variable 'temp'
strings : character array in which last array element is null character '\0' in order to identify last element of the array , similar to \n, a special character
benefit: don need to worry about size of array bc last element always a null character and can easily be found
post test loop - use when want loop to be ran at least once, ex. playing a game b4 quitting
boolean test comes after body of loop so loop executed at least once do{ /*body*/ } while (Boolean); notice the semicolon, not there in pretest loop
use early return and break statements to end functions early. ...
by checking (after variable declarations) if the inputs passed even make sense in terms of the function. for example, if length in writeNumber==0, it doesnt make sense to continue
how to convert a char from lower case to uppercase
c=c-'a'+'A' -'a' gives u index + 'A' gives u the uppercase number with that index
fscanf in reading a file doesnt always have to return 1 , can return data per line
can also make it return 1 var: while (fscanf( inFile,"%*d %lf %*lf ..",&next);
QUIZ: what will happen if SIZE=3 int index; int data []={4,1,8}; intdata2[SIZE]; for(index=SIZE;index>=0;index--) data2[SIZE-1-index]=data[index];
cant tell bc first run: data2[-1]=data[3] both indexes are out of the allowed range
double
capable of storing floating point values up to 15 dec places
"what is the value of this variable from the fnc "
check if it explicitly returns something. if it doesnt, the value is what it was when it was initialized RMBR a fnc can only return one value in main, rmbr to assign a variable to the return val of a fnc
lookup tables : use an array to display digits 0-9 so digits[0]=byte of data to display 0 replaces 'runtime computation' with simpler array 'indexing operation'
const int digits[ ] ={252, 96, 218, 242, 102, 185, 190, 224, 254 246}
ex. int countZerios(int arr[],int num); ... int numZeros=countZeros(data,count);
data and arr will both refer to same array even if diff names in actual and formal parameters
if want to copy input from keyboard to string, need to..
declare a temporary string for holding user-entered data. cant sprintf the data directly
#include <stdio.h>
declares printf scanf
Sleep( ) <Windows.h> (uppercase) takes parameters in milliseconds
define ONE_SECOND 1000
setupDAQ( int setupNum ), continueSuperLoop( void) used for init. and control of flow of program
digitalRead( int ChannelNumber ), digitalWrite( int ChannelNumber, int value ) used for I/O from/to digital devices digital = only reads binary vals 0,1 define TRUE 1 FALSE 0 at top of all programs
dont forget "print \n"
dont make the ++ or -- mistake when making a picture
implicit casting - taking dbl value 91.2 and assigning it to int value iData
double dData = 45.6; int iData; iData=dData * 2.0; in the end, iData=91 since its an int value got casted from dbl to int
3. array initialization
double data[]={5.2,3.8,7.2}; -not nessecary to specify size of array
code for max of 2 vals fnc - this fnc cant be used in isolation. 'return' statement terminates execution of fnc - only one return val possible
double maximum (double num1, double num2){ double maximum; if (num1>num2) maxVal=num1; else maxVal=num2; return maxVal; }
1. array declaration
double strain [10 000]; declares an array of 10 000 variables of type double data [0]=5.2; assigns 5.2 to 0th index of array
boolean exp
eval to true or false <=, >=, !=, ==, &&, ||, !(unary)
event vs counter controlled loops
event: executes until some event occurs (ex. user enters 1) -dont know how many times it will run → do while/while counter: know how many times it will run beforehand (ex. print all elements of an array) → for loops
character arrays (not string) -a 'char' variable limited to range [-128, 127] and when used in fncs, they represent printable characters
ex. char somecharacter=104; //no "" printf("%c,somecharacter); will print 'h' instead of memorizing chart, can just write 'a','z'
you CAN have an empty for loop
ex. int stringLength(char str[ ]){ int length=0; for(length=0;str[length]!='\0';length++){ } return length; }
you can put input from scanf or fscanf directly into array instead of declaring another var and making arr[index]=var
ex. while (count<MAX_ATHLETES && fscanf (inFile, "%d %lf %lf %lf", &ids[count], &scores[count][0], &scores [count][1], & scores [count][2])==4){
declaring: a character string can be initialized using string constants(no commas) or character constants(letters seperated by commas)
ex. char filename[ ]="sensor.txt"; the size (no need specified) is 11=10+1 for null character -note: no { }
sprintf - to write to a string sprintf (destString, formatString, var1...varN); purpose: to create a new string, destString, from a number of vars you already have the same string variable, destString, cant equal var 1....varN. ie. shouldnt be in both source & destination sprintf same as printf except for destString parameter at start
ex. int mynum; char filename[100]; //100 is more than enough, the unfilled spaces = garbage printf("Enter a number"); scanf("%d," &mynum); sprintf(filename, "myfile-%d",mynum); printf("file name is %s,filename); for input=30 → filename is myfile 30. the 2nd param in sprintf is the MSG youre writing to the string
to print out a string format specifier: %s no brackets [ ] in variable call
ex. printf("%10s \n %10i \n",label, pressure); 10 = field width
4. close file
fclose(inputFile); put at end of function or end of conditional block
4. close file writing
fclose(outputFile); at end of body of conditional block or function
ex. maximum fnc takes larger of 2 values -takes 2 'couble' vals as parameters and returns larger one
fnc prototype: >double maximum (double num1, double num2)< goes before int main (void) after hashtags
2. check if file opens correctly
fopen returns "NULL" if file fails after inputFile=fopen... write: if(inputFile !=NULL){
*for* loops - another way of writing while loops ex. for(index=SIZE;index>=0;index--)
for (init; boolExpr; post){body} init: initialization statement executed once per run of loop if Bool true→body→post if still true→again when false→exit loop
format specifiers: %d, %f for int %lf for double for scanf
for printf: %X.Yf with sometimes (+/-) before X Y= # decimal places (default = 6) X= width of field (default=just enough or default # decimal places) (-X) → aligned on left side; otherwise, aligned to right (spaces first) (+X) → sign of # always printed ex. a=4.52366 %-6.1f → 4 . 5 _ _ _ (. takes up one space) %6.2f → _ _ 4 . 5 2
code for looping through strings
for(i=0; str[i]!='\0'; i++)
infinite loops
forgetting to modify variable in loop so boolean always true or error in boolean exp.
3.write data to file
fprintf (filePointer, formatString, var1, ... varN); formatString → like "%lf" for double
you can put ret val of fnc (and array vals)` directly as variable in (f)scanf
fprintf(outFile, "%d "lf "lf \n",ids[row], rowMax(row,scores)) where rowMax is a fnc
3. read files data
fscanf: fscanf (filePointer, formaString, &var1, ... &varN) like scanf but with extra file pointer parameter fscanf returns an integer representing # of pieces of data read from file
operator precedence
highest to lowest !, ++, --, unary +, unary - / * % binary +, binary - <, >, <=, >= ==, != && || =,+=,*=.....
4. array processing
how to print to screen all elements of an array of given size: int data []= {3, 8, 2, 5, -1, 9}; int index=0; while (index<SIZE){ printf("%d",data[index]); index++; }
code for (nested) branching
if (Boolean) { /*true block*/ } else if { /*false block 1*/ } else { /*false block 2*/ } braces: used to define start/end, optional when block is single statement
code to set up daq
if (setupDAQ(setupNum)==TRUE){ //code } else printf("Error")
when passing parameters to a fnc , do not inc TYPE of parameter in the CALL incl it when DEFINING the fnc (header, prototype)
if parameter is an array, do not put []
2. check file opened correctly
if(outputFile != NULL) { ... } after opening the file
parameter passing mechanism
in main: 1.waterCosts=maximum(unitsUsed*WATER,MIN); ... function header: 2. double maximum(double num1,double num2) 1.when fnc is called →"actual parameters" 2.when fnc defined → "formal parameters"
how to check if file with name user entered already exists
in variable declarations, initialize file = NULL: FILE* file = NULL; -this way, if the file with the same name DNE, it will remain NULL as it will fail to open
in most simple nested loop, with count++, what is value of count when it endss?
inner loop runs * outer loop runs times
if output file cannot be opened,
input file should be closed
2D arrays
int data [3][2] → 3x2 array int data [] [3] = {{3,1,5},{4,0,2}};
copying an array - use for loop
int index; for (index=0;index<SIZE;index++) arr2[index]=arr1[index];
1. open file
int main (void) { FILE* inputFile; variables declared inputFile=fopen("data.txt","r"); inputFile is the variable pointing to the file we want to open "r" for read
<stdio.h> fncs for printing strings
int printf (const char* format,.. ) int fprintf (FILE*file, const char* format); int sprintf (char* str, const char* format, ...); char* = character array string const char * = unchanging array (message to be printed in this case )
to sum elements of row of 2D array to sum rows - increment cols to sum cols - increment rows
int rowNum, colNum; double sum; for(rowNum=0; rowNum<RSIZE;rowNum++){ sum=0.0; for (colNum=0;colNum<CSIZE;colNum++) { sum+=powerOutput[rowNum][colNum];} printf("% %,rowNum+1,sum); note: this doesnt sum entire array bc sum reset to 0 everytime loop runs
<stdio.h> fncs for reading stings
int scanf (const char* format, ...); int fscanf(FILE* file, const char* format, ... ); int sscanf (const char* str, const char* format,...);
explicit casting - does not convert sum from int -> dbl, converts VALUE of sum to dbl for purposes of this calc only
int sum; int count; double avg; sum=123 count=10 sum/count = 12 double avg so 12.0 which is WRONG => need casting : average = (double) sum/count
data type : int
int: stores ints from -2bill to 2 bill unsigned int: 0-4bill
use *trace tables* to keep track of value of variables and value of booleans controlling the loop
line # | variable | boolean(t/f) when reach false -> cont. with rest of code
char word [ ] = "mouse"; word[0] = 'h'; //single quotation marks word[5] = 's'; printString(word); whats printed?
no null character so fnc will continue to print until it encouters 0 (# for NUL) or until memory runs out ie. houseadjflkajdfkl
for workFunction, one time tasks, like initializations/declarations occur before/after superLoop
note for arrays: int name[100]={1} → 1 0 0 0 0 .... -can declare an array explicitly, or use a loop if the entries follow a pattern -an arrray occupies a 'continuous location' in memory. the size than an array occupies is (#elements)(size of element type)
% modulous (remainder) operator
only for (+) num/ (+) num ex. 12 % 3 = 0 5 % 12 = 5
function interface specification - t ensure fncs can work tgt; specifies ins/outs
possible in/out: -fr keyboard to screen -input parameters output return values
what is the output from the following code segment: int count = 0; do { printf("%d",count); count--; } while (count>0); printf(%d",count);
post test so loop executed at least once => 0 is printed printf outside the loop => -1 printed => 0 -1
pretest looping
pretest: boolean tested before loop; may never run while (Boolean) { /*body loop */ }
passing arrays as parameters
primitive type (int, char, double) → pass-by-value array → pass-by-address ∴array is not copied when its passed, the formal and actual parameters refer to the *same array*
when simulator number not defined,
prompt user for setupNum
temperature sensor
resistor whos resistance ( and ∴ voltage) varies with temperature (K) and voltage(V) is linearly α to temperature T=V (T₀/V₀) where T₀,V₀ is a reference point
photocell
resistor whos resistance changes depending on amnt of ambient light. ↑ light → resistance ↓
returns pseudo random number btwn 1 & max
return rand () % max +1 without the +1, it would be btwn 0 and (max-1)
array defn
seq of vars stored one after another in memory each with index starting at 0
flowchart shapes
start/end - circle decision (boolean) - diamond compute - rectangle input/output - parallelogram
identifier rules
starts with letter or _ all characters are letters, numbers, _ cant start with number
data type: char
stores a singlel character ex. char midInitial ='A'; need quotation marks
the role if \0 is to ...
terminate the string. if removed, it wouuld no longer be a valid C string and the contents of the array would be garbage. The results would be unpredictable after it prints whats given
if var is declared in a loop, what is the scope
the body of the loop, not accessible outside loop
char str [10] = " ";
this initializes all entries to NUL (0)
DAQ- data acquisition
to acquire data, ex. temp uses sensors, user input, devices -processes data in computer with C programs, excel -DAQ also has display so we can interface it to other devices
abstraction defn
to hide unimportant details and focus on inputs/outputs only
if turning LEDS on/off in a pattern , ex, one after another, only need to define LED 0, bc the other ones can be operated using a loop
to round numbers: int A = double B +0.5
how to order an array in ascending order
two 'for' loops nested for looping the array, one starting at i=0, one starting at j=i+1 if (num[i] > num[j]) → swich the nums by using placeholder variable i = num on left j= num on right
algorithms defn
unambiguous seq of steps for solving problem (flowchart)
Increment/Decrement operators
unary operators ++i; prefix i++; postfix used alone → no diff used with other operators: ++a = value AFTER inc/dec a++ = value BEFORE inc/dec
8 bit binary numbers range 0-255 since all LEDS on = 255 in binary
use 8 bit binary numbers to write to 7 segment displays "0b########"
to print + + + + (space in btwn)..
use modulous to print space every ___ characters. ex. count %2==0 will print - - - count%3==0 will print -- -- --
functions - put documentation at opening and before calling new function. fnc doc indicates purpose and intereface
used for modular programs ex. for nested loops, each loop can be its own function -use flowcharts to rep. relationship btwn modules in the program. ex [main]-[printRow] means that main will be called first and main will use printRow in it -main codes for outer loop (#rows) printRow codes for inner loop (#stars)
Analog Sensor Potentiometer (POTs) rotary potentiometers: compares angle on the two segment arm, determines angle btwn 2 objects connected through the POT
variable resistor acting like analog input device -resistor linearly changes with the angle, thus the voltage (output) changes as well. ---Then, angles can be later derived from measured voltage
controlLeds( ) with no if turns LED 0,1,2 on/off depending on state of switches
void controlLeds(void){ int switch0=digitalRead(SWITCH0); int switch1=digitalRead(SWITCH1); digitalWrite(LED0,switch0&&!switch1); } note that it checks status in the variable declaration and the param in digitalWrite has no ==ON or ==OFF
displayWrite( ) bc digitalWrite impractical for writing to 7 segment displays since we would need 8 fnc calls per display. 1 dec byte = 8 binary bits
void displayWrite(int data, int position); assumes we have several LEDs grouped tgt in a row data - val to be written to 7 segment display (binary, dec 0-255, hex) position- which LED display is writtten to Left → right = 7→0
returning data from fnc stored in ararays here, nVals copies val of SIZE from main (not shown)
void getValues(int data[],int nVals){ int index; int next; printf("enter %d int vals:",nVals); for (index=0;index<nVals;index++){ scanf("%d",&next); data [index]=next; } }
function prototype - beginning of code same as function header except prototype ends with ;
void printRow (int row); declares that fnc printRow takes parameter of type int and has no return value
printString(...) prints an arbitrary character string in sequence
void printString(char message[ ]){ int i; for(i=0; message[i]!='\0',i++){ printf("%c",message[i]); } } note: length not needed as a param
remember to append strings with \0 at end
void stringCopy (char dest[],char srs[]){ int length=0; for(length=0; src[length]!='\0',length++){ dest[length]=src[length];} dest[length]='\0'
sometimes superloop will call many fncs that take a long time. btwn such long calls, the daq may have alr shut down or the use quit. therefore, check continueSuperLoop( ) within body of loop and exit loop early if needed
void workFunction (void) { while (continueSuperLoop( )==TRUE){ long Fncs( ); *if (!continueSuperLoop( )){ break;}* OR if(continueSuperLoop( )){ longFnc2( )}; can use break or if statements
writeNumber function including length and offset, assuming there is no MAX_DISPLAYS value how to extract digit: digit = number%10 how to truncate number: number = number/10
void writeNumber( int number, int length, int offset){ const int DIGITS_TABLE[]=<252,...} const int SPACE_CHAR 0 int pos=offset; int digit=0; if (length==0){ return; } do{ digit=number%10; number=number/10; displayWrite(DIGITS_TABLE[digit],pos); pos++; } while (pos<offset+length &&number!=0); while (pos<offset+length){ displayWrite(SPACE_CHAR,pos); pos++; } }
scope of parameters is also the body of the corresponding fnc
when a variable/parameters is local - can only be accessed within scope and nowhere else in program
pass-by-value mechanism
when fnc is called, val of actual parameters copied and used to initialize corresponding formal parameters
short circuit evaluation
when part of boolean doesnt need to be evaluated to evaluate overall expression ex. a=0, x=1 (a!=0) && (x==1/a) 2nd condition DNE but since 1st is flase, whole thing is false
you can use system ("PAUSE") in functions other than main, just anytime u want to pause before continuing
whenever using 8 screen display for general purposes, include the >const int DIGITS_TABLE[10]<
any of the binary arithmetic operations can be assignment operator to make a 'compound assignment' operator
x=x[ ]y → x[ ]=y
when manipulating strings, define : char c=message[i] to shorten code and to modify c, not the original string
you can make char strings of diff lines: char text []=".../n" "...\n" ; note the multiple quotation marks.
MT1: int x = 3, y=2, z=0; if(x++<4){ if (++y>2) z=x+y printf("z is %d \n",z); printf("y is %d \n",y); } else printf("x is %d \n",x); what does it print
z is 7 y is 3 since the ++ are both executed after the booleans execute. the before/after only applies while inside the boolean
the scanf family of fncs use white space to seperate tokens, so not useful for reading expressions containing spaces
∴ use int getchar(void) which reads characters one by one until the end of an input, such as \n or End-Of-File (EOF) character -return type 'int; accounts for special EOF character, ∴ need to CAST value to (char) when appending to output. -spaces are counted as characters in getchar ( ) while (c != '\n' && c != EOF){ line[len++] = (char)c; c = getchar(); } line[len] = '\0';