The C Programming Language
• Currently one of the most commonly-used
programming languages
• “High-level assembly”
• Small but powerful
• Very portable:compiler exists for virtually
every processor
Hello World in C
#include <stdio.h>
Include a header file that
lets you use I/O related C
functions
Similar to Java’s import
int main() {
printf(“Hello, world!\n”);
return 0;
}
Why is C Dangerous
• C’s small feature set is an advantage and
disadvantage
• The price of C’s flexibility
• C does not, in general, try to protect a
programmer from his/her mistakes
Commonly used header files
• stdio.h
 Standard C library for I/O
• stdlib.h
 General purpose standard C library
• string.h
• math.h
 sqrt, pow, sin, cos
• ctype.h
 a bunch of very useful character functions: isdigit,
isalpha, isalnum, isspace, islower,
isupper, tolower/toupper
• time.h
Hello World in C
#include <stdio.h>
Program mostly a
collection of functions
“main” function special: the
entry point
“int” qualifier indicates
function returns an integer
int main() {
printf(“Hello, world!\n”);
return 0;
}
I/O performed by a library function
C is Function-oriented
• C came before OO concept
• C program resemble java programs with a
single giant class
• C is procedural
 Program organization and modularization is
achieved through function design
 Carefully plan your function return type and
parameter list
 Write small functions!
Functions
• Function: Unit of operation
 A series of statements grouped together
• Must have the main function
• C functions are stand-alone
• Most programs contain multiple function
definitions
 Must be declared/defined before being used
Functions
int menuChoice() {
int choice;
printf(
"1. Yes\n"
"0. No\n"
"Enter the number corresponding to your choice: ");
scanf("%d", &choice);
return choice;
}
int main() {
int choice;
printf("=== Expert System ===\n");
printf("Question1: ...\n");
choice = menuChoice();
if (choice == 1) { /* yes */
printf("Question 2: ...\n");
choice = menuChoice();
/* skipped */
Function parameters
void km_mile_conv(int choice) {
int input;
printf("Enter a %s value: ", choice==1?"mile":"km");
scanf("%lf", &input);
if (choice == 1)
printf("%f mile(s) = %f km(s)\n", input, input*1.6);
else
printf("%f km(s) = %f mile(s)\n", input, input/1.6);
}
int main() {
int choice;
scanf("%d", &choice);
switch (choice) {
case 1:
km_mile_conv(choice);
break;
caea 2:
km_mile_conv(choice);
break;
/* more cases */
}
}
Function Return and Parameters
• The syntax for C functions is the same as
Java methods
• void keyword can be omitted
void km_to_mile(void) {
}
mile_to_km() {
}
int main() {
int choice;
}
Function Prototype
• A prototype is a
function declaration
which includes the
return type and a list
of parameters
• A way to move
function definitions
after main
• Need not name
formal parameters
/* function prototypes */
double km2mile(double);
double mile2km(double);
int main() {
}
/* actual function definitions */
double km2mile(double k) {
}
double mile2km(double m) {
}
Function name overloading
• Does not exist in C
• Exists in C++
Local/Global Variables
• Variables declared inside a function are local
• Function arguments are local to the function
passed to
• A global variable is a variable declared
int x = 0;
outside of any function.
int f(int x) {
int x = 1;
• In a name conflict, the local
return x;
}
variable takes precedence
• When local variable shadows int main() {
int x;
x = f(2);
function parameter?
}
Scope of Global Variables
• The scope of a global variable starts at the
point of its definition.
• Globals should be used with caution
 If using globals at all, declare
them at the top.
int x;
int f() {
}
int y;
int g(){
}
int main() {
}
Keep main Uncluttered
• Your main function should consist mainly
of function calls
• One main input loop or conditional is okay
• Write your main and choose your function
name in such a way so that
 the main algorithm and program structure is
clearly represented
 the reader can get an idea how your program
works simply by glancing at your main
Program Organization
• #include and #define first
• Globals if any
• Function prototypes, unless included with
header file already
• int main()– putting your main before
all other functions makes it easier to read
• The rest of your function definitions
Data Types
• Integer types:
 different number of bits-different ranges
 char: ASCII character, typically 8 bits=1 byte
 range –127 to 128
 short: typically 16 bits
 int: 32 bits
 range ±2 billion
 long: typically 32 bits
 long long: (some compilers support) 64-bits
 Integer types can be preceded by unsigned which disables
representing negative numbers
 e.g. unsigned char
 range 0-255
Data Types
Floating-point types
 float 4 bytes
 double 8 bytes
 long double 12 bytes
 Floating point constants default to double unless
suffixed by f or l
 Examples: 0.67f, 123.45f, 1.2E-6f,
0.67, 123.45
Boolean
• C does not have type boolean—use int
• False is represented by 0
• Any expression evaluates to non-zero is
considered true
• True is typically represented by 1 however
Constants
• Integer
 const int year = 2002;
• Floating point number
 const double pi = 3.14159265;
• Constants are variables whose initial value
can not be changed.
• Comparable to static final
#define
• Often used to define constants
 #define TRUE 1 #define FALSE 0
 #define PI 3.14
 #define SIZE 20
• Anywhere PI occurs compiler replaces with 3.14
• Offers easy one-touch change of scale/size
• #define vs const
 The preprocessor directive uses no memory
Types and Casting
• Choose types carefully
• An arithmetic operation requires that the
two values are of the same type
• For an expression that involves two
different types, the compiler will cast the
smaller type to the larger type
• Example: 4 * 1.5 = 6.0
Mixing Data Types
• int values only  int
 4 / 2  2
 3 / 2  1
 int x = 3, y = 2;
x / y  1
• Involving a double value  double
 3.0 / 2  1.5
sizeof and Type Conversions
• sizeof(type)
 The sizeof operator returns the number of bytes
required to store the given type
Implicit conversions
 arithmetic
Explicit conversions
 assignment
 casting
int x;
 function parameters
x = (int) 4.0;
 function return type
Use of char (character)
• Basic operations
 Declaration: char c;
 Assignment: c = 'a';
 Reference: c = c + 1;
• Constants
 Single-quoted character (only one)
 Some special characters: '\n‘ (newline),
'\t' (tab), '\"' (double quote), '\''
(single quote), '\\' (backslash)
Characters are Integers
• A char type represents an integer value
• A single quoted character is called a
“character constant”.
• C characters use ASCII representation:
• 'A' = 65 … 'Z' = 'A' + 25 = 90
• 'a' = 97 … 'z' = 'a' + 25 = 122
• '0'!= 0 (48), '9' - '0' = 9
• Never make assumptions of char values
 Always write 'A' instead of 65
ASCII Table
American Standard Code
for Information Interchange
A standard way of
representing the alphabet,
numbers, and symbols
(in computers)
Output Functions
• Output characters
printf("Text message\n");
\n for new line
• Output an integer
int x = 100;
printf("Value = %d\n", x);
Output: Value = 100
Variations
• Output a floating-point number
double y = 1.23;
printf("Value = %f\n", y);
• Output multiple numbers
int x = 100;
double y = 1.23;
15 digits below decimal
(excluding trailing 0’s)
printf("x = %d, y = %f\n", x, y);
Output: x = 100, y = 1.230000
printf Summary
printf("
",
);
• Text containing special symbols
 %d for an integer
 %f for a floating-point number
 \n for a newline
• List of variables (or expressions)
 In the order correspoding to the % sequence
% Specification
• (most commonly used ones)
• %c
• %i
convert an int to an unsigned char and print
as a character
int, char (printas a signed decimal number)
• %d
same as above (d for decimal)
• %f
float, double (floating-point)
• %e
float, double (exponential, e.g., 1.5e3)
• %s
string pointed by a char*
Formatting
• Precision
• Width
%.#f
%#f, %#d
 Note: Entire width
Replace #
with digit(s)
• Various combinations of the above and
other options available
Formatting Example
%f
with 1.23456789 >1.234568<
%.10f with 1.23456789 >1.2345678900<
%.2f with 1.23456789 >1.23<
%d
with 12345 >12345<
%10d with 12345 >
12345<
%2d with 12345 >12345<
%f
with 1.23456789 >1.234568<
%8.2f with 1.23456789 >
1.23<
char Input/Output
• Input
 char getchar() receives/returns a character
 Built-in function
• Output
 printf with %c specification
 putchar()
int main() {
char c;
c = getchar();
printf("Character >%c< has the value %d.\n", c, c);
return 0;
}
scanf Function
scanf("
",
);
• Format string containing special symbols
 %d for int
 %f for float
 %lf for double
 %c for char
 \n for a newline
• List of variables (or expressions)
 In the order correspoding to the % sequence
scanf Function
• The function scanf is the input analog of
printf
• Each variable in the list MUST be prefixed
with an &.
• Ignores white spaces unless format string
contains %c
scanf Function
int main() {
int x;
printf("Enter a value:\n");
scanf("%d", &x);
printf("The value is %d.\n", x);
return 0;
}
scanf with multiple variables
int main() {
int x;
char c;
printf("Enter an int and a char:");
scanf("%d %c", &x, &c);
printf("The values are %d, %c.\n",
x, c);
return 0;
}
Control Structures
• Conditionals
 if-else
 switch
• Loops
 while
 for
 do-while
• SAME syntax as in Java
Assignment as Expression
• Assignment
 Assignments are expressions
 Evaluates to value being assigned
• Example
int x = 1, y = 2, z = 3;
x = (y = z);
3
3
3
evaluates to 3
evaluates to 3 (true)
if (x = 3) {
...
}
Complex Data Types
•
•
•
•
Pointers
Arrays
Strings
Structures
Variable and Address
• Variable = Storage in computer
memory
Memory
0
1
2
3
4
5
6
7
8
9
70
31
4
6
30
1
10
4
6
95
char
int
 Contains some value
 Must reside at a specific location
called address
 Basic unit – byte
 Imagine memory as a onedimensional array with addresses
30 201
as byte indices
31 12
 A variable consists of one or more
bytes, depending on its type (size) address value
Pointer – Reference
• A pointer (pointer variable) is a variable that
stores an address (like Java reference)
• Recall in Java, when one declares variables
of a class type, these are automatically
references.
• In C, pointers have special syntax and much
greater flexibility.
Address Operations in C
• Declaration of pointer variables
 The pointer declarator ‘*’
• Use of pointers
 The address of operator ‘&’
 The indirection operator ‘*’ – also known as
de-referencing a pointer
Pointer Declaration
• Syntax
 destinationType * varName;
• Must be declared with its associated type.
• Examples
 int *ptr1;
ptr1
A pointer to an int variable
 char *ptr2;
A pointer to a char variable
ptr2
will contain addresses
Pointers are NOT integers
• Although memory addresses are essentially
very large integers, pointers and integers are
not interchangeable.
• Pointers are not of the same type
• A pointer’s type depends on what it points to
 int *p1;
 char *p2;
Address of operator
0012FF88
ip
int i = 8;
int *ip;
ip = &i;
8
i (@0012FF88)
Pointer Assignment
• A pointer p points to x if x’s address is
stored in p
• Example
x
 int x = 1;
1
int *p, *q;
address = 567
p = &x;
p
567
q = p;
q
567
x
1
Interpreted as:
p
q
Pointer Assignment
• Example
 int x=1, y=2, *p, *q;
p = &x; q = &y;
q = p;
x
1
y
2
address = 567 address = 988
p
567
q
567
988
Indirection Operator
• Syntax
Note: ‘*’ in a declaration and ‘*’
in an expression are different.
int *p; int * p; int* p;
 * pointerVar
 Allows access to value of memory being pointed to
 Also called dereferencing
• Example
 int x = 1, *p;
p
p = &x;
printf("%d\n", *p);
*p refers to x; thus prints 1
x
1
Assignment Using Indirection Operator
• Allows access to a variable indirectly through
a pointer pointed to it.
• Example
 int x = 1, *p;
p
p = &x;
*p = 2;
p
printf("%d\n", x);
 *p is equivalent to x
x
1
x
2
The NULL Pointer
• A pointer that contains the address zero
known as the NULL pointer
 It points to nothing
 Many of the standard header files define NULL
• NULL means false in conditions
int *ip;
if (ip) {
/* ip is not NULL */
}
Pointer initialization
• DO NOT derefence an undefined/unitialized
pointer!
 It could be pointing anywhere.
Pass by Value
• Same as Java, modification to function
arguments during function execution has no
effect outside of function
void f(int x) {
x = x * x;
printf("%d", x);
}
The variable x in f gets
a copy of the value of
the variable x in main.
int main() {
int x = 3;
f(x);
printf("%d", x);
return 0;
}
Does not change the
value of x in main.
Pass by Value and Pointers
• All functions are pass-by-value in C
• Pass-by-value sill holds even if the
parameter is a pointer
 A copy of the pointer’s value is made – the
address stored in the pointer variable
 The copy is then a pointer pointing to the same
object as the original parameter
 Thus modifications via de-referencing the copy
STAYS.
Function Arguments
• x and y are copies of the original, and thus
a and b can not be altered.
void swap(int x, int y) {
int tmp;
tmp = x; x = y; y = tmp;
}
int main() {
int a = 1, b = 2;
swap(a, b);
return 0;
}
Wrong!
Pointers and Function Arguments
• Passing pointers – a and b are passed by
reference (the pointers themselves px and
py are still passed by value)
void swap(int *px, int *py) {
px
int tmp;
tmp = *px; *px = *py; *py = tmp; py
}
int main() {
int a = 1, b = 2;
swap(&a, &b);
return 0;
}
a
1
b
2
pointers to pointers
•
•
•
•
int i;
int *ip = &i;
int **iip = &ip; /* iip points to ip */
….
Generic pointers
• Sometimes necessary to store or pass pointers
without knowing what type they refer to—use the
generic pointer type: void *
int x;
int *xp
= &x;
void *vp = xp; /*okay, types are compatible*/
float *fp = ip; /*error */
• BUT, a generic pointer cannot be derefenced:
x = *vp; /*error */
Arrays
• Declaration – int a[5];
• Allocates a static
array
• Assignment – a[0] = 1;
• Reference – y = a[0];
0
1
2
element
a ?
a
k2
0
1
?
?
?
?
?
?
?
4
?
k1 index
Pointers and Arrays
• Arrays are contiguous
allocations of memory of
the size:
sizeof(elementType)
* numberOfElements
• Given the address of the
first byte, using the type
(size) of the elements one
can calculate addresses to
access other elements
pointer Memory
1
array
0
1
2
3
4
5
6
7
8
9
70
31
4
6
30
1
10
4
6
31
30
31
45
12
address value
Name of an Array
• The variable name of an array is also a
pointer to its first element.
a
a+1
a+8
a:
a[0] a[1]
• a == &a[0]
• a[0] == *a
a[8]
Pointer Arithmetic
• One can add/subtract an integer to/from a
pointer
• The pointer advances/retreats by that number
of elements (of the type being pointed to)
 a+i == &a[i]
 a[i] == *(a+i)
• Subtracting two pointers yields the number
of elements between them
Array name is a constant pointer
int arr[5];
int x;
int *s = &x;
arr = s; /*illegal */
Arrays as Arguments
• Arrays are passed
by reference
• Modifications stay
/* equivalent pointer alternative */
void init(int *a) {
int i;
for(i = 0;i<SIZE;i++){
*(a+i) = 0;
}
}
#define SIZE 10
void init(int a[]) {
int i;
for(i = 0;i<SIZE;i++){
a[i] = 0;
}
}
int main() {
int a[SIZE];
init(a);
return 0;
}
Character and String
• String is not a special type
 An array of characters
 Terminated with a special, null character
• Null character
 Its integer value is 0.
 Its C representation is '\0'.
• E.g., "abc" is internally
'a' 'b' 'c' '\0'
'\0'  '0' (zero)
'\0'  '\n'
Example
Little-o
Zero
Null character
Big-O
'O' 'o' '0' '\0'
Values:
79 111 48
0
Declaration/Initialization
• Declaration: char s[5];
• Initialization: char t[] = "abc";
Note: Strings cannot be assigned using '=' (except initialization).
char *s = t;
String Output
• Use printf with the %s specification
Prints character elements until \0 is reached
char s[] = "abc";
printf("%s", s);
/* prints abc */
printf("string: >%s<", s);
/* prints string: >abc< */
printf and Strings
int main() {
char s[] = "01234";
char *p;
p = s;
printf("%s\n", s);
printf("%s\n", p+1);
}
• %s: Displays
characters from
the specified
address until
'\0'
String Input with scanf
• Use the scanf function with %s
scanf("%s", buf);
• Matches the input string up to the first white
space or '\n' and stores it into buf
 Given input "CSE 123\n"
 scanf %s will have stored "CSE"
 Input buffer after scanf call: "123\n"
• No need for & in front of buf
String Input with gets
• The gets function
#define BUFLEN 200
allocate a large buffer
(e.g., more than 2 lines)
int main() {
char buf[BUFLEN];
gets(buf);
printf("string: >%s<", buf);
}
Notes
• gets deletes \n from input.
• If the user presses ENTER without any
other characters, the first position will be
the null character (called ‘empty string’).
• In case the user enters a string longer than
the buffer, gets may cause a serious runtime error.
String Output with puts
• The puts function
#define BUFLEN 200
int main() {
char buf[BUFLEN];
gets(buf);
puts(buf);
return 0;
}
puts adds '\n' to output,
equivalent to
printf("%s\n", buf);
Library String Functions
• #include <string.h>
• Return the Length of a string
size_t strlen(const char *str)
• Copy a string (including the '\0') src to dest
char *strcpy(char *dest, const char *src)
• Concatenate two strings: append src to dest
char *strcat(char *dest, const char *src)
• Compare two strings
int strcmp(const char *s1, const char *s2)
Return: 0 if identical; ASCII
>0 for,difference
e.g., "abc"between
vs. "abb",
the <0
firstfor
mismatch
"abc" vs.otherwise
"abd"
strcpy example
#include <string.h>
char words[100];
strcpy(words, “Hello!”);
Structures
• To group multiple (heterogeneous)
variables
• Similar to Java classes, but not as
powerful
 A structure has only data members
 All members are public
Structure Type Declaration
• Pattern
 struct StructType {
/* members */
};
 Typically global
• Members
 Analogous to data
declaration
struct Aircraft{
char id[10];
int x;
int y;
int z;
int prevZ;
int heading;
int verticalSpeed;
int speed;
};
int main() {
/* skipped */
}
Struct Instance
• Aircraft identifies a struct Aircraft {
structure type, also
/*members*/
known as a structure };
tag.
structure tag
• a is an instance of
the structure type
Aircraft
struct Aircraft a;
• Keyword struct
may not be dropped
typedef
• A way to define a synonym for existing
(complicated) types.
 typedef int Bool;
 typedef int*** Intptr3;
typedef and Structures
• This is a case of programmer laziness!
• Instead of
struct Aircraft boeing747;
use
typedef struct Aircraft Arcrft;
then
Arcrft boeing747;
• Arcrft is a new user-defined type.
Structure Variable Declaration
typedef struct Ac{
char id[10];
int x;
int y;
int z;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
int main() {
Aircraft a, b, c;
/* skipped */
}
Member Assignment/Reference
• Assignment pattern
 structVar.memberName
= exp;
• Reference pattern
 structVar.memberName
typedef struct {
char id[10];
int x;
int y;
int z;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
int main() {
Aircraft a;
a.z = 0;
a.prevZ = a.z;
/* skipped */
}
Structure Initialization
• Like array initializations,
this only works at the
time of declaration.
• Afterwards you must
assign/initialize each
member one by one.
typedef struct {
char id[10];
int x;
int y;
int z;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
int main() {
Aircraft a =
{"N3NK", 0, 0, 0,
0, 270, 0, 0};
/* skipped */
}
Structure Assignment
• Pattern
 structVar1 = structVar2;
• Each member’s value will
be copied
typedef struct {
char id[10];
int x;
int y;
int z;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
int main() {
Aircraft a =
{"N3NK", 0, 0, 0,
0, 270, 0, 0};
Aircraft b;
b = a;
/* skipped */
}
Additional Examples
typedef struct {
int ssn;
float debt;
} Person;
typedef struct {
int type;
int value;
int address;
char name[32];
} Variable;
ssn
debt
type
value
address
name
Complex Structures
• Various structure
members
 Basic types: int,
double, char, etc.
 Arrays
 Pointers
 Structures
• Arbitrary combination
possible
typedef struct {
int x;
int y;
int z;
} Position;
typedef struct {
char id[10];
Position pos;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
Array of Structures
typedef struct {
char id[10];
Position pos;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
int main() {
Aircraft aircrafts[2] =
{ { init list for elem 0 },
{ init list for elem 1 } };
aircrafts[0].pos.x = 0;
}
Structure with Array of Structures
typedef struct {
char id[10];
Position pos;
int prevZ;
int heading;
int verticalSpeed;
int speed;
} Aircraft;
typedef struct {
int numOfAircrafts;
Aircraft aircrafts[100];
} Radar;
int main() {
Radar r;
r.aircrafts[0].pos.x = 0;
}
Structure Arguments
void updateStatus(Aircraft b) {
b.heading += 90;
}
int main() {
Aircraft a = initialization;
updateStatus(a);
return 0;
}
• The argument variable b is a copy of the original
variable a.
• Analogous to basic variables, different from arrays
• Cannot change the original variable a
Structure Return
Aircraft updateStatus(Aircraft b) {
b.heading += 90;
return b;
}
int main() {
Aircraft a = initialization;
a = updateStatus(a);
}
• The local variable b is modified and
returned.
• The returned b can be assigned (copied) to
the original a.
Pointer to Structure
• To modify the original value, pass the
pointer to a structure
void updateStatus(Aircraft *b) {
(*b).heading += 90;
}
int main() {
Aircraft a = initialization;
updateStatus(&a);
return 0;
}
Shorthand
• To deal with pointers to structure, the
shorthand form is more commonly used.
• Pattern
 StructPtrVarmember-of-structure;
void updateStatus(Aircraft *b) {
b->heading += 90; /* same as (*b).heading */
}
int main() {
Aircraft a = initialization;
updateStatus(&a);
return 0;
}
Summary: pointers to structures
Aircraft a;
Aircraft *a2 = &a;
(*a2).heading = 90;
Is equivalent to
a2->heading = 90
File I/O
• Accessing a stream in C is done through file
pointers:
 A variable pointing to a file  FILE *fp;
fp
 The type FILE is defined in stdio.h
 Certain streams have predefined pointers with
standard names – stdin, stdout and stderr
Opening/Closing a File
fp = fopen("file.dat", "r")
filename
"r" – reading
Returns the null pointer NULL "w" – writing
(overwriting)!
(zero) on error, i.e. trying to
"a" – appending
read a file that doesn’t exist.
• Full path name as well as the filename
may be included btw the quotes
• Always test against NULL
• Closing a file when done: fclose(fp);
Reading
• Reading a char– returns char read or EOF
 int fgetc(FILE *fp)
 int getc(FILE *fp) // macro
 int getchar() <==> int fgetc(stdin)
• Reading a string
 char *fgets(char *s, int size, FILE *fp)
 Reads in at most (size-1) characters and stores
them in the buffer pointed by s
 Reading stops after a newline of EOF
 ‘\0’ is stored after the last character
 char *gets(char *s, int size) // from stdin
Writing
• Writing a char– returns char written
 int fputc(int c, FILE *fp)
 int putc(int c, FILE *fp) // macro
 int putchar(int c) <==> int fputc(…, stdin)
 int ungetc(int c, FILE *fp)
//pushes c back to stream where it is
//available for subsequent read operations
• Writing a string
 int fputs(const char *s, FILE *fp)
 Writes the string and a training newline into fp
 int puts(const char *s) // to stdout
Example: File Copy by Line
int main() {
char buf[BUFLEN], inFile[BUFLEN], outFile[BUFLEN];
FILE *in, *out;
printf("Enter source filename: ");
fgets(inFile,BUFLEN-1,stdin); trim_newline(inFile);
// get outFile as well from user
in = fopen(inFile, "r");
out = fopen(outFile, "w");
if ((in == NULL) || (out == NULL)) {
printf("*** File open error\n");
return;
}
/* NULL returned at EOF */
while (fgets(buf, BUFLEN-1, in) != NULL) {
fputs(buf, out);
}
}
fclose(in);
return 0;
fclose(out);
filecopy2.c
Formated I/O
• Reading – returns number of matches or EOF
int fscanf(FILE *fp, "...", variableList);
• Writing – returns number of chars written
int fprintf(FILE *fp, "...", variableList);
• scanf is equivalent to fscanf with stdin
• printf to fprintf with stdout
Buffering and fflush(…)
• A buffer is an area of memory that acts as a
temporary holding area for I/O
• Characters/strings are not usually written to
a file as son as they are written to a stream
 They are accumulated in buffer and written to
file as a block
• To force the buffer to be written to file, use:
 fflush(FILE *fp)
 Otherwise, buffer is flushed when full, or when
stream is closed, or at exit.
Dynamic Memory Allocation
• The most important usage of pointers.
• C’s data structures are normally fixed in
size, i.e. static.
 Static data structures must have their sizes
decided at time of compilation
 Arrays are good examples
• Through pointers, C supports the ability to
allocate storage during program execution.
The Heap
• The pool of memory from which dynamic
memory is allocated is separate, and is
known as the heap.
• There are library routines to allocate and
free memory from the heap.
• Heap memory is only accessible through
pointers.
• Mixing statically and dynamically allocated
memory is not allowed.
malloc() and free()
• Library routines for managing the heap
• Dynamically allocate and free arbitrary-sized chunks
of memory in any order
 void *malloc (size_t size);
 Allocates a block of size bytes from the heap
 Returns a pointer to the block allocated (casting to correct type
required, value pointed by void * cannot be accessed directly.)
 size_t is an unsigned integer type used for very large integers.
 On failure, malloc returns a null pointer. Make sure to test for error
 void free (void *ptr);
 frees memory space pointed by ptr.
• #include<stdlib.h>
Example: Allocating an int Array
int *a;
a = (int *) malloc(sizeof(int)*6);
a[5] = 3;
free(a);
• Never attempt to free memory that has not
been previously allocated via malloc!
• Memory allocated through malloc is not
cleared or initialized in anyway. Initialize
yourself!
Example: String Allocations
char* newStr(char *str) {
char *s;
s = (char *) malloc(strlen(str) + 1);
return strcpy(s, str);
}
char* newStr2(char *str, char *str2){
char *s;
s = (char *) malloc(strlen(s) + strlen(s2) + 1);
strcpy(s, str); return strcat(s, str2);
}
• By default void* will be casted to char*,
so in fact no casting is necessary here.
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
0
malloc(6);
Text
Data
malloc(2);
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
p1
0
malloc(6);
Text
Data
malloc(2);
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
p1
0
p2
Text
Data
malloc(2);
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2
Text
Data
p3
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2
Text
Data
p3
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2
Text
Data
p3
p4
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2
Text
Data
p3
p4
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2,p5
Text
Data
p3
p4
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2,p5
Text
Data
p3
p4
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2,p5
Text
Data
p3
p4
BSS
Heap
Stack
0xffffffff
Dynamic Memory Layout
char *p1 =
char *p2 =
char *p3 =
free(p2);
char *p4 =
free(p3);
char *p5 =
free(p1);
free(p4);
free(p5);
malloc(3);
malloc(4);
malloc(1);
malloc(6);
malloc(2);
p1
0
p2,p5
Text
Data
p3
p4
BSS
Heap
Stack
0xffffffff
The Love-hate Relationship with
malloc
• Most experience C-programmers have such
a dilemma.
 malloc is fast, efficient and flexible
 The dreaded memory leak – neglecting to free
memory
 Reaching beyond malloced bounds
 Heap fragmentation – this is not really a
programming error, and is therefore even
harder to fix
Summary
• Learn how to handle memory management in C
• malloc and related functions are essential to C
programming
• Watch for the following common errors
 Not checking to see if malloc returned NULL
 No freeing memory after use: memory leak
 Dangling pointes:
 trying to access memory after freeing
 Set pointer to NULL after freeing it, otherwise it wil still hold the adress
of the memory space that you freed
Descargar

No Slide Title