C - Programming
C - Programming
Welcome to C!
Course Objectives
tells compiler about standard input and output functions (i.e. printf + others)
#include
#include <stdio.h>
<stdio.h> /*
/* comment
comment */
*/
main function
int
int main(void)
main(void)
{{
printf("Hello\n");
printf("Hello\n");
“begin” printf("Welcome
printf("Welcome to
to the
the Course!\n");
Course!\n");
return
return 0;
0;
}}
flag success Hello
Hello
to operating “end” Welcome
Welcome to
to the
the Course!
Course!
system
The Format of C
printf("%i
printf("%i -- %i
%i == %i\n",
%i\n", a,
a, b,
b, aa -- b);
b);
write “a”, “b” and “a-b” return
return 0;
0;
in the format specified }
} Enter
Enter two
two numbers:
numbers: 21
21 17
17
21
21 -- 17
17 == 44
Variables
#include
#include <stdio.h>
<stdio.h>
#include
#include <limits.h>
<limits.h>
int
int main(void)
main(void)
{{
unsigned
unsigned long
long big
big == ULONG_MAX;
ULONG_MAX;
printf("minimum
printf("minimum int
int == %i,
%i, ",
", INT_MIN);
INT_MIN);
printf("maximum
printf("maximum int
int == %i\n",
%i\n", INT_MAX);
INT_MAX);
printf("maximum
printf("maximum unsigned
unsigned == %u\n",
%u\n", UINT_MAX);
UINT_MAX);
printf("maximum
printf("maximum long
long int
int == %li\n",
%li\n", LONG_MAX);
LONG_MAX);
printf("maximum
printf("maximum unsigned
unsigned long
long == %lu\n",
%lu\n", big);
big);
return
return 0;
0; minimum int = -32768, maximum int = 32767
}} minimum int = -32768, maximum int = 32767
maximum
maximum unsigned
unsigned == 65535
65535
maximum
maximum long
long int
int == 2147483647
2147483647
maximum
maximum unsigned
unsigned long
long == 4294967295
4294967295
Character Example
Note: print integer
value of character
#include
#include <stdio.h>
<stdio.h>
#include <limits.h>
#include <limits.h>
int
int main(void)
main(void)
{{
char
char lower_a
lower_a == 'a';
'a';
char
char lower_m
lower_m == 'm';
'm';
printf("minimum
printf("minimum char
char == %i,
%i, ",
", CHAR_MIN);
CHAR_MIN);
printf("maximum
printf("maximum char
char == %i\n",
%i\n", CHAR_MAX);
CHAR_MAX);
printf("after
printf("after '%c'
'%c' comes
comes '%c'\n",
'%c'\n", lower_a,
lower_a, lower_a
lower_a ++ 1);
1);
printf("uppercase
printf("uppercase is
is '%c'\n",
'%c'\n", lower_m
lower_m -- 'a'
'a' ++ 'A');
'A');
return
return 0;
0;
}} minimum
minimum char
char == 0,
0, maximum
maximum char
char == 255
255
after
after 'a'
'a' comes
comes 'b'
'b'
uppercase
uppercase isis 'M'
'M'
Integers With Different Bases
#include
#include <stdio.h>
<stdio.h>
#include
#include <float.h>
<float.h>
int
int main(void)
main(void)
{{
double
double ff == 3.1416,
3.1416, gg == 1.2e-5,
1.2e-5, hh == 5000000000.0;
5000000000.0;
printf("f=%lf\tg=%lf\th=%lf\n",
printf("f=%lf\tg=%lf\th=%lf\n", f,
f, g,
g, h);
h);
printf("f=%le\tg=%le\th=%le\n",
printf("f=%le\tg=%le\th=%le\n", f,
f, g,
g, h);
h);
printf("f=%lg\tg=%lg\th=%lg\n",
printf("f=%lg\tg=%lg\th=%lg\n", f,
f, g,
g, h);
h);
printf("f=%7.2lf\tg=%.2le\th=%.4lg\n",
printf("f=%7.2lf\tg=%.2le\th=%.4lg\n", f,
f, g,
g, h);
h);
return
return 0;
0;
}} f=3.141600 g=0.000012 h=5000000000.000000
f=3.141600 g=0.000012 h=5000000000.000000
f=3.141600e+00 g=1.200000e-05
f=3.141600e+00 g=1.200000e-05 h=5.000000e+09
h=5.000000e+09
f=3.1416
f=3.1416 g=1.2e-05
g=1.2e-05 h=5e+09
h=5e+09
f=
f= 3.14
3.14 g=1.20e-05
g=1.20e-05 h=5e+09
h=5e+09
Constants
return
return 0;
0;
}}
f=5000000000.000000
f=5000000000.000000
g=705032704.000000 OVERFLOW
g=705032704.000000
Named Constants
#include
#include <stdio.h>
<stdio.h>
creates an
integer int
int main(void)
main(void)
constant {{
const
const long
long double
double pi
pi == 3.141592653590L;
3.141592653590L;
const
const int
int days_in_week
days_in_week == 7;7;
const sunday = 0;
const sunday = 0;
days_in_week
days_in_week == 5;
5;
error!
return
return 0;
0;
}}
Preprocessor Constants
int
int day
day == SUNDAY;
SUNDAY;
long
long flag = USE_API;
flag = USE_API;
#include
#include <stdio.h>
<stdio.h>
“%c” fills one byte
of “a” which is two int
int main(void)
main(void)
bytes in size {{
short
short aa == 256,
256, bb == 10;
10;
printf("Type
printf("Type aa number:
number: ");
");
scanf("%c",
scanf("%c", &a);
&a);
“%f” expects 4 byte
float in IEEE format,
printf("a
printf("a == %hi,
%hi, bb == %f\n",
%f\n", a,
a, b);
b);
“b” is 2 bytes and
NOT in IEEE format
return
return 0;
0;
}}
Type
Type aa number:
number: 11
aa == 305
305 bb == Floating
Floating support
support not
not loaded
loaded
Summary
K&R C vs Standard C
main, printf
Variables
Integer types
Real types
Constants
Named constants
Preprocessor constants
Take care with printf and scanf
Operators in C
Arithmetic operators
Cast operator
Increment and Decrement
Bitwise operators
Comparison operators
Assignment operators
sizeof operator
Conditional expression operator
Arithmetic Operators
ff == (double)i
(double)i // j;
j;
ff == ii // (double)j;
(double)j;
ff == (double)i
(double)i // (double)j;
(double)j;
ff == (double)(i
(double)(i // j);
j);
integer division is done here,
return
return 0;
0;
the result, 1, is changed to a
}}
double, 1.00000
Increment and Decrement
int
int ii == 5,
5, jj == 4;
4;
“i” becomes 6
i++;
i++;
“j” becomes 3 --j;
--j;
++i;
++i;
“i” becomes 7
Prefix and Postfix
#include
#include <stdio.h>
<stdio.h> equivalent to:
1. j++;
int
int main(void)
main(void) 2. i = j;
{{
int
int i,
i, jj == 5;
5;
ii == ++j;
++j;
printf("i=%d,
printf("i=%d, j=%d\n",
j=%d\n", i,
i, j);
j); equivalent to:
jj == 5; 1. i = j;
5;
ii == j++; 2. j++;
j++;
printf("i=%d,
printf("i=%d, j=%d\n",
j=%d\n", i,
i, j);
j);
return
return 0;
0;
}} i=6,
i=6, j=6
j=6
i=5,
i=5, j=6
j=6
Truth in C
if(0)
if(0)
printf("this
printf("this will
will never
never be
be printed\n");
printed\n");
Comparison Operators
int
int i,
i, jj == 10,
10, kk == 28;
28;
ii == ((j
((j >> 5)
5) &&
&& (k
(k << 100))
100)) ||
|| (k
(k >> 24);
24);
Logical Operator Guarantees
if(i
if(i << 10
10 &&
&& a[i]
a[i] >> 0)
0)
printf("%i\n",
printf("%i\n", a[i]);
a[i]);
Warning!
int
int ii == 10;
10;
if(!i
if(!i ==
== 5)
5)
printf("i
printf("i is
is not
not equal
equal toto five\n");
five\n");
else
else
printf("i
printf("i is
is equal
equal to
to five\n");
five\n");
ii is
is equal
equal to
to five
five
Bitwise Operators
printf("%i\n",
printf("%i\n", jj == 93);
93);
“j” is assigned 93, the 93 is then
made available to printf for
printing
Warning!
int
int main(void)
main(void)
{{
int
int ii == 0;
0;
if(i
if(i == 0)
0)
printf("i
printf("i is
is equal
equal to
to zero\n");
zero\n");
else
else
printf("somehow
printf("somehow ii is
is not
not zero\n");
zero\n");
return
return 0;
0;
}}
somehow
somehow ii is
is not
not zero
zero
Other Assignment Operators
is equivalent to:
(expression1) = (expression1) op (expression2)
aa +=
+= 27;
27; ff /=
/= 9.2;
9.2; ii *=
*= jj ++ 2;
2;
aa == aa ++ 27;
27; ff == ff // 9.2;
9.2; ii == ii ** (j
(j ++ 2);
2);
sizeof Operator
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void)
{{
int
int ii == 0,
0, j,
j, kk == 7,
7, mm == 5,
5, n;
n;
jj == mm +=
+= 2;
2;
printf("j
printf("j == %d\n",
%d\n", j);
j);
jj == k++
k++ >> 7;
7;
printf("j
printf("j = %d\n",
= %d\n", j);
j);
jj == ii ==
== 00 && k;
k;
printf("j
printf("j = %d\n", j);
= %d\n", j);
nn == !i
!i >> kk >>
>> 2;
2;
printf("n
printf("n == %d\n",
%d\n", n);
n);
return
return 0;
0;
}}
Control Flow
scanf("%i",
scanf("%i", &i);
&i);
if(i
if(i >> 0)
0)
printf("a
printf("a positive
positive number
number was
was entered\n");
entered\n");
if(i
if(i << 0)
0) {{
printf("a
printf("a negative
negative number
number was
was entered\n");
entered\n");
ii == -i;
-i;
}}
Warning!
printf("input
printf("input an
an integer:
integer: ");
");
scanf("%i",
scanf("%i", &j);
&j);
if(j
if(j >> 0);
0);
printf("a
printf("a positive
positive number
number was
was entered\n");
entered\n");
input
input an
an integer:
integer: -6
-6
aa positive
positive number
number was
was entered
entered
if then else
if(i
if(i >> 0)
0)
printf("i
printf("i is
is positive\n");
positive\n");
else {
else {
printf("i
printf("i is
is negative\n");
negative\n");
ii == -i;
-i;
}}
Nesting ifs
int
int ii == -20;
-20;
if(i
if(i >> 0)
0) {{
if(i
if(i >> 1000)
1000)
printf("i
printf("i is
is big\n");
big\n");
}} else
else ii is
is negative
negative
printf("i
printf("i isis negative\n");
negative\n");
switch
float ii == 3;
float f;
f; 3;
switch(f) switch(i)
switch(i) {{
switch(f) {{ case
case
case 2:
2: case 3:3: printf("i
printf("i == 3\n");
3\n");
.... case 2: printf("i = 2\n");
case 2: printf("i = 2\n");
.... case
case 1:1: printf("i
printf("i == 1\n");
1\n");
switch(i) }}
switch(i) {{ ii == 33
case
case 22 ** j:
j: ii == 22
....
.... ii == 11
A switch Example
printf("On
printf("On thethe ");
");
switch(i)
switch(i) { {
case
case 1:
1: printf("1st");
printf("1st"); break;
break;
case 2:
case 2: printf("2nd");
printf("2nd"); break;
break;
case 3:
case 3: printf("3rd");
printf("3rd"); break;
break;
default:
default: printf("%ith", i); break;
printf("%ith", i); break;
}}
printf("
printf(" dayday of
of Christmas
Christmas my
my true
true love
love sent
sent toto me
me ");
");
switch(i)
switch(i) { {
case
case 12:
12: printf("twelve
printf("twelve lords
lords aa leaping,
leaping, ");
");
case 11:
case 11: printf("eleven ladies dancing,
printf("eleven ladies dancing, "); ");
case 10:
case 10: printf("ten
printf("ten pipers
pipers piping,
piping, ");
");
case 9:
case 9: printf("nine
printf("nine drummers drumming, ");
drummers drumming, ");
case 8:
case 8: printf("eight maids a milking,
printf("eight maids a milking, "); ");
case 7:
case 7: printf("seven
printf("seven swans
swans aa swimming,
swimming, ");
");
case 6:
case 6: printf("six geese a laying,
printf("six geese a laying, "); ");
case 5:
case 5: printf("five
printf("five gold
gold rings,
rings, ");
");
case 4:
case 4: printf("four
printf("four calling birds, ");
calling birds, ");
case 3:
case 3: printf("three French hens,
printf("three French hens, "); ");
case 2:
case 2: printf("two
printf("two turtle
turtle doves
doves and
and ");
");
case 1:
case 1: printf("a
printf("a partridge in a pear tree\n");
partridge in a pear tree\n");
}}
while Loop
int
int jj == 5;
5;
user probably
printf("start\n");
printf("start\n");
intends “until j is while(j
equal to zero”, while(j == == 0)
0)
printf("j
printf("j == %i\n",
%i\n", j--);
j--);
however this is NOT printf("end\n");
printf("end\n");
the way to write it
start
start
end
end
do while
jj == 55
int
int j;
j; jj == 44
for(j jj == 33
for(j == 5;
5; jj >> 0;
0; j--)
j--)
printf("j jj == 22
printf("j = %i\n", j);
= %i\n", j);
jj == 11
for(j jj == 55 odd
for(j == 5;
5; jj >> 0;
0; j--)
j--) {{ odd
jj == 44 even
printf("j
printf("j == %i %i ",
", j);
j); even
printf("%s\n", ((j%2)==0)?"even":"odd"); jj == 33 odd
odd
printf("%s\n", ((j%2)==0)?"even":"odd"); jj == 22 even
}} even
jj == 11 odd
odd
for Is Not Until Either!
int
int j;
j;
user probably printf("start\n");
printf("start\n");
intends “until j is for(j
for(j == 5;
5; jj ==
== 0;
0; j--)
j--)
equal to zero”, printf("j
printf("j == %i\n",
%i\n", j);
j);
however this is NOT printf("end\n");
printf("end\n");
the way to write it start
start
either! end
end
Stepping With for
#include
#include <math.h>
<math.h>
int
int main(void)
main(void)
{{
double
double angle;
angle;
for(angle
for(angle == 0.0;
0.0; angle
angle << 3.14159;
3.14159; angle
angle +=
+= 0.2)
0.2)
printf("sine
printf("sine of of %.1lf
%.1lf is
is %.2lf\n",
%.2lf\n",
angle,
angle, sin(angle));
sin(angle));
return
return 0;
0;
}}
Extending the for Loop
for(;i
for(;i << 10;)
10;) use of a while loop would
be clearer here!
for(;;)
for(;;)
creates an infinite loop
break
for(j jj == 11
for(j == 1;
1; jj <=
<= 10;
10; j++)
j++) {{
if(j jj == 22
if(j %% 33 ==== 0)
0)
continue; jj == 44
continue;
printf("j jj == 55
printf("j == %i\n",
%i\n", j);
j);
}} jj == 77
jj == 88
jj == 10
10
Summary
Rules of functions
Examples - writing a function, calling a function
Function prototypes
Visibility
Call by value
The stack
auto, static and register
The Rules
int
int print_table(double
print_table(double start,
start, double
double end,
end, double
double step)
step)
{{
double
double d;d;
int
int lines
lines == 1;
1;
printf("Celsius\tFarenheit\n");
printf("Celsius\tFarenheit\n");
for(d
for(d == start;
start; dd <=
<= end;
end; dd +=
+= step,
step, lines++)
lines++)
printf("%.1lf\t%.1lf\n",
printf("%.1lf\t%.1lf\n", d, d * 1.8
d, d * 1.8 ++ 32);
32);
return
return lines;
lines;
}}
#include
#include <stdio.h>
<stdio.h>
int
int print_table(double,
print_table(double, double,
double, double);
double);
int
int main(void)
main(void)
{{
int
int how_many;
how_many;
double
double end
end == 100.0;
100.0;
the compiler knows these
how_many
how_many == print_table(1.0,
print_table(1.0, end,
end, 3);
3); should be doubles and
print_table(end, 200, 15);
print_table(end, 200, 15); converts them automatically
return
return 0;
0;
}}
now the compiler does not know how the function works
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void)
{{
int
int how_many;
how_many; the compiler does NOT
double
double end
end == 100.0;
100.0; convert these ints to
doubles. The function
how_many
how_many == print_table(1.0,
print_table(1.0, end,
end, 3);
3); picks up doubles
print_table(end, 200, 15);
print_table(end, 200, 15); anyway!
return
return 0;
0;
}}
Prototypes
is known as a prototype
If the compiler meets a call to an unknown
function it “guesses”
– Guess 1: the function returns an int, even if it doesn’t
– Guess 2: you have passed the correct number of parameters
and made sure they are all of the correct type, even if you
haven’t
The prototype provides the compiler with
important information about the return type and
parameters
Prototyping is Not Optional
Prototype:
int
int print_table(double,
print_table(double, double,
double, double);
double);
Function header:
int
int print_table(double
print_table(double start,
start, double
double end,
end, double
double step)
step)
{{
int
int print_table(double
print_table(double x,
x, double
double y,
y, double
double z);
z);
Take Care With Semicolons
/*
/* no
no parameters,
parameters, double
double return
return value
value */
*/
double get_double(void);
double get_double(void);
/*
/* no
no parameters,
parameters, no
no return
return value
value */
*/
void
void clear_screen(void);
clear_screen(void);
/*
/* three
three int
int parameters,
parameters, int
int return
return value
value */
*/
int day_of_year(int day, int month, int year);
int day_of_year(int day, int month, int year);
/*
/* three
three int
int parameters,
parameters, long
long int
int return
return value
value */
*/
long day_since_1_jan_1970(int, int,
long day_since_1_jan_1970(int, int, int);int);
/*
/* parameter
parameter checking
checking DISABLED,
DISABLED, double
double return
return value
value */
*/
double
double k_and_r_function();
k_and_r_function();
/*
/* short
short int
int parameter,
parameter, (default)
(default) int
int return
return value
value */
*/
transfer(short int s);
transfer(short int s);
Example Calls
int
int i;
i;
double
double d;
d;
long
long l;
l;
short
short int
int ss == 5;
5;
ii == get_integer();
get_integer();
no mention of “void”
dd == get_double();
get_double(); when calling these
functions
clear_screen();
clear_screen();
ii == day_of_year(16,
day_of_year(16, 7,
7, 1969);
1969);
ll == day_since_1_jan_1970(1,
day_since_1_jan_1970(1, 4,
4, 1983);
1983);
the compiler cannot tell
dd == k_and_r_function();
k_and_r_function(); which of these (if any) is
dd == k_and_r_function(19.7);
k_and_r_function(19.7); correct - neither can we
dd == k_and_r_function("hello
k_and_r_function("hello world");
world"); without resorting to
documentation!
ii == transfer(s);
transfer(s);
Rules of Visibility
int
int table(void)
table(void)
{{
int lines auto keyword
int lines == 13;
13;
auto int columns;
auto int columns; redundant
static
int
int running_total(void)
running_total(void)
{{ permanently allocated,
static
static int
int rows;
rows;
but local to this
function
rows++;
rows++;
register
#include
#include <stdio.h>
<stdio.h> variable “d” is global
double
double d;
d; and available to all
int functions defined
int main(void)
main(void)
{{ below it
int
int i;
i;
return
return 0;
0;
}}
Review
Declaring pointers
The “&” operator
The “*” operator
Initialising pointers
Type mismatches
Call by reference
Pointers to pointers
Pointers - Why?
int
int *pi;
*pi; /*
/* pi
pi is
is aa pointer
pointer to
to an
an int
int */
*/
long
long int
int *p;
*p; /*
/* pp is
is aa pointer
pointer to
to aa long
long int
int */
*/
float*
float* pf;
pf; /*
/* pf
pf is
is aa pointer
pointer to
to aa float
float */
*/
char
char c,
c, d,
d, *pc;
*pc; /*
/* cc and
and dd are
are aa char
char
pc
pc is a pointer to
is a pointer to char
char */
*/
double*
double* pd,
pd, e,
e, f;
f; /*
/* pd
pd is
is pointer
pointer to
to aa double
double
ee and f are double
and f are double */ */
char*
char* start;
start; /*
/* start
start is
is aa pointer
pointer to
to aa char
char */
*/
char*
char* end;
end; /*
/* end
end is
is aa pointer
pointer to
to aa char
char */
*/
The “&” Operator
pp == &large;
&large; /*
/* ERROR
ERROR */
*/
The “*” Operator
#include
#include <stdio.h>
<stdio.h> p c
char
char gg == 'z';
'z'; 0x1132 'a'
0x1132
int
int main(void)
main(void)
{{
char cc == 'a'; p g
char 'a';
char
char *p;
*p; 0x91A2 'z'
pp == &c; 0x91A2
&c;
printf("%c\n",
printf("%c\n", *p);
*p);
pp == &g;
&g;
print “what p points to”
printf("%c\n",
printf("%c\n", *p);
*p);
return
return 0;
0; aa
}} zz
Writing Down Pointers
#include p i
#include <stdio.h>
<stdio.h>
? 13
int
int main(void)
main(void) 0x1212
{{
short
short ii == 13;
13;
short
short *p;
*p;
*p
*p == 23;
23;
printf("%hi\n",
printf("%hi\n", *p);
*p);
return
return 0;
0;
}}
Initialise Pointers!
and:
p i
int
int ii == 10,
10, jj == 14;
14;
int
int *p
*p == &i;
&i; 0x15A0 10
int
int *q
*q == &j;
&j; 0x15A4 0x15A0
q j
pp == q;
q;
0x15A4 14
0x15A4
Fill in the Gaps
int
int main(void)
main(void)
{{ i
int
int ii == 10,
10, jj == 14,
14, k;
k; 0x2100
int
int *p = &i;
*p = &i;
int
int *q
*q == &j;
&j; j
0x2104
*p
*p +=
+= 1;
1;
k
pp == &k;
&k; 0x1208
*p
*p == *q;
*q; p
pp == q;
q; 0x120B
*p q
*p == *q;
*q;
0x1210
return
return 0;
0;
}}
Type Mismatch
cannot write
cannot write
0x15A4 into i
14 into p
Call by Value - Reminder
#include
#include <stdio.h>
<stdio.h>
void
void change(int
change(int v);
v);
int
int main(void)
main(void)
{{ the function
int
int var
var == 5;
5; was not able
change(var); to alter “var”
change(var);
printf("main:
printf("main: var
var == %i\n",
%i\n", var);
var);
return
return 0;
0;
}}
the function is
void change(int
void change(int v)v)
{{ able to alter “v”
vv *=
*= 100;
100;
printf("change:
printf("change: vv == %i\n",
%i\n", v);
v);
}} change:
change: vv == 500
500
main: var =
main: var = 5 5
Call by Reference
prototype “forces” us to pass a pointer
#include
#include <stdio.h>
<stdio.h>
void
void change(int*
change(int* p);
p);
int
int main(void)
main(void)
{{
int main: var
int var
var == 5;
5;
change(&var); 5
change(&var); 0x1120
printf("main:
printf("main: var
var == %i\n",
%i\n", var);
var);
return
return 0;
0; change: p
}}
0x1120
void
void change(int*
change(int* p)
p) 0x1124
{{
*p
*p *=
*= 100;
100;
printf("change:
printf("change: *p
*p == %i\n",
%i\n", *p);
*p);
}}
change:
change: *p
*p == 500
500
main: var = 500
main: var = 500
Pointers to Pointers
pp is a “pointer to” a
#include
#include <stdio.h>
<stdio.h> “pointer to an int”
int
int main(void)
main(void)
{{
int
int ii == 16;
16;
int i
int *p = &i;
*p = &i; 16
int **pp;
int **pp; 0x2320
pp p
pp == &p;
&p; 0x2320
printf("%i\n",
printf("%i\n", **pp);
**pp); 0x2324
return
return 0;
0; pp
}} 0x2324
0x2328
Review
int
int main(void)
main(void) i j k
{{
int
int ii == 10,
10, jj == 7,
7, k;
k;
int
int *p
*p == &i;
&i;
int
int *q = &j;
*q = &j;
int *pp p q
int *pp == &p;
&p;
**pp
**pp +=
+= 1;
1;
*pp pp
*pp == &k;
&k;
**pp
**pp == *q;
*q;
ii == *q***pp;
*q***pp;
ii == *q/**pp;
*q/**pp; /*
/* headache?
headache? */;
*/;
return
return 0;
0;
}}
Arrays in C
Declaring arrays
Accessing elements
Passing arrays into functions
Using pointers to access arrays
Strings
The null terminator
Declaring Arrays
return
return 0;
0; 5
}}
Array Names
int
int a[10];
a[10];
int
int *p;
*p;
float
float f[5]
f[5] p a
float *fp;
float *fp;
pp == a; /* fp f
a; /* pp == &a[0]
&a[0] */
*/
fp
fp == f;
f; /*
/* fp
fp == &f[0]
&f[0] */
*/
Passing Arrays to Functions
int
int add_elements(int
add_elements(int a[],
a[], int
int size)
size)
{{
int
int add_elements(int
add_elements(int *p,
*p, int
int size)
size)
{{
Example
primes
#include
#include <stdio.h>
<stdio.h> 1
void
void sum(long
sum(long [],
[], int);
int); 2
int
int main(void)
main(void)
{{ 3
long
long primes[6]
primes[6] == {{ 1,
1, 2,
2,
3, 5
3, 5, 7, 11
5, 7, 11 };
};
sum(primes,
sum(primes, 6);
6);
7
printf("%li\n",
printf("%li\n", primes[0]);
primes[0]); 11
return
return 0;
0; a
}}
void
void sum(long
sum(long a[],
a[], int
int sz)
sz)
{{ sz 6
int
int i;i;
long
long total == 0;
total 0;
for(i provides bounds checking
for(i == 0;
0; ii << sz;
sz; i++)
i++)
total += a[i];
total += a[i];
a[0]
a[0] == total;
total; the total is written over
}}
element zero
Using Pointers
long
long v[6]
v[6] == {{ 1,2,
1,2,
3,4,5,6
3,4,5,6 };
};
long
long *p;*p;
pp == vv ++ 5;
5; p--
p-=2
printf("%ld\n",
printf("%ld\n", *p); *p);
p--; p
p--;
printf("%ld\n",
printf("%ld\n", *p); *p); 1020 1 2 3 4 5 6
pp -= 2; 66 v
-= 2; 1000 1008 1016
printf("%ld\n", 55
printf("%ld\n", *p); *p); 1004 1012 1020
33
Pointers May be Subtracted
double
double d[7]
d[7] == {{ 1.1,
1.1, 2.2,
2.2, p1 p2
3.3,
3.3, 4.4, 5.5, 6.6, 7.7
4.4, 5.5, 6.6, 7.7 };
};
double 2008 2048
double *p1;
*p1;
double
double *p2;
*p2;
*p++ means:
*p++ find the value at the end of the pointer
*p++ increment the POINTER to point to the
next element
(*p)++ means:
(*p)++ find the value at the end of the pointer
(*p)++ increment the VALUE AT THE END OF THE
POINTER (the pointer never moves)
*++p means:
*++p increment the pointer
*++p find the value at the end of the pointer
Which Notation?
short
short a[8]
a[8] == {{ 10,
10, 20,
20, 30,
30, 40,
40, 50,
50, 60,
60, 70,
70, 80
80 };
};
short *p = a;
short *p = a;
printf("%i\n",
printf("%i\n", a[3]);
a[3]);
printf("%i\n",
printf("%i\n", *(a ++ 3));
*(a 3));
printf("%i\n", *(p + 3)); 40
40
printf("%i\n", *(p + 3)); 40
printf("%i\n",
printf("%i\n", p[3]);
p[3]); 40
printf("%i\n", 40
40
printf("%i\n", 3[a]);
3[a]); 40
40
40
40
p a
1000 10 20 30 40 50 60 70 80
1000 1004 1008 1012
1002 1006 1010 1014
Strings
char
char first_name[5]
first_name[5] == {{ 'J',
'J', 'o',
'o', 'h',
'h', 'n',
'n', '\0'
'\0' };
};
char
char last_name[6]
last_name[6] == "Minor";
"Minor";
char
char other[]
other[] == "Tony
"Tony Blurt";
Blurt";
char
char characters[7]
characters[7] == "No
"No null";
null";
other 'T' 'o' 'n' 'y' 32 'B' 'l' 'u' 'r' 't' 0
char
char other[]
other[] == "Tony
"Tony Blurt";
Blurt";
char
char *p; *p; int
int ii == 0;
0;
pp == other;
other; while(other[i]
while(other[i] !=
!= '\0')
'\0')
while(*p
while(*p != != '\0')
'\0') printf("%c",
printf("%c", other[i++]);
other[i++]);
printf("%c",
printf("%c", *p++);
*p++); printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("%s\n",
printf("%s\n", other);
other);
Null Really Does Mark the End!
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void) even though the rest of
{{ the data is still there,
char
char other[]
other[] == "Tony
"Tony Blurt";
Blurt"; printf will NOT move
past the null terminator
printf("%s\n",
printf("%s\n", other);
other);
other[4]
other[4] == '\0';
'\0';
printf("%s\n",
printf("%s\n", other);
other);
return
return 0;
0;
}} Tony
Tony Blurt
Blurt
Tony
Tony
other 'T' 'o' 'n' 'y' 32 'B' 'l' 'u' 'r' 't' 0
Assigning to Strings
#include
#include <stdio.h>
<stdio.h>
#include <string.h>
#include <string.h>
int
int main(void)
main(void)
{{
char
char who[]
who[] == "Tony
"Tony Blurt";
Blurt";
who
who == "John
"John Minor";
Minor";
strcpy(who,
strcpy(who, "John
"John Minor");
Minor");
return
return 0;
0;
}}
Pointing to Strings
char
char *p
*p == "Data
"Data segment!!";
segment!!";
char *q = "nt!!";
char *q = "nt!!";
q 0xF10A
p 0xF100
'D' 'a' 't' 'a' 32 's' 'e' 'g' 'm' 'e' 'n' 't' '!' '!' 0
0xF100 0xF10A
Example
this utterly pointless statement causes the
compiler to store the characters, unfortunately
we forget to save the address
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void)
{{
char
char *p
*p == "a
"a string
string in
in the
the data
data segment\n";
segment\n";
"a
"a second
second string
string in
in the
the data
data segment\n";
segment\n";
printf("a
printf("a third
third string
string in
in the
the data
data segment\n");
segment\n");
printf("%s",
printf("%s", p);
p);
printf(p);
printf(p);
return aa third
third string
string in
in the
the data
data segment
return 0;
0; segment
}} aa string in the data segment
string in the data segment
aa string
string in
in the
the data
data segment
segment
Multidimensional Arrays
const
const int
int brighton
brighton == 7;
7;
int day_of_year = 238;
int day_of_year = 238;
rainfall[brighton][day_of_year]
rainfall[brighton][day_of_year] == 0.0F;
0.0F;
Review
Concepts
Creating a structure template
Using the template to create an instance
Initializing an instance
Accessing an instance’s members
Passing instances to functions
Linked lists
Concepts
struct
struct Date
Date
{{ instances must be
int
int day;
day; declared before the ‘;’ ...
int
int month;
month;
int year;
int year;
}} today,
today, tomorrow;
tomorrow;
an array of 7
date instances
Initialising Instances
struct
struct Date
Date bug_day
bug_day == {{ 1,
1, 1,
1, 2000
2000 };
};
struct
struct Book
Book k_and_r
k_and_r == {{
"The
"The CC Programming
Programming Language
Language 2nd
2nd edition",
edition",
"Brian
"Brian W. Kernighan and Dennis M. Ritchie",
W. Kernighan and Dennis M. Ritchie",
31.95,
31.95,
"0-13-110362-8"
"0-13-110362-8" struct Book
struct Book
};
}; {
{
char title[80];
char title[80];
char
char author[80];
author[80];
float
float price;
price;
char
char isbn[20];
isbn[20];
};
};
Structures Within Structures
struct Library_member
struct Library_member
{
{
char name[80];
char
char
name[80];
address[200];
initialises first 4
char address[200];
long member_number; elements of array
long member_number;
float
float
fines[10];
fines[10]; “fines”, remainder are
struct Date dob;
struct
struct
Date
Date
dob;
enrolled;
initialised to 0.0
struct Date enrolled;
};
};
struct
struct Library_member
Library_member mm == {{
"Arthur
"Arthur Dent",
Dent",
"16 New Bypass",
"16 New Bypass",
42,
42,
{{ 0.10,
0.10, 2.58,
2.58, 0.13,
0.13, 1.10
1.10 },
}, initialises day, month
{{ 18,
18, 9,
9, 1959
1959 },
}, and year of “dob”
{{ 1,
1, 4,4, 1978
1978 }}
};
}; initialises day, month
and year of “enrolled”
Accessing Members
Arrays Structures
Name is pointer to the structure itself
zeroth element
Passed to functions by pointer value or pointer
struct
struct Library_member
Library_member mm == {{
"Arthur
"Arthur Dent",
Dent",
.....
.....
};
};
struct
struct Library_member
Library_member tmp;
tmp;
tmp
tmp == m;
m;
copies array “name”, array “address”,
long integer “member_number”, array
“fines”, Date structure “dob” and Date
structure “enrolled”
Passing Instances to Functions
by_value(m);
by_value(m);
by_reference(&m);
by_reference(&m);
void
void member_display(struct
member_display(struct Library_member
Library_member *p)
*p)
{{
printf("name
printf("name == %s\n",
%s\n", p->name);
p->name);
printf("address
printf("address == %s\n",
%s\n", p->address);
p->address);
printf("membership
printf("membership number == %li\n",
number %li\n", p->member_number);
p->member_number);
printf("fines:
printf("fines: ");
");
for(i
for(i = 0; i < 10 &&
= 0; i < 10 && p->fines[i]
p->fines[i] >> 0.0;
0.0; i++)
i++)
printf("£%.2f ", p->fines[i]);
printf("£%.2f ", p->fines[i]);
printf("\njoined
printf("\njoined %i/%i/%i\n",
%i/%i/%i\n", p->enrolled.day,
p->enrolled.day,
p->enrolled.month,
p->enrolled.month, p->enrolled.year);
p->enrolled.year);
}}
Pass by Reference - Warning
void
void member_display(struct
member_display(struct Library_member
Library_member *p)*p)
{{ function alters
printf("fines: the library
printf("fines: "); "); member instance
for(i
for(i == 0;
0; ii << 10
10 &&
&& p->fines[i]
p->fines[i] == 0.0;
0.0; i++)
i++)
printf("£%.2f ", p->fines[i]);
printf("£%.2f ", p->fines[i]);
}}
void
void member_display(const
member_display(const struct
struct Library_member
Library_member *p)
*p)
{{
....
....
}}
Returning Structure Instances
struct
struct Node
Node {{
char
char name[10];
name[10];
struct
struct Node
Node *next_in_line;
*next_in_line;
};
};
struct
struct Node
Node a1
a1 == {{ "John",
"John", NULL
NULL };
};
struct
struct Node
Node a2
a2 == {{ "Harriet",
"Harriet", &a1
&a1 },},
struct Node a3 = { "Claire",
struct Node a3 = { "Claire", &a2 }&a2 }
struct
struct Node
Node a4
a4 == {{ "Tony",
"Tony", &a3
&a3 };
};
a4 a3 a2 a1
Tony\0 Claire\0 Harriet\0 John\0
struct
struct Node
Node ** current
current == &a4;
&a4;
while(current
while(current !=
!= NULL)
NULL) {{
printf("%s\n",
printf("%s\n", current->name);
current->name);
current
current = current->next_in_line;
current = current->next_in_line;
0x1012 }}
a4
Tony\0 Claire\0 Harriet\0 John\0
Introduction
SOAC
Examples
typedef
Examples revisited
Introduction
int * p [15] ;
double (* p ) [38];
short * * ab [5][10] ;
int ( * pf ) (void) ;
f is a function, taking no
pta6c is a pointer to an
parameters, returning a
array of 6 char
pointer to an array of 6
char
fprp is a pointer to a
function, taking no
f * fprp ;
parameters, returning a
pointer to an array of 6
char
Example 8 Revisited
f is a function, taking a
pti is a pointer to an int char, returning a pointer
to an int
Don’t Panic!
SOAC - Spiral Outwards Anti Clockwise
To simplify, use typedef(s)
Handling Files in C
Streams
stdin, stdout, stderr
Opening files
When things go wrong - perror
Copying files
Accessing the command line
Dealing with binary files
Introduction
a b c d e f g h i j k l
output stream
a b c d e f g h i j
input stream
Why stdout and stderr?
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void)
{{ output written to
printf("written
printf("written to
to stdout\n");
stdout\n"); stderr first
fprintf(stderr,
fprintf(stderr, "written
"written to
to stderr\n");
stderr\n"); because it is
C:> unbuffered
return
return 0;
0; C:> outprog
outprog
}} written
written to
to stderr
stderr
written to stdout
written to stdout
C:>
C:> outprog
outprog >> file.txt
file.txt
written
written to
to stderr
stderr
C:> type file.txt
C:> type file.txt
written
written to
to stdout
stdout
stdin is Line Buffered
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void)
{{ streams, you’ll
FILE* in; need one for each
FILE* in;
FILE* out; file you want
FILE* out;
FILE* append; open
FILE* append;
in
in == fopen("autoexec.bat",
fopen("autoexec.bat", "r");
"r");
out
out = fopen("autoexec.bak", "w");
= fopen("autoexec.bak", "w");
append
append = fopen("config.sys", "a");
= fopen("config.sys", "a");
Dealing with Errors
#include
#include <stdio.h>
<stdio.h>
int
int main(void)
main(void)
{{
FILE*
FILE* in;
in;
if((in
if((in == fopen("autoexec.bat",
fopen("autoexec.bat", "r"))
"r")) ==
== NULL)
NULL) {{
fprintf(stderr,
fprintf(stderr, "open
"open of
of autoexec.bat
autoexec.bat failed
failed ");
");
perror("because");
perror("because");
return
return 1;1;
}}
open
open of
of autoexec.bat
autoexec.bat failed
failed because:
because: No
No such
such file
file or
or directory
directory
File Access Problem
int
int main(int
main(int argc,
argc, char
char *argv[])
*argv[])
argc 3 argv c o p y p r o g . e x e \0
\ a u t o e x e c . b a t \0
\ a u t o e x e c . 0 0 0 \0
NULL
Example
#include
#include <stdio.h>
<stdio.h>
int
int main(int
main(int argc,
argc, char
char *argv[])
*argv[])
{{
int
int j;
j;
for(j
for(j == 0;
0; jj << argc;
argc; j++)
j++)
printf("argv[%i]
printf("argv[%i] == \"%s\"\n",
\"%s\"\n", j,
j, argv[j]);
argv[j]);
return
return 0;
0;
}}
C:>
C:> argprog
argprog one
one two
two three
three
argv[0] = "C:\cct\course\cprog\files\slideprog\argprog.exe"
argv[0] = "C:\cct\course\cprog\files\slideprog\argprog.exe"
argv[1]
argv[1] == "one"
"one"
argv[2] = "two"
argv[2] = "two"
argv[3]
argv[3] == "three"
"three"
Useful Routines
long
long l1,
l1, l2;
l2;
int
int j,
j, ch;
ch; example input
double
double d;
d;
float f; 28.325|9000000:68000/13
28.325|9000000:68000/13
float f;
char
char buf[200];
buf[200];
in
in == fopen("in.txt",
fopen("in.txt", "r")
"r") ....
....
out
out = fopen("out.txt", "w") ....
= fopen("out.txt", "w") ....
9000000:13:28.33
9000000:13:28.33
fscanf(in,
fscanf(in, "%lf|%li:%li/%i",
"%lf|%li:%li/%i", &d,
&d, &l1,
&l1, &l2,
&l2, &j);
&j);
fprintf(out, "%li:%i:%.2lf\n", l1, j,
fprintf(out, "%li:%i:%.2lf\n", l1, j, d);d);
size_t
size_t fread(void*
fread(void* p,
p, size_t
size_t size,
size, size_t
size_t n,
n, FILE*
FILE* stream);
stream);
size_t
size_t fwrite(const void* p, size_t size, size_t n, FILE*
fwrite(const void* p, size_t size, size_t n, FILE* stream);
stream);
int
int fseek(FILE*
fseek(FILE* stream,
stream, long
long offset,
offset, int
int whence);
whence);
long
long ftell(FILE* stream);
ftell(FILE* stream);
void
void rewind(FILE*
rewind(FILE* stream);
stream);
int
int fgetpos(FILE*
fgetpos(FILE* stream,
stream, fpos_t*
fpos_t* pos);
pos);
int
int fsetpos(FILE*
fsetpos(FILE* stream, const fpos_t* pos);
stream, const fpos_t* pos);
Example
double
double d;
d; read one chunk
long
long double
double lda[35];
lda[35]; of 8 bytes
fpos_t
fpos_t where;
where;
in
in == fopen("binary.dat",
fopen("binary.dat", "rb");
"rb"); remember current
out
out == fopen("binnew.dat",
fopen("binnew.dat", "wb");
"wb"); position in file
fread(&d,
fread(&d, sizeof(d),
sizeof(d), 1,
1, in);
in);
fwrite(lda,
fwrite(lda, sizeof(long
sizeof(long double),
double), 20,
20, out);
out); read 35 chunks
of 10 bytes
fseek(in,
fseek(in, 0L,
0L, SEEK_END);
SEEK_END);
write 20 long
move to end of binary.dat doubles from lda
Summary
Unions
Enumerated types
The Preprocessor
Working with multiple .c files
Unions
s
struct
struct SS union
union UU
{{ {{ u
short
short s;
s; short s;
short s;
long
long l;
l; long l;
long l;
double
double d;
d; double d;
double d;
char
char c;
c; char c;
char c;
}} s;
s; }} u;
u;
s.s
s.s == 10; u.s
10; u.s == 10;
10;
s.l = 10L;
s.l = 10L; u.l = 10L;
u.l = 10L;
s.d
s.d == 10.01; u.d
10.01; u.d == 10.01;
10.01;
s.c = '1';
s.c = '1'; u.c = '1';
u.c = '1';
Remembering
#define
#define sun
sun 00
#define mon
#define mon 11
enum
enum day
day {{ sun,
sun, mon,
mon, tue, #define
wed,
tue, #define tue
tue 22
wed, thu,
thu, fri,
fri, sat
sat };
}; #define wed
#define wed 33
#define
#define thu
thu 44
enum
enum day
day today
today == sun; #define
sun; #define fri
fri 55
#define sat
#define sat 66
if(today
if(today ==
== mon)
mon)
.... int
.... int today
today == sun;
sun;
if(today
if(today ==
== mon)
mon)
....
....
Using Different Constants
enum
enum day
day {{ sun
sun == 5,
5, mon,
mon, tue,
tue, wed,
wed, thu,
thu, fri,
fri, sat
sat };
};
enum
enum direction
direction {{ north
north == 0,
0, east
east == 90,
90, south
south == 180,
180,
west
west = 270 };
= 270 };
#define
#define JAN
JAN 11
#define FEB
#define FEB 22
#define
#define MAR 33 #define
MAR #define JAN
JAN 11
#define FEB
#define FEB 22
#define
#define PI 3.1416 #define
PI 3.1416 #define MAR
MAR 33
double
double my_global; #define
my_global; #define PI
PI 3.1416
3.1416
mydefs.h double
double my_global;
my_global;
#include double
double angle
angle == 22 ** 3.1416;
#include "mydefs.h"
"mydefs.h" 3.1416;
printf("%s", month[2]);
printf("%s", month[2]);
double
double angle
angle == 22 ** PI;
PI;
printf("%s", month[FEB]); myprog.i
printf("%s", month[FEB]);
myprog.c
Pathnames
cc
cc -I
-I c:\cct\course\cprog\misc\slideprog
c:\cct\course\cprog\misc\slideprog myprog.c
myprog.c
Preprocessor Constants
#if
#if !defined(SUN)
!defined(SUN) if “SUN” is not defined, then begin
#define
#define SUN
SUN 00 define “SUN” as zero
#endif
#endif end
#if
#if TUE
TUE if “TUE” is defined with a non zero value
#define
#define begin
begin {{
#define
#define end
end ;}
;}
#define
#define if
if if(
if(
#define
#define then
then ))
#define
#define integer
integer int
int
integer
integer i;
i; int
int i;
i;
if
if ii >> 00 then
then begin
begin if(
ii == 17 if( ii >> 00 )) {{
17 ii == 17
17
end
end ;}
;}
Preprocessor Macros
#define
#define MAX(A,B)
MAX(A,B) AA >> BB ?? AA :: BB
#define
#define MIN(X,Y)
MIN(X,Y) ((X)
((X) << (Y)
(Y) ?? (X)(X) :: (Y))
(Y))
int
int ii == 10,
10, jj == 12,
12, k;
k;
kk == MAX(i,
MAX(i, j);
j); printf("k
printf("k == %i\n",
%i\n", k);
k);
kk == MAX(j,
MAX(j, i) ** 2;
i) 2; printf("k = %i\n", k);
printf("k = %i\n", k);
kk == MIN(i, j) * 3;
MIN(i, j) * 3; printf("k
printf("k == %i\n",
%i\n", k);
k); k = 12
kk == MIN(i--,
MIN(i--, j++);
j++); printf("i = %i\n", i); kk == 12
printf("i = %i\n", i); 12
k = 12
kk == 30
30
ii == 88
A Debugging Aid
#define
#define GOT_HERE
GOT_HERE printf("reached
printf("reached %i%i in
in %s\n",
%s\n", \\
___LINE_
_LINE__,
_, ___FILE_
_FILE__)
_)
#define
#define SHOW(E,
SHOW(E, FMT)
FMT) printf(#E
printf(#E "" == "" FMT
FMT "\n",
"\n", E)
E)
printf("reached
printf("reached %i
%i in
in %s\n",
%s\n", 17,
17, "mysource.c");
"mysource.c");
GOT_HERE;
GOT_HERE;
SHOW(i,
SHOW(i, "%x");
"%x"); printf("i
printf("i == %x\n",
%x\n", i);
i);
SHOW(f/29.5,
SHOW(f/29.5, "%lf");
"%lf");
printf("f/29.5
printf("f/29.5 == %lf\n",
%lf\n", f/29.5);
f/29.5);
Working With Large Projects
print_table(0.0,
print_table(0.0, 5.5F);
5.5F);
#include
#include <stdio.h>
<stdio.h>
return 0;
return 0;
}} float
float step;
step;
void
void print_table(double
print_table(double start,
start, float
float stop)
stop)
{{
printf("Celsius\tFarenheit\n");
printf("Celsius\tFarenheit\n");
for(;start
for(;start << stop;
stop; start
start +=
+= step)
step)
printf("%.1lf\t%.1lf\n",
printf("%.1lf\t%.1lf\n", start,
start,
start
start ** 1.8
1.8 ++ 32);
32);
}}
Data Hiding Example
print_table(0.0,
print_table(0.0, 5.5F);
5.5F);
#include
#include <stdio.h>
<stdio.h>
return 0;
return 0;
}} double
double step;
step;
void
void print_table(double
print_table(double start,
start, double
double stop)
stop)
{{
printf("Celsius\tFarenheit\n");
printf("Celsius\tFarenheit\n");
for(;start
for(;start << stop;
stop; start
start +=
+= step)
step)
printf("%.1lf\t%.1lf\n",
printf("%.1lf\t%.1lf\n", start,
start,
start
start ** 1.8
1.8 ++ 32);
32);
}}
Use Header Files
project.h
extern
extern double
double step;
step;
void
voidprint_table(double,
print_table(double, double);
double);
#include
#include "project.h"
"project.h" #include
#include <stdio.h>
<stdio.h>
#include "project.h"
#include "project.h"
int
int main(void)
main(void)
{{ double
double step;
step;
step
step == 0.15F;
0.15F; void
void print_table(double
print_table(double start,
start, double
double stop)
stop)
print_table(0.0,
print_table(0.0, 5.5F);
5.5F); {{
return
return 0;
0; }}
}}
Be as Lazy as Possible
#if
#if defined(MAIN)
defined(MAIN)
#define
#define EXTERN
EXTERN
#else
#else
#define
#define EXTERN
EXTERN extern
extern
#endif
#endif
EXTERN
EXTERN double
double step;
step;
EXTERN long
EXTERN long current;
current;
EXTERN
EXTERN short
short res;
res;
#define
#define MAIN
MAIN #include
#include "globals.h"
"globals.h" #include
#include "globals.h"
"globals.h"
#include
#include "globals.h"
"globals.h"
first.c second.c
main.c
Summary
pp == malloc(s
malloc(s ** sizeof(double));
sizeof(double));
pp == realloc(NULL,
realloc(NULL, ss ** sizeof(double));
sizeof(double));
free(p);
free(p);
realloc(p,
realloc(p, 0);
0);
Allocating Arrays of Arrays
float
float **rain;
**rain;
rain
rain == calloc(s,
calloc(s, 365
365 ** sizeof(float));
sizeof(float));
float
float (*rainfall)[365];
(*rainfall)[365];
rainfall
rainfall == calloc(s,
calloc(s, 365
365 ** sizeof(float));
sizeof(float));
rainfall[s-1][18]
rainfall[s-1][18] == 4.3F;
4.3F;
Dynamic Data Structures
first_node
first_node == new_node(-100);
new_node(-100);
second_node
second_node == new_node(0);
new_node(0);
first_node->next_in_line
first_node->next_in_line == second_node;
second_node;
third_node
third_node == new_node(10);
new_node(10);
second_node->next_in_line
second_node->next_in_line == third_node;
third_node;
current
current == first_node;
first_node;
while(current
while(current !=!= NULL)
NULL) {{
printf("%i\n",
printf("%i\n", current->data);
current->data);
current = current->next_in_line;
current = current->next_in_line;
}}
Summary