SlideShare a Scribd company logo
C Programming in Unix
Whirlwind tour of C
slides prepared by: mkc
Outline
● gcc
● make
● gdb
● emacs
● C-tour
C is a compiled language
● For a program to run, its source text has to be
processed by a compiler, producing object
files, which are combined by a linker yielding
an executable program.
gcc
● Gcc is both a compiler and a linker of the open-
source GNU project (www.gnu.org).
Alternate Compilation
● General form:
man gcc
Command-line options
Warning
● It's a memorable error if your -o option gets
switched around in the command line so it
accidentally comes before a source file like
"...-o foo.c program" -- this can overwrite your
source file – bye bye source file!
Command-line options
Insights
● Sometimes -Wall warnings are not actually
problems. The code is ok, and the compiler
just needs to be convinced.
● Don't ignore the warning. Fix up the source
code so the warning goes away. Getting used
to compiles that produce "a few warnings" is a
very bad habit.
Command-line options
Finding the #include file.
● find /usr/include/ -name '*math*'
Important
● The position of the -l flag in the option list is important
because the linker will not go back to previously examined
libraries to look for unresolved symbols.
● Ex. if you are using a library that requires the math library
it must appear before the math library on the command
line otherwise a link error will be reported. Again, there is
no space between the option flag and the library file
name, and that's a lower case 'L', not the digit '1'. If your
link step fails because a symbol cannot be found, you
need a -l to add the appropriate library, or somehow you
are compiling with the wrong name for the function.
Makefile
● A makefile consists of a series of variable
definitions and dependency rules.
● A variable in a makefile is a name defined to
represent some string of text.
● This works much like macro replacement in
the C pre-processor.
Makefile variables
Variable
● To refer to the value of a variable, put a dollar
sign ($) followed by the name in parenthesis
or curly braces...
Exercise
● Run a Hello,World! Program using emacs.
-Wall warning
Compile Success
Run
● ./sample
Or
● M-x compile make run
Dependency/build rule
● A rule tells how to make a target based on
changes to a list of certain files.
● The ordering of the rules does not make any
difference, except that the first rule is
considered to be the default rule – the rule that
will be invoked when make is called without
arguments
Important
● The command lines must be indented with a
tab character -- just using spaces will not
work, even though the spaces will sort of look
right in your editor.
Example
C tour Unix
Insights
● The first (default) target builds the program
from the three .o's.
● The next three targets such as "main.o :
main.c binky.h akbar.h defs.h" identify the .o's
that need to be built and which source files
they depend on.
● These rules identify what needs to be built, but
they omit the command line. Therefore they
will use the default rule which knows how to
build one .o from one .c with the same name.
Insights
● make automatically knows that a X.o always
depends on its source X.c, so X.c can be
omitted from the rule. So the first rule could b
ewritten without main.c – "main.o : binky.h
akbar.h defs.h".
● The clean target is used to remove all of the
object files, the executable, and a core file if
you've been debugging, so that you can
perform the build process from scratch .
Compiling in Emacs
● Emacs has built-in support for the compile
process.
● To compile your code from emacs, type
M­x compile.
● If you have a makefile, just type make and hit
return.
● The makefile will be read and the appropriate
commands executed.
● The emacs buffer will split at this point, and
compile errors will be brought up in the newly
created buffer.
gdb
● GNU debugger gdb
C tour Unix
Example
Debug Division By Zero
Debug Division By Zero
Debug Factorial Solution
Debug Factorial Solution
Solved!
emacs
Moving about
Searching and Deleting
C tour Unix
C tour Unix
Unix Shell
C tour Unix
C tour Unix
C tour Unix
C tour Unix
Reference
Appendix
Starting and Leaving Emacs
Working with Files
C tour Unix
Moving the Cursor
C tour Unix
C tour Unix
Repeating Commands
Cutting Text
C tour Unix
Stopping Commands
● When you want to stop any command that's in
progress, press C-g.
● The word Quit appears in the command area.
Incremental Search
Nonincremental and Word Search
Query Replace
C tour Unix
External Library
myLibrary.c
myLibrary.h
Test.c
Compilation and Run
Nick Parlante's Essential C
● Have a mental picture (or a real drawing) of how your
C code is using memory. That's good advice in any
language, but in C it's critical.
● Java and C++ are more structured than C. Structure
is useful for large projects.
● C works best for small projects where performance is
important and the programmers have the time and
skill to make it work in C.
● In any case, C is a very popular and influential
language. This is mainly because of C's clean (if
minimal) style.
Typical ranges for C integral data
types on a 32-bit machine.
C tour Unix
Floats are Inexact!
●You should never compare floating numbers to
eachother for equality (==) -- use inequality (<)
comparisons instead. (But sometimes it works!)
Variables start with random values
Pitfall
Bitwise Operators
C Arrays
Examine An Uninitialized Array
Pointers
Pointers
● Programmer's have their own conventions
Pointer Dereferencing
Advanced Declarations
Initialize A Pointer
Pitfall -- Uninitialized Pointers
● There are three things which must be done for
a pointer/pointee relationship to work...
(1) The pointer must be declared and
allocated
(2) The pointee must be declared and
allocated
(3) The pointer (1) must be initialized so that it
points to the pointee (2)
Insights
● The most common pointer related error of all time
is the following:
“ Declare and allocate the pointer (step 1). Forget
step 2 and/or 3. Start using the pointer as if it has
been setup to point to something. Code with this
error frequently compiles fine, but the runtime
results are disastrous. Unfortunately the pointer
does not point anywhere good unless (2) and (3)
are done, so the run time dereference operations
on the pointer with * will misuse and trample
memory leading to a random crash at some point.”
Dangling Pointer
Using Pointers
● Declaring a pointer allocates space for the
pointer itself, but it does not allocate space for
the pointee.
● The pointer must be set to point to something
before you can dereference it.
Using Pointers
C Strings
● C does include a standard library of functions
which perform common string operations, but
the programmer is responsible for the
managing the string memory and calling the
right functions.
● Unfortunately computations involving strings
are very common, so becoming a good C
programmer often requires becoming adept at
writing code which manages strings which
means managing pointers and arrays.
C Strings
● A C string is just an array of char with the one
additional convention that a "null" character ('0') is
stored after the last real character in the array to
mark the end of the string.
● The most useful library function is strcpy(char
dest[], const char source[]); which copies the bytes
of one string over to another.
● The order of the arguments to strcpy() mimics the
argument in of '=' -- the right is assigned to the left.
C Strings
● Another useful string function is strlen(const
char string[]); which returns the number of
characters in C string not counting the trailing
'0'.
● Note that the regular assignment operator (=)
does not do string copying which is why
strcpy() is necessary.
Example
● The following code allocates a 10 char array and
uses strcpy() to copy the bytes of the string
constant "binky" into that local array.
Example
"Frances000004b"
Reversing a String
Reversing a String
Reversing a String
char*
● Because of the way C handles the types of
arrays, the type of the variable an array uses is
essentially char*.
● C programs very often manipulate strings using
variables of type char* which point to arrays of
characters.
● Manipulating the actual chars in a string
requires code which manipulates the underlying
array, or the use of library functions such as
strcpy().
TypeDef
● A typedef statement introduces a shorthand
name for a type. The syntax is
● It's convenient to use typedef to create types
with upper case names and use the lower-
case version of the same word as a variable.
Example
● The following typedef defines the name Tree
as a standard pointer to a binary tree node
where each node contains some data and
"smaller" and "larger" subtree pointers.
static
● The keyword "static" defines that the function
will only be available to callers in the file where
it is declared.
● The static form is convenient for utility functions
which will only be used in the file where they
are declared.
● If a function needs to be called from another
file, the function cannot be static and will
require a prototype.
Actual vs Formal Parameters
● The expression passed to a function by its
caller is called the "actual parameter".
● The parameter storage local to the function is
called the "formal parameter" such as the
"num" in "static int Twice(int num)".
C-ing and Nothingness -- void
● void is a type formalized in ANSI C which
means "nothing".
● To indicate that a function does not return
anything, use void as the return type.
● Also, by convention, a pointer which does not
point to any particular type is declared as
void*.
More on Void
● Sometimes void* is used to force two bodies
of code to not depend on each other where
void* translates roughly to "this points to
something, but I'm not telling you (the client)
the type of the pointee exactly because you do
not really need to know."
● If a function does not take any parameters, its
parameter list is empty, or it can contain the
keyword void but that style is now out of favor.
Example
Call by Value vs. Call by Reference
● C passes parameters "by value" which means that the
actual parameter values are copied into local storage.
● The caller and callee functions do not share any memory
-- they each have their own copy.
● The alternative is to pass the arguments "by reference".
Instead of passing a copy of a value from the caller to the
callee, pass a pointer to the value.
● In this way there is only one copy of the value at any time,
and the caller and callee both access that one value
through pointers.
Swap by Reference
Swap by Reference
const
● The qualifier const can be added to the left of a
variable or parameter type to declare that the
code using the variable will not change the
variable.
● As a practical matter, use of const is very
sporadic in the C programming community.
● It does have one very handy use, which is to
clarify the role of a parameter in a function
prototype...
main()
● The execution of a C program begins with
function named main().
● All of the files and libraries for the C program
are compiled together to build a single program
file.
● That file must contain exactly one main()
function which the operating system uses as the
starting point for the program.
● Main() returns an int which, by convention, is 0
if the program completed successfully and non-
zero if the program exited due to some error
condition.
Prototypes
● A "prototype" for a function gives its name and
arguments but not its body.
● In order for a caller, in any file, to use a function,
the caller must have seen the prototype for that
function.
● For example, here's what the prototypes would
look like for Twice() and Swap().
● The function body is absent and there's a
semicolon (;) to terminate the prototype...
ANSI C
● a function may be declared static in which
case it can only be used in the same file
where it is used below the point of its
declaration.
● Static functions do not require a separate
prototype so long as they are defined before
or above where they are called which saves
some work.
ANSI C
● A non-static function needs a prototype. When
the compiler compiles a function definition, it
must have previously seen a prototype so that
it can verify that the two are in agreement
("prototype before definition" rule).
● The prototype must also be seen by any client
code which wants to call the function ("clients
must see prototypes" rule).
Preprocessor
● The preprocessing step happens to the C source before
it is fed to the compiler.
● The two most common preprocessor directives are
#define and #include...
● #define directive can be used to set up symbolic
replacements in the source.
● As with all preprocessor operations, #define is
extremely unintelligent -- it just does textual
replacement without understanding.
● #define statements are used as a crude way of
establishing symbolic constants
#include
● The "#include" directive brings in text from
different files during compilation.
● #include is a very unintelligent and unstructured
-- it just pastes in the text from the given file and
continues compiling.
● The #include directive is used in the .h/.c file
convention below which is used to satisfy the
various constraints necessary to get prototypes
correct.
foo.h vs foo.c
● A separate file named foo.h will contain the
prototypes for the functions in foo.c which
clients may want to call.
● Functions in foo.c which are for "internal use
only" and should never be called by clients
should be declared static.
● Near the top of foo.c will be the following line
which ensures that the function definitions in
foo.c see the prototypes in foo.h which ensures
the "prototype before definition" rule above.
foo.h vs foo.c
● Any xxx.c file which wishes to call a function
defined in foo.c must include the following line
to see the prototypes, ensuring the "clients
must see prototypes" rule above.
#include "foo.h"
#if
● At compile time, there is some space of
names defined by the #defines. The #if test
can be used at compile-time to look at those
symbols and turn on and off which lines the
compiler uses.
Multiple #includes -- #pragma once
● There's a problem sometimes where a .h file is #included
into a file more than one time resulting in compile errors.
● This can be a serious problem. Because of this, you
want to avoid #including .h files in other .h files if at all
possible.
● On the other hand, #including .h files in .c files is fine. If
you are lucky, your compiler will support the #pragma
once feature which automatically prevents a single file
from being #included more than once in any one file.
Assert
● Array out of bounds references are an extremely
common form of C run-time error.
● You can use the assert() function to sprinkle your code
with your own bounds checks.
● A few seconds putting in assert statements can save you
hours of debugging.
● Assert statements are one of the easiest and most
effective helpers for that difficult phase.
Advanced C Arrays
● In C, an array is formed by laying out all the
elements contiguously in memory.
● The square bracket syntax can be used to
refer to the elements in the array.
● The array as a whole is referred to by the
address of the first element which is also
known as the "base address" of the whole
array.
C tour Unix
[ ]
● The programmer can refer to elements in the
array with the simple [ ] syntax such as
array[1].
● This scheme works by combining the base
address of the whole array with the index to
compute the base address of the desired
element in the array.
C tour Unix
Insight
● The expression (intArray + 3) is a pointer to the integer
intArray[3].
● (intArray + 3) is of type (int*) while intArray[3] is of type
int.
● The two expressions only differ by whether the pointer
is dereferenced or not. So the expression (intArray +
3) is exactly equivalent to the expression
(&(intArray[3])).
● In fact those two probably compile to exactly the same
code. They both represent a pointer to the element at
index 3.
Pointer++ Style -- strcpy()
● Strcpy() : Debug the following:
Debugging with gdb
Debugging with gdb
Debugging with gdb
Debugging with gdb
Debugging with gdb
Debugging with gdb
Debugging with gdb
Pointer Type Effects
● Both [ ] and + implicitly use the compile time
type of the pointer to compute the
element_size which affects the offset
arithmetic.
● When looking at code, it's easy to assume that
everything is in the units of bytes.
Answer
● The previous code does not add the number 12
to the address in p-- that would increment p by
12 bytes.
● The previous code increments p by 12 ints.
Each int probably takes 4 bytes, so at run time
the code will effectively increment the address
in p by 48.
● The compiler figures all this out based on the
type of the pointer.
Casting a Pointer
● The programmer is allowed to cast any pointer
type to any other pointer type like this to
change the code the compiler generates.
Arrays and Pointers
● One effect of the C array scheme is that the compiler
does not distinguish meaningfully between arrays and
pointers-- they both just look like pointers.
● In the following example, the value of intArray is a
pointer to the first element in the array so it's an (int*).
● The value of the variable intPtr is also (int*) and it is
set to point to a single integer i.
Arrays and Pointers
● So what's the difference between intArray and intPtr?
Not much as far as the compiler is concerned.
● They are both just (int*) pointers, and the compiler is
perfectly happy to apply the [ ] or + syntax to either.
● It's the programmer's responsibility to ensure that the
elements referred to by a [] or + operation really are
there.
● Really its' just the same old rule that C doesn't do any
bounds checking.
● C thinks of the single integer i as just a sort of
degenerate array of size 1.
C tour Unix
Array Names Are Const
● One subtle distinction between an array and a
pointer, is that the pointer which represents
the base address of an array cannot be
changed in the code.
● The array base address behaves like a const
pointer.
● The constraint applies to the name of the array
where it is declared in the code.
C tour Unix
Array parameters are passed as
pointers
● The following two definitions of foo look
different, but to the compiler they mean
exactly the same thing.
Heap Memory
● C gives programmers the standard sort of facilities to
allocate and deallocate dynamic heap memory.
● A word of warning: writing programs which manage
their heap memory is notoriously difficult.
● This partly explains the great popularity of languages
such as Java and Perl which handle heap
management automatically.
● These languages take over a task which has proven
to be extremely difficult for the programmer.
Heap Memory
● C provides access to the heap features
through library functions which any C code
can call.
● The prototypes for these functions are in the
file <stdlib.h>, so any code which wants to call
these must #include that header file.
void* malloc(size_t size)
● Request a contiguous block of memory of the given
size in the heap.
● malloc() returns a pointer to the heap block or NULL
if the request could not be satisfied.
● The type size_t is essentially an unsigned long
which indicates how large a block the caller would
like measured in bytes.
● Because the block pointer returned by malloc() is a
void* (i.e. it makes no claim about the type of its
pointee), a cast will probably be required when
storing the void* pointer into a regular typed pointer.
void free(void* block)
● The mirror image of malloc() -- free takes a
pointer to a heap block earlier allocated by
malloc() and returns that block to the heap for
re-use.
● After the free(), the client should not access
any part of the block or assume that the block
is valid memory.
● The block should not be freed a second time.
void* realloc(void* block, size_t size)
● Take an existing heap block and try to relocate it to a
heap block of the given size which may be larger or
smaller than the original size of the block.
● Returns a pointer to the new block, or NULL if the
relocation was unsuccessful.
● Remember to catch and examine the return value of
realloc() -- it is a common error to continue to use the old
block pointer.
● Realloc() takes care of moving the bytes from the old
block to the new block.
● Realloc() exists because it can be implemented using
low-level features which make it more efficient than C
code the client could write.
Memory Management
● All of a program's memory is deallocated
automatically when the it exits, so a program
only needs to use free() during execution if it is
important for the program to recycle its memory
while it runs -- typically because it uses a lot of
memory or because it runs for a long time.
● The pointer passed to free() must be exactly the
pointer which was originally returned by malloc()
or realloc(), not just a pointer into somewhere
within the heap block.
Dynamic Arrays
● Since arrays are just contiguous areas of bytes, you
can allocate your own arrays in the heap using
malloc().
● The following code allocates two arrays of 1000
ints-- one in the stack the usual "local" way, and one
in the heap using malloc().
Advantages of being in the heap
● Size (in this case 1000) can be defined at run time.
Not so for an array like "a".
● The array will exist until it is explicitly deallocated
with a call to free().
● You can change the size of the array at will at run
time using realloc().
● The following changes the size of the array to
2000. Realloc() takes care of copying over the old
elements.
Disadvantages of Being in The Heap
● You have to remember to allocate the array, and you
have to get it right.
● You have to remember to deallocate it exactly once
when you are done with it, and you have to get that
right.
● The above two disadvantages have the same basic
profile: if you get them wrong, your code still looks
right. It compiles fine. It even runs for small cases, but
for some input cases it just crashes unexpectedly
because random memory is getting overwritten
somewhere like the smiley face.
● This sort of "random memory smasher" bug can be a
real ordeal to track down.
Dynamic Strings
● The dynamic allocation of arrays works very well
for allocating strings in the heap.
● The advantage of heap allocating a string is that
the heap block can be just big enough to store
the actual number of characters in the string.
● The common local variable technique such as
char string[1000]; allocates way too much space
most of the time, wasting the unused bytes, and
yet fails if the string ever gets bigger than the
variable's fixed size.
C tour Unix
Standard Library Functions
stdio.h
● stdio.h is a very common file to #include
-- it includes functions to print and read strings
from files and to open and close files in the file
system.
C tour Unix
C tour Unix
printf()
scanf()
ctype.h
string.h
C tour Unix
C tour Unix
stdlib.h
C tour Unix
Reference:
END
Appendix
Defensive Programmer Strategies
● Never Trust Input
- Never trust the data you are given and always validate it.
● Prevent Errors
- If an error is possible, no matter how probable, try to
prevent it.
● Fail Early And Openly
- Fail early, cleanly, and openly, stating what happened,
where and how to fix it.
● Document Assumptions
- Clearly state the pre-conditions, post-conditions, and
invariants.
Defensive Programmer Strategies
● Prevention Over Documentation
- Do not do with documentation, that which can be
done with code or avoided completely.
● Automate Everything
- Automate everything, especially testing.
● Simplify And Clarify
- Always simplify the code to the smallest, cleanest
form that works without sacrificing safety.
● Question Authority
- Do not blindly follow or reject rules.

More Related Content

PDF
Valgrind
PPTX
Functional Programming in Java
PDF
Functional Programming in Ruby
PPSX
Java 8 – completion stage
PDF
Thinking in Functions
PPTX
09 advanced c#
PPTX
Inline function in C++
PPTX
Inline functions
Valgrind
Functional Programming in Java
Functional Programming in Ruby
Java 8 – completion stage
Thinking in Functions
09 advanced c#
Inline function in C++
Inline functions

What's hot (20)

ODP
2nd presantation
PDF
Programming Sessions KU Leuven - Session 02
PPTX
PPTX
Inline functions & macros
PPTX
INLINE FUNCTION IN C++
PDF
New c sharp4_features_part_v
PDF
12 Jo P Dec 07
PDF
Effective c++notes
PDF
Effective stl notes
PPTX
PPT
Csc1100 lecture03 ch03-pt2-s14
PPT
Csc1100 lecture03 ch03-pt2-s14
PDF
FregeDay: Design and Implementation of the language (Ingo Wechsung)
PDF
FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo W...
PDF
Hanoi JUG: Java 8 & lambdas
PDF
C++ Tail Recursion Using 64-bit variables
PPTX
Inline function in C++
DOCX
Inline function(oops)
2nd presantation
Programming Sessions KU Leuven - Session 02
Inline functions & macros
INLINE FUNCTION IN C++
New c sharp4_features_part_v
12 Jo P Dec 07
Effective c++notes
Effective stl notes
Csc1100 lecture03 ch03-pt2-s14
Csc1100 lecture03 ch03-pt2-s14
FregeDay: Design and Implementation of the language (Ingo Wechsung)
FregeDay: Roadmap for resolving differences between Haskell and Frege (Ingo W...
Hanoi JUG: Java 8 & lambdas
C++ Tail Recursion Using 64-bit variables
Inline function in C++
Inline function(oops)
Ad

Viewers also liked (18)

PPTX
T-Shell (TCSH)
PPTX
Kernels, Shells, and Popcorn
PPTX
First steps in C-Shell
PDF
Mercurial setup
PDF
LBYEC72_Overview
PDF
My Android portfolio part2
PDF
My Android portfolio part1
PDF
Dismath part2 2013
PDF
Nummeth0 ay1415
PDF
Data communication part2
PDF
DISMATH_Intro_Admin
PDF
PDF
Vector calculus
PDF
Transport layer services
PDF
Ipn conference2016
PDF
DISMATH_Part1
PDF
DISMATH_Part2
PPTX
Unix operating system
T-Shell (TCSH)
Kernels, Shells, and Popcorn
First steps in C-Shell
Mercurial setup
LBYEC72_Overview
My Android portfolio part2
My Android portfolio part1
Dismath part2 2013
Nummeth0 ay1415
Data communication part2
DISMATH_Intro_Admin
Vector calculus
Transport layer services
Ipn conference2016
DISMATH_Part1
DISMATH_Part2
Unix operating system
Ad

Similar to C tour Unix (20)

PPTX
C101 – Intro to Programming with C
ODP
C prog ppt
PDF
0100_Embeded_C_CompilationProcess.pdf
PDF
Programming in c_in_7_days
DOC
Basic c
PPTX
00 C hello world.pptx
PPTX
Lecture 01 Programming C for Beginners 001
PDF
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
PPT
C tutorial
PDF
c programming L-1.pdf43333333544444444444444444444
PPT
C tutorial
PPT
C introduction by piyushkumar
DOCX
C language industrial training report
PPTX
chapter 1.pptx
DOCX
The basics of c programming
DOCX
1 CMPS 12M Introduction to Data Structures Lab La.docx
PDF
C programming
PDF
Introduction to C programming
DOCX
C LANGUAGE UNIT-1 PREPARED BY MVB REDDY
C101 – Intro to Programming with C
C prog ppt
0100_Embeded_C_CompilationProcess.pdf
Programming in c_in_7_days
Basic c
00 C hello world.pptx
Lecture 01 Programming C for Beginners 001
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
C tutorial
c programming L-1.pdf43333333544444444444444444444
C tutorial
C introduction by piyushkumar
C language industrial training report
chapter 1.pptx
The basics of c programming
1 CMPS 12M Introduction to Data Structures Lab La.docx
C programming
Introduction to C programming
C LANGUAGE UNIT-1 PREPARED BY MVB REDDY

Recently uploaded (20)

PDF
top salesforce developer skills in 2025.pdf
PDF
System and Network Administraation Chapter 3
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Essential Infomation Tech presentation.pptx
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
System and Network Administration Chapter 2
PDF
Digital Strategies for Manufacturing Companies
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
AI in Product Development-omnex systems
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
top salesforce developer skills in 2025.pdf
System and Network Administraation Chapter 3
How to Migrate SBCGlobal Email to Yahoo Easily
VVF-Customer-Presentation2025-Ver1.9.pptx
Essential Infomation Tech presentation.pptx
Odoo POS Development Services by CandidRoot Solutions
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Design an Analysis of Algorithms II-SECS-1021-03
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
System and Network Administration Chapter 2
Digital Strategies for Manufacturing Companies
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
How to Choose the Right IT Partner for Your Business in Malaysia
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
AI in Product Development-omnex systems
Which alternative to Crystal Reports is best for small or large businesses.pdf

C tour Unix

  • 1. C Programming in Unix Whirlwind tour of C slides prepared by: mkc
  • 2. Outline ● gcc ● make ● gdb ● emacs ● C-tour
  • 3. C is a compiled language ● For a program to run, its source text has to be processed by a compiler, producing object files, which are combined by a linker yielding an executable program.
  • 4. gcc ● Gcc is both a compiler and a linker of the open- source GNU project (www.gnu.org).
  • 8. Warning ● It's a memorable error if your -o option gets switched around in the command line so it accidentally comes before a source file like "...-o foo.c program" -- this can overwrite your source file – bye bye source file!
  • 10. Insights ● Sometimes -Wall warnings are not actually problems. The code is ok, and the compiler just needs to be convinced. ● Don't ignore the warning. Fix up the source code so the warning goes away. Getting used to compiles that produce "a few warnings" is a very bad habit.
  • 12. Finding the #include file. ● find /usr/include/ -name '*math*'
  • 13. Important ● The position of the -l flag in the option list is important because the linker will not go back to previously examined libraries to look for unresolved symbols. ● Ex. if you are using a library that requires the math library it must appear before the math library on the command line otherwise a link error will be reported. Again, there is no space between the option flag and the library file name, and that's a lower case 'L', not the digit '1'. If your link step fails because a symbol cannot be found, you need a -l to add the appropriate library, or somehow you are compiling with the wrong name for the function.
  • 14. Makefile ● A makefile consists of a series of variable definitions and dependency rules. ● A variable in a makefile is a name defined to represent some string of text. ● This works much like macro replacement in the C pre-processor.
  • 16. Variable ● To refer to the value of a variable, put a dollar sign ($) followed by the name in parenthesis or curly braces...
  • 17. Exercise ● Run a Hello,World! Program using emacs.
  • 21. Or ● M-x compile make run
  • 22. Dependency/build rule ● A rule tells how to make a target based on changes to a list of certain files. ● The ordering of the rules does not make any difference, except that the first rule is considered to be the default rule – the rule that will be invoked when make is called without arguments
  • 23. Important ● The command lines must be indented with a tab character -- just using spaces will not work, even though the spaces will sort of look right in your editor.
  • 26. Insights ● The first (default) target builds the program from the three .o's. ● The next three targets such as "main.o : main.c binky.h akbar.h defs.h" identify the .o's that need to be built and which source files they depend on. ● These rules identify what needs to be built, but they omit the command line. Therefore they will use the default rule which knows how to build one .o from one .c with the same name.
  • 27. Insights ● make automatically knows that a X.o always depends on its source X.c, so X.c can be omitted from the rule. So the first rule could b ewritten without main.c – "main.o : binky.h akbar.h defs.h". ● The clean target is used to remove all of the object files, the executable, and a core file if you've been debugging, so that you can perform the build process from scratch .
  • 28. Compiling in Emacs ● Emacs has built-in support for the compile process. ● To compile your code from emacs, type M­x compile. ● If you have a makefile, just type make and hit return. ● The makefile will be read and the appropriate commands executed. ● The emacs buffer will split at this point, and compile errors will be brought up in the newly created buffer.
  • 37. emacs
  • 58. Stopping Commands ● When you want to stop any command that's in progress, press C-g. ● The word Quit appears in the command area.
  • 68. Nick Parlante's Essential C ● Have a mental picture (or a real drawing) of how your C code is using memory. That's good advice in any language, but in C it's critical. ● Java and C++ are more structured than C. Structure is useful for large projects. ● C works best for small projects where performance is important and the programmers have the time and skill to make it work in C. ● In any case, C is a very popular and influential language. This is mainly because of C's clean (if minimal) style.
  • 69. Typical ranges for C integral data types on a 32-bit machine.
  • 71. Floats are Inexact! ●You should never compare floating numbers to eachother for equality (==) -- use inequality (<) comparisons instead. (But sometimes it works!)
  • 72. Variables start with random values
  • 78. Pointers ● Programmer's have their own conventions
  • 82. Pitfall -- Uninitialized Pointers ● There are three things which must be done for a pointer/pointee relationship to work... (1) The pointer must be declared and allocated (2) The pointee must be declared and allocated (3) The pointer (1) must be initialized so that it points to the pointee (2)
  • 83. Insights ● The most common pointer related error of all time is the following: “ Declare and allocate the pointer (step 1). Forget step 2 and/or 3. Start using the pointer as if it has been setup to point to something. Code with this error frequently compiles fine, but the runtime results are disastrous. Unfortunately the pointer does not point anywhere good unless (2) and (3) are done, so the run time dereference operations on the pointer with * will misuse and trample memory leading to a random crash at some point.”
  • 85. Using Pointers ● Declaring a pointer allocates space for the pointer itself, but it does not allocate space for the pointee. ● The pointer must be set to point to something before you can dereference it.
  • 87. C Strings ● C does include a standard library of functions which perform common string operations, but the programmer is responsible for the managing the string memory and calling the right functions. ● Unfortunately computations involving strings are very common, so becoming a good C programmer often requires becoming adept at writing code which manages strings which means managing pointers and arrays.
  • 88. C Strings ● A C string is just an array of char with the one additional convention that a "null" character ('0') is stored after the last real character in the array to mark the end of the string. ● The most useful library function is strcpy(char dest[], const char source[]); which copies the bytes of one string over to another. ● The order of the arguments to strcpy() mimics the argument in of '=' -- the right is assigned to the left.
  • 89. C Strings ● Another useful string function is strlen(const char string[]); which returns the number of characters in C string not counting the trailing '0'. ● Note that the regular assignment operator (=) does not do string copying which is why strcpy() is necessary.
  • 90. Example ● The following code allocates a 10 char array and uses strcpy() to copy the bytes of the string constant "binky" into that local array.
  • 95. char* ● Because of the way C handles the types of arrays, the type of the variable an array uses is essentially char*. ● C programs very often manipulate strings using variables of type char* which point to arrays of characters. ● Manipulating the actual chars in a string requires code which manipulates the underlying array, or the use of library functions such as strcpy().
  • 96. TypeDef ● A typedef statement introduces a shorthand name for a type. The syntax is ● It's convenient to use typedef to create types with upper case names and use the lower- case version of the same word as a variable.
  • 97. Example ● The following typedef defines the name Tree as a standard pointer to a binary tree node where each node contains some data and "smaller" and "larger" subtree pointers.
  • 98. static ● The keyword "static" defines that the function will only be available to callers in the file where it is declared. ● The static form is convenient for utility functions which will only be used in the file where they are declared. ● If a function needs to be called from another file, the function cannot be static and will require a prototype.
  • 99. Actual vs Formal Parameters ● The expression passed to a function by its caller is called the "actual parameter". ● The parameter storage local to the function is called the "formal parameter" such as the "num" in "static int Twice(int num)".
  • 100. C-ing and Nothingness -- void ● void is a type formalized in ANSI C which means "nothing". ● To indicate that a function does not return anything, use void as the return type. ● Also, by convention, a pointer which does not point to any particular type is declared as void*.
  • 101. More on Void ● Sometimes void* is used to force two bodies of code to not depend on each other where void* translates roughly to "this points to something, but I'm not telling you (the client) the type of the pointee exactly because you do not really need to know." ● If a function does not take any parameters, its parameter list is empty, or it can contain the keyword void but that style is now out of favor.
  • 103. Call by Value vs. Call by Reference ● C passes parameters "by value" which means that the actual parameter values are copied into local storage. ● The caller and callee functions do not share any memory -- they each have their own copy. ● The alternative is to pass the arguments "by reference". Instead of passing a copy of a value from the caller to the callee, pass a pointer to the value. ● In this way there is only one copy of the value at any time, and the caller and callee both access that one value through pointers.
  • 106. const ● The qualifier const can be added to the left of a variable or parameter type to declare that the code using the variable will not change the variable. ● As a practical matter, use of const is very sporadic in the C programming community. ● It does have one very handy use, which is to clarify the role of a parameter in a function prototype...
  • 107. main() ● The execution of a C program begins with function named main(). ● All of the files and libraries for the C program are compiled together to build a single program file. ● That file must contain exactly one main() function which the operating system uses as the starting point for the program. ● Main() returns an int which, by convention, is 0 if the program completed successfully and non- zero if the program exited due to some error condition.
  • 108. Prototypes ● A "prototype" for a function gives its name and arguments but not its body. ● In order for a caller, in any file, to use a function, the caller must have seen the prototype for that function. ● For example, here's what the prototypes would look like for Twice() and Swap(). ● The function body is absent and there's a semicolon (;) to terminate the prototype...
  • 109. ANSI C ● a function may be declared static in which case it can only be used in the same file where it is used below the point of its declaration. ● Static functions do not require a separate prototype so long as they are defined before or above where they are called which saves some work.
  • 110. ANSI C ● A non-static function needs a prototype. When the compiler compiles a function definition, it must have previously seen a prototype so that it can verify that the two are in agreement ("prototype before definition" rule). ● The prototype must also be seen by any client code which wants to call the function ("clients must see prototypes" rule).
  • 111. Preprocessor ● The preprocessing step happens to the C source before it is fed to the compiler. ● The two most common preprocessor directives are #define and #include... ● #define directive can be used to set up symbolic replacements in the source. ● As with all preprocessor operations, #define is extremely unintelligent -- it just does textual replacement without understanding. ● #define statements are used as a crude way of establishing symbolic constants
  • 112. #include ● The "#include" directive brings in text from different files during compilation. ● #include is a very unintelligent and unstructured -- it just pastes in the text from the given file and continues compiling. ● The #include directive is used in the .h/.c file convention below which is used to satisfy the various constraints necessary to get prototypes correct.
  • 113. foo.h vs foo.c ● A separate file named foo.h will contain the prototypes for the functions in foo.c which clients may want to call. ● Functions in foo.c which are for "internal use only" and should never be called by clients should be declared static. ● Near the top of foo.c will be the following line which ensures that the function definitions in foo.c see the prototypes in foo.h which ensures the "prototype before definition" rule above.
  • 114. foo.h vs foo.c ● Any xxx.c file which wishes to call a function defined in foo.c must include the following line to see the prototypes, ensuring the "clients must see prototypes" rule above. #include "foo.h"
  • 115. #if ● At compile time, there is some space of names defined by the #defines. The #if test can be used at compile-time to look at those symbols and turn on and off which lines the compiler uses.
  • 116. Multiple #includes -- #pragma once ● There's a problem sometimes where a .h file is #included into a file more than one time resulting in compile errors. ● This can be a serious problem. Because of this, you want to avoid #including .h files in other .h files if at all possible. ● On the other hand, #including .h files in .c files is fine. If you are lucky, your compiler will support the #pragma once feature which automatically prevents a single file from being #included more than once in any one file.
  • 117. Assert ● Array out of bounds references are an extremely common form of C run-time error. ● You can use the assert() function to sprinkle your code with your own bounds checks. ● A few seconds putting in assert statements can save you hours of debugging. ● Assert statements are one of the easiest and most effective helpers for that difficult phase.
  • 118. Advanced C Arrays ● In C, an array is formed by laying out all the elements contiguously in memory. ● The square bracket syntax can be used to refer to the elements in the array. ● The array as a whole is referred to by the address of the first element which is also known as the "base address" of the whole array.
  • 120. [ ] ● The programmer can refer to elements in the array with the simple [ ] syntax such as array[1]. ● This scheme works by combining the base address of the whole array with the index to compute the base address of the desired element in the array.
  • 122. Insight ● The expression (intArray + 3) is a pointer to the integer intArray[3]. ● (intArray + 3) is of type (int*) while intArray[3] is of type int. ● The two expressions only differ by whether the pointer is dereferenced or not. So the expression (intArray + 3) is exactly equivalent to the expression (&(intArray[3])). ● In fact those two probably compile to exactly the same code. They both represent a pointer to the element at index 3.
  • 123. Pointer++ Style -- strcpy() ● Strcpy() : Debug the following:
  • 131. Pointer Type Effects ● Both [ ] and + implicitly use the compile time type of the pointer to compute the element_size which affects the offset arithmetic. ● When looking at code, it's easy to assume that everything is in the units of bytes.
  • 132. Answer ● The previous code does not add the number 12 to the address in p-- that would increment p by 12 bytes. ● The previous code increments p by 12 ints. Each int probably takes 4 bytes, so at run time the code will effectively increment the address in p by 48. ● The compiler figures all this out based on the type of the pointer.
  • 133. Casting a Pointer ● The programmer is allowed to cast any pointer type to any other pointer type like this to change the code the compiler generates.
  • 134. Arrays and Pointers ● One effect of the C array scheme is that the compiler does not distinguish meaningfully between arrays and pointers-- they both just look like pointers. ● In the following example, the value of intArray is a pointer to the first element in the array so it's an (int*). ● The value of the variable intPtr is also (int*) and it is set to point to a single integer i.
  • 135. Arrays and Pointers ● So what's the difference between intArray and intPtr? Not much as far as the compiler is concerned. ● They are both just (int*) pointers, and the compiler is perfectly happy to apply the [ ] or + syntax to either. ● It's the programmer's responsibility to ensure that the elements referred to by a [] or + operation really are there. ● Really its' just the same old rule that C doesn't do any bounds checking. ● C thinks of the single integer i as just a sort of degenerate array of size 1.
  • 137. Array Names Are Const ● One subtle distinction between an array and a pointer, is that the pointer which represents the base address of an array cannot be changed in the code. ● The array base address behaves like a const pointer. ● The constraint applies to the name of the array where it is declared in the code.
  • 139. Array parameters are passed as pointers ● The following two definitions of foo look different, but to the compiler they mean exactly the same thing.
  • 140. Heap Memory ● C gives programmers the standard sort of facilities to allocate and deallocate dynamic heap memory. ● A word of warning: writing programs which manage their heap memory is notoriously difficult. ● This partly explains the great popularity of languages such as Java and Perl which handle heap management automatically. ● These languages take over a task which has proven to be extremely difficult for the programmer.
  • 141. Heap Memory ● C provides access to the heap features through library functions which any C code can call. ● The prototypes for these functions are in the file <stdlib.h>, so any code which wants to call these must #include that header file.
  • 142. void* malloc(size_t size) ● Request a contiguous block of memory of the given size in the heap. ● malloc() returns a pointer to the heap block or NULL if the request could not be satisfied. ● The type size_t is essentially an unsigned long which indicates how large a block the caller would like measured in bytes. ● Because the block pointer returned by malloc() is a void* (i.e. it makes no claim about the type of its pointee), a cast will probably be required when storing the void* pointer into a regular typed pointer.
  • 143. void free(void* block) ● The mirror image of malloc() -- free takes a pointer to a heap block earlier allocated by malloc() and returns that block to the heap for re-use. ● After the free(), the client should not access any part of the block or assume that the block is valid memory. ● The block should not be freed a second time.
  • 144. void* realloc(void* block, size_t size) ● Take an existing heap block and try to relocate it to a heap block of the given size which may be larger or smaller than the original size of the block. ● Returns a pointer to the new block, or NULL if the relocation was unsuccessful. ● Remember to catch and examine the return value of realloc() -- it is a common error to continue to use the old block pointer. ● Realloc() takes care of moving the bytes from the old block to the new block. ● Realloc() exists because it can be implemented using low-level features which make it more efficient than C code the client could write.
  • 145. Memory Management ● All of a program's memory is deallocated automatically when the it exits, so a program only needs to use free() during execution if it is important for the program to recycle its memory while it runs -- typically because it uses a lot of memory or because it runs for a long time. ● The pointer passed to free() must be exactly the pointer which was originally returned by malloc() or realloc(), not just a pointer into somewhere within the heap block.
  • 146. Dynamic Arrays ● Since arrays are just contiguous areas of bytes, you can allocate your own arrays in the heap using malloc(). ● The following code allocates two arrays of 1000 ints-- one in the stack the usual "local" way, and one in the heap using malloc().
  • 147. Advantages of being in the heap ● Size (in this case 1000) can be defined at run time. Not so for an array like "a". ● The array will exist until it is explicitly deallocated with a call to free(). ● You can change the size of the array at will at run time using realloc(). ● The following changes the size of the array to 2000. Realloc() takes care of copying over the old elements.
  • 148. Disadvantages of Being in The Heap ● You have to remember to allocate the array, and you have to get it right. ● You have to remember to deallocate it exactly once when you are done with it, and you have to get that right. ● The above two disadvantages have the same basic profile: if you get them wrong, your code still looks right. It compiles fine. It even runs for small cases, but for some input cases it just crashes unexpectedly because random memory is getting overwritten somewhere like the smiley face. ● This sort of "random memory smasher" bug can be a real ordeal to track down.
  • 149. Dynamic Strings ● The dynamic allocation of arrays works very well for allocating strings in the heap. ● The advantage of heap allocating a string is that the heap block can be just big enough to store the actual number of characters in the string. ● The common local variable technique such as char string[1000]; allocates way too much space most of the time, wasting the unused bytes, and yet fails if the string ever gets bigger than the variable's fixed size.
  • 152. stdio.h ● stdio.h is a very common file to #include -- it includes functions to print and read strings from files and to open and close files in the file system.
  • 164. END
  • 166. Defensive Programmer Strategies ● Never Trust Input - Never trust the data you are given and always validate it. ● Prevent Errors - If an error is possible, no matter how probable, try to prevent it. ● Fail Early And Openly - Fail early, cleanly, and openly, stating what happened, where and how to fix it. ● Document Assumptions - Clearly state the pre-conditions, post-conditions, and invariants.
  • 167. Defensive Programmer Strategies ● Prevention Over Documentation - Do not do with documentation, that which can be done with code or avoided completely. ● Automate Everything - Automate everything, especially testing. ● Simplify And Clarify - Always simplify the code to the smallest, cleanest form that works without sacrificing safety. ● Question Authority - Do not blindly follow or reject rules.