Step 1: Work An Example Yourself: C Programming-Fundamentals 1-4 Coursera
Step 1: Work An Example Yourself: C Programming-Fundamentals 1-4 Coursera
Step 1: Work An Example Yourself: C Programming-Fundamentals 1-4 Coursera
The above figure shows how you should approach designing your algorithm.
If you get stuck at this step, it typically means one of two things. The first case is that the problem
is ill-specified—it is not clear what you are supposed to do.
The second case where Step 1 is difficult is when you lack domain knowledge
Eg of Algorithm
Variable
An identifier is the formal programming term for a word that can be used to name something
An assignment statement starts with an lvalue on the left. An lvalue (pronounced “el-value”)
must be something that “names a box”
The rvalue (pronounced “are-value”) must be an expression whose value shall be placed in the
box.
Functions
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
A return statement starts with the keyword return, which is then followed by an expression. The
effect of this statement is to say what the "answer" is for the current function, leaving its
computation and returning to the code that called it.
we must first group together the variables belonging to one particular function into a larger box,
labeled with the function’s name, which is called a frame (or stack frame, since they are located
on the call stack).
Scope of a variable
To determine which variable a name refers to, we must first determine which variable(s) with that
name are in scope at the reference
If multiple variables are in scope, we select the one whose declaration is in the innermost
enclosing block. That is, if you went backwards out of blocks, through open curly braces, the
variable which would go out of scope first is the one to use.
Another type of special information we can include in the string is escape sequences.
\n newline \t tab
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
IF ELSE
switch/case
When the execution arrow reaches the break keyword, it jumps to the close curly brace which
ends the switch statement.
. When the execution arrow passes from one case into the next like this, it is called “falling
through” into the next case.
Shorthand
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
Another possible shorthand is to omit the curly braces around single statement blocks of code in
certain cases. it is highly inadvisable to write code this way.
While Loops
do/while Loops
By contrast, a do-while loop is guaranteed to execute its body at least once because it executes
the loop body before ever checking the condition.
For Loops
it does not introduce any new behavior, but instead provides a more convenient syntax for a
common programming idiom.
There are two possible behaviors that a programmer might want when leaving the loop
body early.
break;
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
Continue
Executing the continue statement jumps to the top of the innermost enclosing loop
In the case of a for loop, the “increment statement” in the for loop is executed immediately before
the jump.
continue;
Hardware Representations
Binary Numbers
Hexadecimal
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
DATA TYPES
In particular,
sizes depend on the hardware and the compiler—the program that turns your code into
instructions the computer can actually execute
ASCII
Examples of chars and ints. At first glance, c and x appear identical since they both have the
binary value 65. However, they differ in both size (c has only 8 bits whereas x has 32) and
interpretation (c’s value is interpreted using ASCII encoding whereas x’s value is interpreted as
an integer). Similarly, y and z are identical in hardware but have differing interpretations because
y is unsigned and z is not.
ints are actually represented using an encoding called two’s complement, in which half of the
2^{32} possible bit patterns are used to express negative numbers and the other half to express
positive one
Another pair of qualifiers you may run into are short and long which decrease or increase the
total number of bits dedicated a particular variable, respectively.s.
Float
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
One way we could (but often do not) choose to represent real numbers is fixed point. We could
take 32 bits, and interpret them as having the binary point in the middle. That is, the most
significant 16 bits would be the “integer” part, and the least 16 bits would be the “fractional” part.
Precision
. A double takes up twice as much space as a float. This may not matter for a single variable, but
some programs declare thousands or even millions of variables at a time. If these variables do
not require the precision of a double, choosing a float can make your code run faster and use
less memory with no loss of correctness.
The types of constants can be modified by applying a letter suffix if needed (U for unsigned, L for
long, and f for float): 3.14f is a constant with type float, and 999999999999L is a constant with
type long int.
When the two operands have different types, the compiler attempts to add a type
conversion (sometimes called a type promotion) to make the types the same.
The third common way that the bit representation can be changed during an automatic
conversion happens when a longer integer type is converted to a shorter integer type. Here, the
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
bit pattern is truncated to fit—the most significant bits are thrown away, and only the least
significant bits are retained.
We will note that while understanding when to cast is important, understanding that you should
generally not cast is even more important—sprinkling casts into your code to make errors go
away indicates that you are not actually fixing your code, but rather hiding the problems with it.
Explicitly requested conversion is called casting and is written in the code by placing the desired
type in parentheses before the expression whose value should be converted. For
example, (double)x evaluates x (by reading the value in its box), then converts it to a double.
A string is a sequence of characters that ends with a special character called the null terminator,
which can be written with the character literal '\0' (pronounced “backslash zero”) that signals the
end of the string.
Image
While there are many ways to represent a color as a number, the most common is RGB
Typically, this encoding is done with each component being represented on a scale from 0 to
255. The RGB values for the color red are: R=255, G=0, B=0.
You may have noticed that computers typically have a variety of image formats, such as JPG,
BMP, PNG, TIFF, and many others. Each of these encodes the image numerically,
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
Struct declarations do not go inside functions; they live in the global scope of the program, next
to function declarations and definitions.
Ending the tag in “_t” is a convention that makes it easier to recognize the name as identifying a
type throughout your code.
TYPE DEF
Padding ===========
struct node{
int I;
double j;
char array[12];
int I = 1 double =8
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
double j = 1 double=8
NOTE(Padding concept):
If 2 data type are same they can occupy the same allocated block
UNIONS
union var_name{
int I;
char[20];
};
It takes the memory it takes to store the largest element in this case 20bytes for char[20] and al
elements share that
If char[20] is full and you try to store int I it will cause seg fault
Enumerated Types
enum threat_level_t {
LOW,
GUARDED,
ELEVATED,
HIGH,
SEVERE
};
The convention for indicating that a name denotes a constant is to write the name in all
uppercase. However, variables of the enumerated type can be created, and assigned to
normally.
eg
switch(threat) {
case LOW:
printf("Green/Low.\n");
break;
case GUARDED:
printf("Blue/Guarded.\n");
break;
case ELEVATED:
printf("Yellow/Elevated.\n");
break;
case HIGH:
printf("Orange/High.\n");
break;
case SEVERE:
printf("Red/Severe.\n");
break;
STEP 3
Generalizing Values
Generalizing Repetitions
Generalizing Conditional Behavior
Function declaration
1. we may need to do in writing down the function declaration is to figure out its
parameter types and return type.
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
2. replace the generalized algorithm from Step 3, written as comments ten write code at ls
of comment
In C, there are two forms of comments: // comments to the end of the line, and /*...*/ makes
everything between the slash-star and the star-slash into a comment.
Repetition
If your algorithm calls for you to "stop repeating things" or "stop counting" you will want to
translate that idea into a break statement. Meanwhile, if your algorithm calls for you to skip the
rest of the steps in the current repetition, and go back the start of the loop, that translates into
a continue statement.
Decision Making
Whenever your algorithm calls for you to make a decision, that will translate into
either if/else or switch/case.
Math
Names
Altering Values
manipulates the values that it works with, these translate into assignment statements
return statement
Complicated Steps
something that you cannot translate directly into a few lines of code—you should call another
function
do not worry about defining the function yet. Instead, just call the function you will write in the
future
Top-down design
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
The process of taking large, complex pieces, and separating them out into their own function
Whenever you have a chance to pull a well-defined logical piece of your program out into its own
function, you should consider this an opportunity, not a burden.
Compilation Process
For one, if the programmer ever needs to change the constant, only the macro definition must be
changed, rather than all of the places where the constant is used.
The standard header file limits.h contains constants specifically for portability. These constants
describe the maximum and minimum value of various types on the current platform.
Macros
#define SQUARE(x) x * x
text z-y, resulting in z-y * z-y. Note that this will compute z- (y*z) -y,
stdint.h defines types such as int32_t (which is guaranteed to be a 32-bit signed int on any
platform), or uint64_t (which is always a 64-bit unsigned int).
NOTE
Compiler errors can be a source of confusion and frustration for novice programmers. One key
rule in dealing with them is to try to fix them in order,
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
If parts of an error message are completely unfamiliar, try to ignore them and see if the rest of
the error message(s) make sense
Compilng
Once the compiler has parsed your program, it type-checks the program. Type-checking the
program involves determining the type of every expression
Once the compiler finishes checking your code for errors, it will translate it into assembly
You can ask the compiler to optimize your code—transform it to make the resulting assembly run
faster—by specifying the -O option
Programs are usually compiled with no optimizations for testing and debugging and then re-
compiled with optimizations once they are ready for release/use.
You can request that gcc stop after it assembles an object file by specifying the -c option. For
example, gcc -c xyz.c will compile xyz.c into xyz.o.
Linker errors—indicated by the fact that they are reported by ld (the linker’s name)
When make is run, it starts from a particular target—something that it can build out of other
things. A common starting target might be your entire program. make first checks if the target is
up-to-date. Checking that a target is up-to-date requires checking that all of the files that the
target depends on are themselves up-to-date, and that none of them are newer than the target.
For example, the target for the whole program may depended on many object files. If any such
file is not itself up-to-date (for example, the object file may depend on a .c file, which just got
changed), it is rebuilt first. make then follows whatever rule was specified for the target to build it
from its dependencies. If the target is already up to date, then it does nothing.
eg: of makefile
CLEAN
The clean target is a bit different in that it does not actually create a file called clean (it is
therefore called a “phony” target). Instead, it is a target intended to remove the compiled
program, all object files, all editor backups (*.c~ *.h~),
.PHONY: clean
clean:
%.o: %.c
.PHONY: clean
clean:
In make, we can write generic rules. A generic rule lets us specify that we want to be able to
build (something).o from (something).c, where we represent the something with a percent-sign
(%)
n this rule, we cannot write the literal name of the source file, as it changes for each instance of
the rule. Instead, we have to use the special built-in variable $<, which make will set to the name
of the first prerequisite of the rule
We could make every object file depend on every header file (by writing %.o : %.c *.h)
CC = gcc
SRCS=$(wildcard *.c)
OBJS=$(patsubst %.c,%.o,$(SRCS))
DBGOBJS=$(patsubst %.c,%.dbg.o,$(SRCS))
myProgram: $(OBJS)
myProgram-debug: $(DBGOBJS)
%.dbg.o: %.c
clean:
depend:
makedepend $(SRCS)
# DO NOT DELETE
Parallelizing computation
the -j option (, make -j8 runs up to 8 tasks in parallel)
Black box testing- making test case without knowing src code
Unlike black box testing, white box testing involves examining the code to devise test cases.
For numerical inputs, these would generally be negative, zero, and positive. One is also
usually a good number to be sure you cover
For sequences of data, your tests should cover an empty sequence, a single element
sequence, and a sequence with many elements.
For characters: lowercase letters, uppercase letters, digits, punctuation, spaces, non-
printable characters
three levels of test coverage: statement coverage, decision coverage, and path coverage
decision coverage— this means we construct a test case where the expression evaluates to true,
and another where it evaluates to false. CFG for one function at a time
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
achieve path coverage, our test cases must span all possible valid paths through the control flow
graph
This approach requires development of code which is not part of the main application—a
program which not only sends the requests into the network model, but also tracks the status of
those requests and checks for the proper outcomes. This additional program is called a test
harness—
An invariant is a property that is (or should be) always true at a given point in the program.
Ask A Question
we should aim for more focused questions: “On which line of code does my program crash?” or
“Why does my program call myFunction with x=3 and y=-42?”.
A breakpoint is set on a particular line of code, and instructs the debugger to stop the execution
of your program whenever the execution arrow is on it.
Watchpoints specify that you want to stop the program when a particular “box” changes.
Correct hypothesis
The first characteristic of a good hypothesis that this exhibits is that it is testable.
The contrived hypothesis we presented at the end of the previous paragraph is quite testable: we
specify a certain category of inputs (y is odd and z is a perfect square) and exactly what behavior
we expect to observe (division by 0 on line 47).
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
Adding asserts
Code inspection
Another method to test your hypothesis is to inspect and analyze your code. Sometimes a simple
hypothesis can be tested with a quick inspection.
start: Begin (or restart) the program’s execution. Stop the program (to accept more commands)
as soon as execution enters main.
run: This command runs the program (possibly restarting it). It will not stop unless it encounters
some other condition that causes it to stop (we will learn about these later).
step: Advance the program one “step”, in much the same way that we would advance the
execution arrow when Advance the program one line of code. However, unlike step, if the current
line of code is a function call, gdb will execute the entire called function without stopping. This
command can be abbreviated n.
print: The print command takes an expression as an argument, evaluates that expression, and
prints the results. Note that if the expression has side-effects, they will happen, and will affect the
state of the program (e.g., if you do print x = 3, it will set x to 3, then print 3). You can
put /x after print to get the result printed in hexadecimal format. This command can be
abbreviated p (or p/x to print in hex). for example, if a is an array, you can do p a[0]@5 to print
the first 5 elements of a.
every time gdb stops and displays a prompt You can set a breakpoint with the break command,
followed by either a line number, or a function name
cond 1 i==250000
Two other useful commands to control the execution of the program are until, which causes a
loop to execute until it finishes (gdb stops at the first line after the loop), and finish (which can be
abbreviated fin),
Signals
Whenever your program receives a signal, gdb will stop the program and give you control.
SIGINT, which happens when the program is interrupted—e.g., by the user pressing Control-c
Pointer
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
lines like these are illegal: int *ptr = &3; and int *ptr = &(x + y) since they do not point to any box .
ptrs can only hold addresses
Code
a program itself can be represented by a series of numbers. Producing these numbers is the job
of a compiler
The compiler converts the C code into object code and also assigns each encoded instruction a
location in memory.
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
Static Data
Unlike a variable that is declared inside a function and is no longer accessible when the function
returns, static variables are accessible until the entire program terminates (hence, the
term static ).
The Heap (in purple) stores dynamically allocated data. The Stack (in orange) stores the local
variables declared by each function.
Arguments of a function lie in the stac frame of the function that called it
programs use a pointer with the numeric value of 0—which has the special name, NULL to mean
“does not point at anything. ….. there is no answer
The NULL pointer has a special type that we have not seen yet—void *
Because we do not know what a void * actually points at, we can neither dereference it
pointer to struct
Pointers to Pointers
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
const
, it is good time to introduce the notion of const data—data which we tell the compiler we are not
allowed to change.
const int * p = &x;\\ cannot assign value to the box arrow points to
Aliasing
casting (int*)&f considers f to be already int converts 3.14 to binary then hex than int
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
so if ptr is of int* then compiler will increment that many number of bytes eg 4
this does not point to a known address and is generally not used
ArraYS
int myarr[3]={1,2,3}
rect p={.x=3,.y=5}
indexing ptr[i]
.DANGLING POINTERS
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
after function memory is deallocated and stack frame destroyed it points to something that is not
there
eg:
size_t x=sizeof(int)+sizeof(*p)
STRINGS
When we want to modify a string, we need the string to reside in writeable memory, such as the
frame of a function or memory that is dynamically allocated by malloc (which you will learn about
in Course 4). To make space for a string in a function’s frame, we need to declare an array of
chars with sufficient space to hold all of its characters, plus its null terminator.
The C library strcmp function behaves slightly differently than the one we are about to write in the
video—it returns 0 if the strings are equal, and non-zero if they are different. In fact, it returns a
positive number if the first string is “greater than” the second string and a negative number if the
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
first string is “less than” the second string. Here “greater than” and “less than” refer
to lexicographic order
The comparison is case sensitive (so abc is different from Abc), but there is another
function, strcasecmp which performs case-insensitive comparison.
strncpy =takes parameter n which is string size if dest<=n dest not null terminated meaning no
space for null terminatorw
String to int
strtol-lets you specify base as well as , end ptr to whatever is there after numerical value
Multidimesional arrays
double myMatrix[4out][3in];
in myArray[2][1]
myArray[2][1] is an lvalue as it points to a box whereas myArray[2] ptr is not stored anywhere
and jus cal from myarray ptr therefor it is not an lvalue
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
When we initialize an array in this fashion we can leave off the first dimension, as the compiler
can determine how many elements there are from the initialize
eg to initialize
in char [1][3][4]
An array of pointers
double row0[3]={11,22,56};
double row1[3];
double row2[3];
double row3[3];
*(array[0]+1)
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
ARRAY OF STRINGS
Above fig may waste space if words smaller than max length
NOTE
FUNCTION POINTER
Declaration
eg int (*elf)(int)
(*elf)(10);
int(*ptr[])(int, int)={fn1,fn2,fn3}
(*ptr[2])(1,3)
executes fn3
void fn (int a)
void fn1(void (*fn)(int))
fn1(fn)
Quicksort fn
strings
int
inp
if(n<=0){
return 1;
return n*factorial(n-1)
1, Recursive function must always have a base case in this case the if stmt
But regular recursion is slow it computes same thing many time ,,, we can use
memorization to solve this
TAIL RECURSION
int f(a,ans){
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
if (a<=0){
return ans;
return f(a-1,ans*a)
f(b,1);}
f(a,a1,,,,,,an, ans)
base condition
return ans
return (exp1,exp2.,,,,expn,ans)
MUTUAL RECURSION
prototype
if a==0 return 0
if a==1 return 1
if a==1 return 0
if a==0 return 1
return fen(n-1)
0 or 1
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
OS Concepts
since errno is global (there is one for the entire program), you must take care not to call anything
that might change it before you test it or call perror.
//BROKEN CODE
int x = someSystemCall();
if (x != 0) {
int argc is the count of how many command line arguments were passed in (it stands
for argument count)
second is an array of strings, which contains the arguments that were passed in (it stands
for argument vector).
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
ENVIRONMENT POINTER
PROCESS CREATION
To create another process in a running program we make use of fork() it creates a process
identical to the parent process called child process
execve() sys call replaces the child process with a script or program it specifies the argv and
envp to pass to it
it stores the argv and envp and moves the arrow to start of script or binary
then it calls main() if main declared with less arg than child process it ignores it
main() returns to the function that calld it then procedes exit() system call to terminate the child
process
OPENING A FILE
Reading a File
Once we have our file open, we might want to read input from it. We typically will use one of
three functions to do so: fgetc, fgets, or fread.
while(c=fgetc(f)!=EOF)
while(fgets(arr1,size,f)!=NULL)
size_t fread (void * ptr, size_t size, size_t nitems, FILE * stream);
ptr=dest
stream=file
WRITING TO A FILE
size_t fwrite(const void * ptr, size_t size, size_t nitems, FILE * stream);
CLOSE
fclose(f)
Instead of stack memory is stored on the heap and freed after it serves its purpose
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
malloc
polygon_t * p2 = malloc(sizeof(*p2));
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
*p2 = *p;
polygon_t * p2 = malloc(sizeof(*p2));
p2->num_points = p1->num_points;
p2->points[i] = p1->points[i];
free
eg for(size_t i=0;i<4;i++){
free(p[i]);
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
free(p)
cannot free a middle of a allocation like p++ free(p) pointer must always point to zeroth element
realloc
If no area in the heap of the requested size is available, realloc returns NULL.
p=realloc(p, 5*sizeof(int))
getline
int main(void){
size_t sz=0;
ssize_t len=0;
char* line=NULL;
FILE *f=fopen(“direc”,”r”);
while(len=getline(&line,&sz,f) >=0)
free(line);
while(len=getline(&line,&sz,f) >=0)
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
store[i] = line;
line=NULL;
i++;
VALGRIND
--track-origins=yes
--vgdb=full --vgdb-error=0
path/to/gdb ./tst
inside gdb
monitor who_points_at
ABSTRACTION
Seperation of
Hierarchial abstraction
Design in such a way that smaller function together make up a single function ie topdown design
methodology bottom up
Readability
Naming conventions
Git
-commit regularly
-pull push
NOTES(STRUCTS)
Flexible arrays at end of struct
1 struct can only have a single flexible array
items preceding it must be defined
struct declarations must always be at the top before any function prototype
when passing struct pointers pass using struc**
when resolvinf addressing use struc*
ARRAY OF STRINGS
eg char **orderedIds;
if(orderedIds[i]==NULL){
perror("");
exit(EXIT_FAILURE);
orderedIds[i]="enterme";
printf("\n{");
printf("%s, ",orderedIds[i]);
int dt=**(dt+i)=6
eg
if(*(orderedIds+i)==NULL){
perror("");
exit(EXIT_FAILURE);
**(orderedIds+i)=12;
printf("\n{");
printf("%d, ",**(orderedIds+i));
FUNCTION POINTER
FP
eg
C PROGRAMMING-FUNDAMENTALS 1-4 COURSERA
fun_y(“this”,2);
ARRAY of FP
fn(fun_y)