Computer Systems Organization
Sessions 5-9 Main Theme C Programming
Dr. Jean-Claude Franchitti
New York University
Computer Science Department Courant Institute of Mathematical Sciences
Presentation material partially based on Lewis Girod CENS Ssems Labs C Torial
Slides copyright © 2020
1
Agenda
1
2
3
Instructor and Course Introduction C Programming
Summary and Conclusion
2
What is the class about?
Course description and syllabus:
» http://www.nyu.edu/classes/jcf/CSCI-UA.0201-005/
» http://www.cs.nyu.edu/courses/fall20/CSCI-UA.0201-005/ » Accessible via NYU Classes
Textbooks:
» Comper Ssems: A Programmers Perspecie
Randal Brant and Daid OHallaron Pearson
ISBN-10: 013409266X, ISBN-13: 978-0134092669, 3rd Edition (03/2015) » Recommended:
» The C Programmning Language, Brian W Kernighan and Dennis Ritchie
Prentice Hall; ISBN-10: 0131103628; ISBN-13: 978-01311103627, 2nd Edition (04/88)
3
Icons / Metaphors
Information
Common Realization Knowledge/Competency Pattern Governance
Alignment
Solution Approach
4
4
C Programming: Detailed Agenda
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
5
Agenda
1
2
3
Instructor and Course Introduction C Programming
Summary and Conclusion
6
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
7
Origin of the C Programming Language
Brian Kernighan Dennis Ritchie
In 1972 Dennis Ritchie at Bell Labs writes C and in 1978 the publication of The C Programming Language by Kernighan & Ritchie caused a revolution in the computing world.
8
Why C?
Mainly because it produces code that runs nearly as fast as code written in assembly language. Some examples of the use of C might be:
» Operating Systems
» Language Compilers » Assemblers
» Text Editors
» Print Spoolers
» Network Drivers
» Language Interpreters » Utilities
9
Interesting Opinion About C
You might never use it professionally, but it contains a lifetime of lessons. And the hardest problems, the ones that the top engineers are asked to solve, will sooner or later hit some foundational C code.
Here are some things that are written in C:
The Java virtual machine is written in ANSI C
Linux is written in C (and some assembly, but mostly C)
Python is written in C
Mac OS X kernel is written in C
Windows is written in C and C++
The Oracle database is written in C and C++
Cisco routers, those things which connect the Internet, also C
Name anything that is foundational, complex, and performance critical. It was written in C, with a sprinkling of assembly thrown in.
C will make you a better Java programmer. You’ll know when the JVM is using the stack and when it’s using the heap, and what that means. You’ll have a more intuitive sense of what garbage collection does. You’ll have a better sense of the relative performance cost of objects versus primitives.
https://www.quora.com/Financially-speaking-which-computer-languages-can-earn-the-most-for-the-programmer/answer/Carter-Page-1
10
Your first goal: Learn C!
Resources
» KR book: The C Programming Langage
» These lectures
» Additional online resources ( some links on the course website)
Learning a Programming Language
» The best way to learn is to write programs
11
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
12
Programming Cycle
high level language
low level language
13
Writing and Running Programs
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(Hello World\n);
return 0; }
1. Write text of program (source code) using a text editor, save as text file e.g. my_program.c
2. Run the compiler, assembler, and linker to convert program from sorce to an executable or binar:
$ gcc Wall g o my_program my_program.c
3-Compiler gives errors and warnings; edit source file, fix it, and re-compile
Run it and see if it works $ ./my_program
Hello World
$
14
Compiling Programs
$ gcc Wall g o my_program my_program.c
generate all warnings
name the generated executable (default: a.out)
keep debugging information
one or more C files
15
About C
Procedural language
» Functions calling each other, starting with main().
Case-sensitive
16
C Syntax and Hello World
#inclde inserts another file. .h files are called header files. The contain stff needed to interface to libraries and code in other .c files.
This is a comment. The compiler ignores this.
The main() function is always where your program starts running.
Blocks of code are marked by
#include
/* The simplest C Program */
int main(int argc, char **argv)
ur
mum Num ofavg
{
printf(Hello World\n);
return 0;
}
Retrn 0 from this fnction
Print ot a message. \n means ne line.
17
Preprocessing
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(Hello World\n);
return 0; }
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int
__extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ;
extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ;
int main(int argc, char **argv)
{
printf(Hello World\n);
return 0; }
Compile
my_program
long long int __dev_t; int __uid_t;
int __gid_t;
long int __ino_t;
long long int __ino64_t;
__off_t;
Preprocess
18
Preprocessing (continued)
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(Hello World\n);
return 0; }
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int
__extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ;
extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ;
int main(int argc, char **argv)
{
printf(Hello World\n);
return 0; }
Preprocess
long long int __dev_t; int __uid_t;
int __gid_t;
long int __ino_t;
long long int __ino64_t;
__off_t;
Dring preprocessing, the sorce code is epanded into a larger form that is simpler for the compiler to nderstand. An line that starts ith # is a line that is interpreted by the Preprocessor.
Inclde files are pasted in (#inclde)
Macros are epanded (#define)
Comments are stripped out ( /* */ , // )
Continued lines (i.e. very long lines ) are joined ( \ )
Compile
my_program
19
Compiling
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(Hello World\n);
return 0; }
__extension__ typedef long int
__extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ;
extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ;
int main(int argc, char **argv)
{
printf(Hello World\n);
return 0; }
my_program
Compile
Preprocess
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned int __nlink_t;
long long int __dev_t; int __uid_t;
int __gid_t;
long int __ino_t;
long long int __ino64_t;
__off_t;
The compiler then converts the resulting text into binary code the CPU can run directly.
The compilation process involves really several steps:
Compiler: high level language assembly
Assembler: assembly machine code
Linker: links all machine code files and needed
libraries into one executable file.
When you type gcc you really invoke the
compiler, assembler, and linker.
20
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
21
What is Memor?
It is like a big table of numbered slots.
Each slot stores a byte.
Addr
0
1
Value
The slot number ( its index) is its Address.
One byte Value can be stored in each slot.
2
3
4
Some logical data ales span more than one slot, like the character string Hello\n
5
6
A Type names a logical meaning to a span of memory. Some simple types are:
a single character (1 slot)
char
char [10]
int signed 4 byte integer float
an array of 10 characters 4 byte floating point
7
8
9
H (72)
e (101)
l (108)
l (108)
o (111)
\n (10)
10
11
12
\0 (0)
22
What is a Variable?
A Variable names a place in memory where you store a Value of a certain Type.
Addr
Value
You first Define a variable by giving it a name and specifying the type, and optionally an initial value
Initial value of x is undefined
char x;
=e;
char
Initial value
The compiler puts them somewhere in memory.
x
y
Symbol
0
1
2
3
4
5
6
7
9
?
e (101)
8
Name
10
Type is single character (char)
11
12
23
Multi-byte Variables
Symbol
Addr
Value
0
1
2
3
x
4
?
y
5
e (101)
6
World boundaries
7
z
8
4
9
3
10
2
11
1
12
Different types consume different amounts of memory. Most architectures store data on ord bondaries, or een mltiples of the size of a primitive data type (int, char)
char x;
char =e;
int z = 0x01020304;
0x means the constant is written in hex
padding
An int consumes 4 bytes
24
Scope
Every Variable is Defined within some scope. A Variable cannot be referenced from outside of that scope.
void p(char x)
{
char y;
char z;
}
char z;
void q(char a)
{
char b;
{
char c;
}
char d;
}
Scopes are defined with curly braces { }.
The scope of Function Arguments is the complete body of the function.
The scope of Variables defined inside a function starts at the definition and ends at the closing brace of the containing block
The scope of Variables defined outside a function starts at the definition and ends at the end of the file. Called Global Vars.
25
Statements
No that e kno abot ariables, lets combine them to form expressions!
Expression
X = 2 * Y + Z;
Statement
26
How Expressions Are Evaluated?
Expressions combine Values using Operators, according to precedence.
1+2*2 1+4 5 (1+2)*2 3*2 6
Comparison operators are used to compare values.
In C: 0 means false, and any other value means tre.
int x=4;
(x < 5)
(x < 4)
((x < 5) || (x < 4))
(4 < 5)
27
Operators Precedence
Highest to lowest ()
*, /, % +, –
When in doubt, use parenthesis.
With operators of the same precedence, expressions
are evaluated left to right.
28
Comparison and Mathematical Operators
== equal to
< less than
<= less than or equal
> greater than
>= greater than or equal
!= not equal
&& logical and
|| logical or
! logical not
+ plus
– minus * mult
/ divide % modulo
& bitwise and
| bitwise or
^ bitwise xor
~ bitwise not
<< shift left
>> shift right
Beware in division:
If second argument is integer, the result will be integer (rounded):
5 / 100 whereas 5 / 10.00.5
Dont confse & and &&
1 & 20 whereas 1 && 2
Assignment Operators
x=y assign y to x x++ post-increment x
x+=yassign(x+y)tox
++x x– –x
pre-increment x
post-decrement x
pre-decrement x
x -= y assign (x-y)
x *= y assign (x*y)
x /= y assign (x/y)
x %= y assign (x%y)
int x=5;
int y;
y = x++; /*x==6,y==5*/
tox tox tox tox
Note the difference between ++x and x++:
int x=5;
int y;
y= ++x;
/* x == 6, y == 6 */
Dont confse = and ==
int x=5;
if (x==6) /* false */ {{
/* … */ /* x is now 6 */ }}
/* x is still 5 */ /* … */
int x=5;
if (x=6) /* always
true */
30
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
31
What is a Function?
A Function is a series of instructions to run.
You pass Arguments to a function and it returns a Value.
main() is a Fnction. Its onl special becase it alas gets called first when you run your program.
Return type, or void
#include
/* The simplest C Program */
main(int argc, char **argv)
{
}
Function Arguments
int
printf(Hello World\n);
return 0;
Returning a value
32
printf() is jst another fnction, like main(). Its defined for o in a library, a collection of functions you can call from your program.
A More Complex Program: pow
#include
float pow(float x, unsigned int exp)
{
/* base case */
if (exp == 0) {
return 1.0; }
/* recursive case */
return x*pow(x, exp 1);
}
int main(int argc, char **argv)
{
float p;
p = pow(10.0, 5);
printf(p = %f\n, p);
return 0;
}
Tracing po():
What does pow(5,0) do? What about pow(5,1)?
33
The Stack
Recall scoping. If a ariable is alid ithin the scope of a fnction, hat happens hen you call that function recursively? Is there more than one exp?
#include
#include
float pow(float x, unsigned int exp)
{
/* base case */
if (exp == 0) {
return 1.0; }
/* recursive case */
return x*pow(x, exp 1);
}
int main(int argc, char **argv)
{
float p;
printf(p = %f\n, p);
return 0; }
Yes. Each fnction call allocates a stack frame here Variables ithin that fnctions scope will reside.
float x
5.0
uint32_t exp
0
Return 1.0
float x
5.0
uint32_t exp
1
Return 5.0
int argc
1
char **argv
0x2342
float p
5u.n0defined
p = pow(5.0, 1);
Stack, with all its stack frames, resides in memory.
Grows
34
Can a function modify its arguments?
What if we wanted to implement a function pow_assign() that modified its argument, so that these are equivalent:
float p = 2.0;
/* p is 2.0 here */
p = pow(p, 5);
/* p is 32.0 here */
float p = 2.0;
/* p is 2.0 here */
pow_assign(p, 5);
/* p is 32.0 here */
Would this work?
void pow_assign(float x, uint exp)
{
float result=1.0;
int i;
for (i=0; (i < exp); i++) {
result = result * x;
}
x = result; }
Pointers: A very powerful but dangerous concept!
35
NO!
Remember the stack!
void pow_assign(float x, unsigned int exp)
{
float result=1.0;
int i;
for (i=0; (i < exp); i++) {
result = result * x;
}
x = result; }
main() {
float p=2.0;
pow_assign(p, 5);
}
In C, all arguments are passed as values.
But, what if the argument is the address of a variable?
float x
32.20.0
uint32_t exp
5
float result
31.20.0
float p
2.0
Grows
36
Passing Addresses
Symbol
Addr
Value
0
1
2
3
char x
4
H (72)
char y
5
e (101)
6
7
8
9
10
11
12
address of x4
memory content at address 472
37
Pointers
This is eactl ho pointers ork.
address of x: &x
if y is an address, the }
content of the memory at that address *y
/* y is 101 */
/* i.e. f(5) */
A pointer tpe: pointer to char
void f(char * p)
{
*p = *p - 32;
char y = 101;
f(&y);
/* y is now 101-32 = 69 */
Pointers are used in C for many other purposes: Passing large objects without copying them
Accessing dynamically allocated memory
Referring to functions
38
Pointer Validity
A Valid pointer is one that points to memory that your program controls. Using invalid pointers will cause non-deterministic behavior, and will often cause Linux to kill your process (SEGV or Segmentation Fault).
There are two general causes for these errors:
Program errors that set the pointer value to a strange number
Use of a pointer that was at one time valid, but later became invalid
Will ptr be valid or invalid?
char * get_pointer()
{
char x=0;
return &x; }
main() {
char * ptr = get_pointer();
*ptr = 12; /* valid? */
}
39
Answer: Invalid!
A pointer to a variable allocated on the stack becomes invalid when that ariable goes ot of scope and the stack frame is popped. The pointer will point to an area of the memory that may later get reused and rewritten.
char * get_pointer()
{
char x=0;
return &x; }
main() {
char * ptr = get_pointer();
*ptr = 12; /* valid? */
other_function();
}
But now, ptr points to a location thats no longer in use, and will be reused the next time a function is called!
101
cichnatraxvxerage
Return 101
014256603
100
char * ptr
1?01
Grows
40
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
41
The for loop
The for loop is jst shorthand for this hile loop strctre.
float pow(float x, unsigned int exp)
{
float result=1.0; int i;
i=0;
while {
result = result * x;
}
return result;
}
int main(int argc, char **argv)
{
float p;
p = pow(10.0, 5);
printf(p = %f\n, p);
return 0;
}
float pow(float x, unsigned int exp)
{
float result=1.0;
int i;
for {
result = result * x;
}
return result;
}
int main(int argc, char **argv)
{
float p;
p = pow(10.0, 5);
printf(p = %f\n, p);
return 0;
}
(i=0;
(i < exp);
i++)
(i < exp)
i++;
42
When to Use?
Different Loop-constructs
while
do-while for
Conditions
if-else
switch-case
43
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
44
More on Types
No that e kno pointers (I hope!), lets go back to tpes
Wee seen a fe tpes at this point: char, int, float, char *
Types are important because:
They allow your program to impose logical structure on memory The help the compiler tell hen ore making a mistake
In the next slides we will discuss:
How to create logical layouts of different types (structs) How to use arrays
How to parse C type names (there is a logic to it!)
How to create new types using typedef
45
Structures
a collection of related data items
possibly of different types
defined using the keyword struct
The members of a struct type variable are accessed with the dot (.) operator:
46
strct Basics
Definition of a structure:
struct
…
};
Each identifier defines a member of the structure.
47
strct Basics (contined)
Example: struct Address {
Example
main() {
struct Address adrs;
adrs.zip = 10012; }
int zip;
char street[50];
char city[20];
};
Example of initializing a structure
struct Address adrs = 10012, Mece, Ne Yok;
48
Arrays
Arrays in C are composed of a particular type, laid out in memory in a repeating pattern. Array elements are accessed by stepping forward in memory from the base of the array by a multiple of the element size.
Brackets specify the count of elements. Initial values optionally set in braces.
Arrays in C are 0-indexed (here, 0..9)
[3] == *(+3) == t (NOT s!)
/* define an array of 5 chars */
char [5] = t,e,s,t,\0;
/* accessing element 0 */
[0] = T;
/* pointer arithmetic to get elt 3 */
char elt3 = *(x+3); /* x[3] */
/* x[0] evaluates to the first element;
* x evaluates to the address of the
* first element, or &(x[0]) */
Symbol
Addr
Value
char x [0]
100
t
char x [1]
101
e
char x [2]
102
s
char x [3]
103
t
char x [4]
104
\0
49
Pointers and Arrays in C
An array name by itself is an address, or pointer in C.
When an array is declared, the compiler allocates sufficient space beginning with some base address to accommodate every element in the array.
The base address of the array is the address of the first element in the array (index position 0).
»Example: intnum[10];
&num[0] is the same as num
50
Pointers and Arrays in C (continued)
Suppose we define the following array and pointer: int a[100]; int *ptr;
Assume that the system allocates memory bytes 400, 404, 408, …, 796 to the array. Integers are allocated 32 bits = 4 bytes.
» The two statements: ptr = a; and ptr = &a[0]; are equivalent and would assign the value of 400 to ptr.
Pointer arithmetic provides an alternative to array indexing in C.
» The two statements: ptr = a + 1; and ptr = &a[1]; are equivalent and would assign the value of 404 to ptr.
51
Pointers and Arrays in C (continued)
Assuming the elements of the array of integer have been assigned values, the following code would sum the elements of the array:
Ca b aEb
sum = 0;
for (ptr = a; ptr < &a[100]; ++ptr) Atb
sum += *ptr;
Here is another way to sum the array:
sum = 0;
for (i = 0; i < 100; ++i)
sum += *(a + i);
Atb
a[b] in C is just syntactic sugar for
*(a + b)
52
Strings
Series of characters treated as a single unit
Can include letters, digits, and certain special
characters (*, /, $)
String literal (string constant) - written in double quotes
» "Hello"
Strings are arrays of characters
Each character is represented in numerical code called ASCII code.
Example:
» char name[] = test;
» address of the above string can be expressed in two ways:
&name[0] name
53
ASCII code
54
Strings
String declarations
» Declare as a character array or a variable of type char * char color[] = "blue";
char *colorPtr = "blue";
» Remember that strings represented as character arrays end with '\0'
• color has 5 elements
Inputting strings » Use scanf
char word[10];
scanf("%s", word);
Copies input into word[], which does not need & (because a string is a pointer)
» Remember to leave space for '\0'
55
Character Handling Library
In
Prototype Description
int isdigit( int c )
int isalpha( int c )
int isalnum( int c )
int isxdigit( int c )
int islower( int c )
int isupper( int c )
int tolower( int c )
int toupper( int c )
int isspace( int c )
int iscntrl( int c )
int ispunct( int c )
Returns true if c is a digit and false otherwise. Returns true if c is a letter and false otherwise.
Returns true if c is a digit or a letter and false otherwise.
Returns true if c is a hexadecimal digit character and false otherwise.
Returns true if c is a lowercase letter and false otherwise.
Returns true if c is an uppercase letter; false otherwise.
If c is an uppercase letter, tolower returns c as a lowercase letter. Otherwise, tolower returns the argument unchanged.
If c is a lowercase letter, toupper returns c as an uppercase letter. Otherwise, toupper returns the argument unchanged.
Returns true if c is a white-space character—newline (‘\n’), space (‘ ‘), form feed (‘\f’), carriage return (‘\r’), horizontal tab (‘\t’), or vertical tab (‘\v’)—and false otherwise
Returns true if c is a control character and false otherwise.
Returns true if c is a printing character other than a space, a digit, or a letter and false
otherwise.
Returns true value if c is a printing character including space (‘ ‘) and false otherwise.
Returns true if c is a printing character other than space (‘ ‘) and false otherwise. Each function receives a character (an int) or EOF as an argument
int isprint( int c )
int isgraph( int c )
56
String Conversion Functions
Conversion functions
» In
» Convert strings of digits to integer and floating-point values
Prototype
Description
double atof( const char *nPtr )
Converts the string nPtr to double.
int atoi( const char *nPtr )
Converts the string nPtr to int.
long atol( const char *nPtr )
Converts the string nPtr to long int.
double strtod( const char *nPtr, char **endPtr )
Converts the string nPtr to double.
long strtol( const char *nPtr, char **endPtr, int base )
Converts the string nPtr to long.
unsigned long strtoul(const char *nPtr, char **endPtr, int base)
Converts the string nPtr to unsigned long.
57
String Manipulation Functions
In
String handling library has functions to » Manipulate string data
» Search strings
» Determine string length
Function prototype
Function description
char *strcpy( char *s1,
const char *s2 )
Copies string s2 into array s1. The value of s1 is returned.
char *strncpy( char *s1,
const char *s2, size_t n )
Copies at most n characters of string s2 into array s1. The value of s1 is returned.
char *strcat( char *s1,
const char *s2 )
Appends string s2 to array s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned.
char *strncat( char *s1,
const char *s2, size_t n )
Appends at most n characters of string s2 to array s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned.
58
String Manipulation Functions (continued)
int strcmp ( const char * str1, const char * str2 )
return value
<0
0
>0
indicates
the first character that does not match has a lower value in ptr1 than in ptr2
the contents of both strings are equal
the first character that does not match has a greater value in ptr1 than in ptr2
59
How to Parse C Types
C type names are parsed by starting at the name and working outwards according to the rules of precedence:
x is
an array of
pointers to
int
int *x[10];
int (*x)[10];
x is
a pointer to
an array of
int
60
Using typedef
At this point we have seen a few basic types, arrays, pointer types, and strctres. So far ee glossed oer ho tpes are named.
int x;
int *y;
int z[10];
/* int;
/* pointer to int;
/* array of ints;
*/ typedef int T;
*/ typedef int *U;
*/ typedef int V[10];
typedef defines a new type
Now:
Tx; isthesameasintx; U y; is the same as int * y; and so on
61
Dynamic Memory Allocation
What if o ant to allocate an arra of N elements, and o dont kno N beforehand?
So far all of our examples have allocated variables statically by defining them in our program. This allocates them in the stack.
But, what if we want to allocate variables based on user input or other dynamic inputs, at run-time? This requires dynamic allocation.
sizeof() reports the size of a type in bytes
int * alloc_ints(size_t requested_count)
{
int * big_array;
big_array = (int *)calloc(requested_count, sizeof(int));
if (big_array == NULL) {
printf(cant allocate %d ints: %m\n, requested_count);
return NULL;
}
/* now big_array[0] .. big_array[requested_count-1] are
* valid and zeroed. */
return big_array;
}
calloc(N, K) allocates memory for N elements of size k
Retrns NULL if cant alloc
Its OK to retrn this pointer. It will remain valid until it is freed with free()
62
Dynamic Memory Allocation (continued)
void *malloc (size_t size);
void* calloc (size_t num, size_t size);
void free (void* ptr);
Unary operator sizeof is used to determine the size in bytes of any data type. Examples:
» sizeof(double) » sizeof(int)
63
Caveats with Dynamic Memory
Dynamic memory is useful. But it has several caveats:
Whereas the stack is automatically reclaimed, dynamic allocations must be tracked and free()d hen the are no longer needed. With eer allocation, be sure to plan how that memory will get freed. Losing track of memor is called a memor leak.
Whereas the compiler enforces that reclaimed stack space can no longer be reached, it is easy to accidentally keep a pointer to dynamic memory that has been freed. Whenever you free memory you must be certain that you will not try to use it again. It is safest to erase any pointers to it.
Because dynamic memory always uses pointers, there is generally no way for the compiler to statically verify usage of dynamic memory. This means that errors that are detectable with static allocation are not with dynamic
64
Pointers and Structures
Assume we have a structure called node: struct node{
int number;
struct node * link; };
Inserting a node in a linked list of nodes (with head pointer called pHead and pPre initially points to the node just before the insertion point):
struct node *pNew;
pNew = (struct node *) malloc(sizeof(struct node)); pNew -> data = item;
if (pPre == NULL){
//add before first node or to an empty list pNew -> next = pHead;
pHead = pNew; }
else {
//add in the middle or at the end
pNew -> next = pPre -> next; // Ppre points to previous node
pPre -> next = pNew; }
number
link
65
Pointers and Structures
pNew
Before
55
124
pPre
pNew
After
55
124
pPre
64
64
66
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
67
I/O
reading from:
» standard input (usually the keyboard) » file
writing to:
» standard output (usually the screen) » file
A library of functions is supplied to perform these operations.
The I/O library functions are listed the header file
68
Writing to stdout
printf ( ) ;
This function provides for formatted output to the screen. The syntax is:
printf ( format, ar1, ar2, ) ;
The format incldes a listing of the data tpes of the variables to be output and, optionally, some
text and control character(s)
Example:
float a ; int b ;
scanf ( %f%d, &a, &b ) ;
printf ( Yo entered %f and %d \n, a, b ) ;
69
Formatted Output with printf
Format Conversion Specifiers (This list is not exhaustive):
d — displays a decimal (base 10) integer
l — used with other specifiers to indicate a long f — displays a floating point value
x — displays a number hexadecimal format
c — displays a single character
s — displays a string of characters
70
Reading from stdin
scanf ( ) ;
This function provides for formatted input from the keyboard. The syntax is:
scanf ( format , &ar1, &ar2, ) ;
The format is a listing of the data tpes of the ariables to be input and the & in front of each variable name tells the system WHERE to store the value that is input; it provides the address for the variable
Example:
float a; int b;
scanf (%f%d, &a, &b);
71
Files
In C, each file is simply a sequential stream of bytes.
C imposes no structure on a file.
Steps to deal with files
» open a file
» check that the open was successful » read/write to a file
» close a file
72
First step
Declaration:
FILE *fptr1, *fptr2 ;
73
Opening Files
The statement:
fptr1 = fopen ( filename”, “r” ) ;
would open the file filename for input (reading).
» r: read
» w: write
» a: append
» there are some more
74
Testing for Successful Open
If the file was not able to be opened, then the value returned by the fopen routine is NULL.
For example, let’s assume that the file mydata does not exist. Then:
FILE *fptr1 ;
fptr1 = fopen ( “myfile”, “r”) ; if (fptr1 == NULL)
{
printf (“File ‘mydata’ did not open.\n”) ; }
75
Reading From Files
In the following segment of C language code:
int a, b ;
FILE *fptr1, *fptr2 ;
fptr1 = fopen ( “mydata”, “r” ) ; fscanf ( fptr1, “%d%d”, &a, &b) ;
the fscanf function would read values from the file “pointed” to by fptr1 and assign those values to a and b.
76
End of File
The end-of-file indicator informs the program when there are no more data (no more bytes) to be processed.
There are a number of ways to test for the end-of-file condition. One is to use the feof function which returns a true or false condition:
fscanf (fptr1, “%d”, &var) ; if ( feof (fptr1) )
{
printf (“End-of-file encountered.\n);
}
Another (better) way of testing EOF: while(fscanf(fp,”%d “, ¤t) == 1) {
}
77
Writing To Files
int a = 5, b = 30;
FILE *fptr2 ;
fptr2 = fopen ( filename”, “” ) ; fprintf ( fptr2, “%d %d\n”, a, b ) ;
the fprintf functions would write the values stored in a and b to the file “pointed” to by fptr2.
78
Closing Files
fclose ( fptr1 ) ;
Once the files are open, they stay open until you close them or end the program (which will close all files.)
79
C Programming
Overview
From Writing to Executing Programs Memory, Variables, and Expressions Functions and Pointers
Statements
Structures, Arrays, and Strings
File I/O
Macros
Summary
80
Macros
Macros can be a useful way to customize your interface to C and make your code easier to read and less redundant. However, when possible, use a static inline function instead.
Format is very simple:
#define identifier replacement-text
Example:
#define NUM 10
Notes:
Each occurrence of NUM in your code will be replaced by 10.
This happens by the preprocessor before compilation.
In the rest of the code you cannot change NUM.
We can take this idea further; instead of defining a constant, we define operations 81
Macros
Sophisticated Example
#define CIRCLE_AREA( x ) ( PI * ( x ) * ( x ) ) area = CIRCLE_AREA( 4 );
becomes
area = ( 3.14159 * ( 4 ) * ( 4 ) );
See how parentheses are used. Always enclose parameters in ().
More sophisticated example: #defineRECTANGLE_AREA(x,y) ((x)*(y)) rectArea = RECTANGLE_AREA( a + 4, b + 7 );
becomes
rectArea = ( ( a + 4 ) * ( b + 7 ) );
82
Macros: More examples
#defineforeover for(;;)
#define max(i,j) ((i) > (j) ? (i) : (j))
#define SWAP(a, b) { \ a^=b; \
b ^= a; \
a ^= b; \ }
83
C Programming: Summary
We took a quick look at the different features of C
To get deeper look: check online tutorials. You will find C Programming Resources on the course webpage
To become an epert: rite code rite code rite code
84
Agenda
1
2
3
Instructor and Course Introduction C Programming
Summary and Conclusion
85
Assignments & Readings
Readings
» Slides and Handouts posted on the course web site
» Recommended Textbook: The C Programming Language (K&R) » C Programming Resources
Assignment #1 / Lab #1
» Lab #1 TBD in later sessions
Development environment
» C development environment setup
» Create GitHub account
» See Announcements regarding invitation to join the course GitHub and related instructions to access the materials for the course and recitations (including private versions of them that you will work on during recitations)
86
Next Session: Machine-Level Programming
87
Questions, Comments, Discussions ?
88