You are on page 1of 12

Programming in C

! A brief history of C
! C as a programming language
! C Programming
"main function
"constants, variables, data types
"operators, control structures
"functions
Programming in C "data structures
"pointer arithmetic
"structures
"dynamic memory allocation
Prof. Gustavo Alonso
Computer Science Department
ETH Zürich
alonso@inf.ethz.ch
http://www.inf.ethz.ch/department/IS/iks/

©Gustavo Alonso, ETH Zürich. Programming in C 2

A brief history of C C as a programming language


! Programming languages are used to ! While writing a FORTRAN compiler for ! C has been standardized (ANSI C) and ! As we will see when we study assembler, C
specify, design, and build software UNIX, a new programming language was spawned new languages (C++, is not very far from the assembler language
systems. developed: B Stroustrup, 1986) that improve C but it provides higher level language
! Programming languages evolve with the ! B was interpreted (like Java) and, ! The basic characteristics of C are: constructs (functions, data structures)
therefore, slow. To solve the performance "small in size that facilitate programming without loosing
systems they are used to construct. C is a problems of B, a new language was
good example of how this process takes created: C "loose typing (lots of freedom, error too much performance
place. prone) Being a low level language, C gives a lot of
"allowed generation of machine code "structured (extensive use of
!
! UNIX was developed at around 1969. It (compilation) freedom to the programmer:
functions)
first version was programmed in assembler "declaration of data types "designed for systems programming "it has the advantage that good
and run on a DEC PDP-7. "definition of data structures (i.e., low level programming of the programmers can implement very
! The second version was ported to a PDP-11 ! In 1973 UNIX was rewritten in C type needed to implement an operating efficient programs in a compact
in 1971 and it was a great success: something that was never done before system) manner
"16 KB for the system "C is much easier to handle than "C is higher level than assembler but "it has the disadvantage that most of us
assembler but still close to the hardware and allows are not good programmers and the
"8 KB for user programs "first C version of UNIX was 20 to 40 direct manipulation of many system freedom C grants is usually translated
"disk of 521 KB % larger and slower than assembler aspects: pointers, memory allocation, in error prone, messy code
"limit of 64 KB per file version bitwise manipulation ...

©Gustavo Alonso, ETH Zürich. Programming in C 3 ©Gustavo Alonso, ETH Zürich. Programming in C 4
This is C The C compilation model
! The Preprocessor accepts source code as source code
#include <stdio.h> Winner of the international input and
Obfuscated C Code Contest "removes comments
main(t,_,a) preprocessor
http://reality.sgi.com/csp/iocc "extends the code according to the
char *a;
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
preprocessor directives included in the
source code (lines starting with #)
main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94, -27+t, a compiler
)&&t == 2 ?_<13 ?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main(_, ! The Compiler takes the output of the
t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\ preprocessor and produces assembly code assembly code
,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/\ ! The Assembler takes the assembly code
+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){n\ and produces machine code (or object assembler
l]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#\ code)
object libraries
n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \ ! The Linker takes the object code, joins it code
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\ with other pieces of object code and
#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/") libraries and produces code that can be linker
:t<-50?_==*a ?putchar(a[31]):main(-65,_,a+1):main((*a == '/')+t,_,a\ executed
+1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc \
executable code
i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

©Gustavo Alonso, ETH Zürich. Programming in C 5 ©Gustavo Alonso, ETH Zürich. Programming in C 6

Structure of a C program Data types


! A C program contains the following #include <stdio.h> ! C has the following basic data types
elements: #define TIMES 10 /* upper bound */
C Type Size (in bytes) Lower bound Upper bound Use
"Preprocessor Commands double myfunction(float); char 1 - - characters
"Type definitions /* Function prototype - Declaration */
unsigned char 1 0 255 small numbers
" Function prototypes -- declarations of main() { short int 2 -32768 +32767 integers
function types and arguments. double wert;
double pi = 3.14;
unsigned short int 2 0 65536 positive int
(long) int 4 − 2 31 + 2 31 − 1 large int
"Variables float 4 − 3.2⋅10 ±38
+ 3.2⋅10±38 real numbers
printf(“Multiply by 10\n”);
"Functions double 8 −1.7 ⋅10±308 +1.7 ⋅10±308 large reals
! All programs must contain a single main() wert = myfunction(pi); void 0 - - no return value
function. All function, including main, printf(“%d * %f = %f\n”,
have the following format: TIMES, pi, wert);
! The sizes of the data types are not standardized (depend on the implementation)
}
type function_name (parameters) { double myfunction(double zahl){ ! The type void is used to indicate functions that return no value or null pointers
local variables int i;
double count = 0; ! With #define, one can introduce symbolic constants
C Statements #define LIMIT 100
} count = TIMES * zahl;
return count;
}
©Gustavo Alonso, ETH Zürich. Programming in C 7 ©Gustavo Alonso, ETH Zürich. Programming in C 8
Variables and constants Type conversions (casts)
CONSTANTS VARIABLES ! In C, the type of a value can change during the run time of a program, this is known as type
! A constant specifies a value that cannot be ! A variable specifies an area of memory that conversion or type cast
modified by the program contains a value of a given type that can be ! The change can be explicit (the programmer does it) …
! Special constants for use with strings: modified by the program
short x; var_new_type = (new_type) var_old_type
\n new line long y; int a;
\t tabulator unsigned a,b; float x = (float) a;
\r carriage return long double lb; ! or implicit (the compiler takes care of it in order to perform operations among variables of
\b backspace unsigned short z; different types):
! sizeof() is a function that returns the size "char and short can be converted to int
\" escape double quote of a given variable in bytes (the size "float can be converted to double
\0 end string depends on the type of the variable "in an expression, if an argument is double, all arguments are cast to double
! Symbols defined through the preprocessor: ! Variables should be initialized before they "in an expression, if an argument is long, all arguments are cast to long
are used (e.g., in the declaration) "in an expression, if an argument is unsigned, all arguments are cast to unsigned
#define ESC '\033’ /* ASCII
escape */
otherwise the variables contain a random
value int a = 3;
float b = 5.0;
float c = a + b; /* a is transformed into double */

©Gustavo Alonso, ETH Zürich. Programming in C 9 ©Gustavo Alonso, ETH Zürich. Programming in C 10

Scope Scope (example 1)


! The scope determines where within a ! Local variables are created (space in
program a particular entity is known and memory is allocated for them) when the
can be accessed control flow in the program reaches the
block where they are declared (e.g., a
! The scope of a variable is the part of a function) and are destroyed (deallocated
program where the variable can be from memory) when the control flow leaves int global_variable;
manipulated. The scope can be global or the block
local ! The creation and destruction of variables int main () {

! Global variables are typically declared can be controlled: int local_variable;

before the main function. They can be "extern: the variable is defined in a global_variable = 1;
accessed from anywhere in the program. different module local_variable = 2;
Try to avoid global variables (a matter of "static: for local variables: makes them
programming style) last the entire program, for global {
variables: restricts the scope to the int very_local_variable;
! Local variables are valid and visible within current module very_local_variable = 3;
a particular block (a block is a set of C "register: try to use a CPU register for
}
statements enclosed within brackets { the variable
…}). Once the control flow is outside "auto: default for local variables
the block, the variable no longer exists }

©Gustavo Alonso, ETH Zürich. Programming in C 11 ©Gustavo Alonso, ETH Zürich. Programming in C 12
Expressions and priority Short-hand operators
! C allows for a short hand notation that introduces side effects. This is done through the
! +, -, *, /, % are the basic arithmetic ! Multiplication operators (*, /, %) have a prefix- or postfix operators ++, --
operators higher priority than the additive operators
Addition ! If ++ or -- are used as prefixes, the variable is modified before it is used in the evaluation
! (+, -). When evaluating an expression, of an expression:
x = 3 + 4; operators with a higher priority are
! Subtraction evaluated first:
x = 10 - 3; a = 3;
! Multiplikation x = 2 + 3 / 2 + 3; b = ++a + 3; /* b = 4 + 3 = 7 and a = 4 side effect */
/* x = 2 + 1 + 3 */
x = 3 * 4;
! Division x = (2 + 3) / (2 + 3); ! If ++ or -- are used as postfixes, the variable is first used to evaluate the expression and
x = 73 / 8; /* x = (5 / 5) = 1 */ then modified.
/* x=9, if int x */
x = 73.0 / 8.0; x = 4*(1/2); /* x = 0 */ a = 3;
/*x=9.125,if float x */ x = 4*1/2; /* x = 2 */ b = a++ + 3; /* b = 3 + 3 = 6 and a = 4 */
! Modulo
x = 73 % 8;
/* x=1, the reminder of the
! Almost all operators can be combined with =
division */ a += b; /* a = a + b */
a *= b; /* a = a * b */

©Gustavo Alonso, ETH Zürich. Programming in C 13 ©Gustavo Alonso, ETH Zürich. Programming in C 14

Bit-Operators Shift Operators


! The Bit-Operators & (AND), ^(Exclusive-OR), and | (Inclusive-OR) manipulate bits ! << and >> are used to manipulate the position of the bits in a byte or a word
according to standard two valued logic ! With a >> b the bits in the variable a are displaced b positions to the right (the new bits
are filled with 0).
Bit1 Bit2 Bit1 & Bit2 Bit1^Bit2 Bit1|Bit2
0 0 0 0 0 MSB a LSB a / = 2b a >> 3

0 1 0 1 1 1 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1

1 0 0 1 1
1 1 1 0 1
! With a << b the bits in the variable a are displaced b positions to the left (the new bits
are filled with 0).
! With & one can set bits to 0. a a* = 2 b a << 3
! With ^one can reverse the valu of bits (0 becomes 1 and 1 becomes 0) 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0
! With | one can set bits to 1.

©Gustavo Alonso, ETH Zürich. Programming in C 15 ©Gustavo Alonso, ETH Zürich. Programming in C 16
Comparison and logical operators if statement
! The comparison operators return a 1 or a 0 depending on the result of the comparison. The ! The if – then – else statement can be
comparison operators in C are used with or without the else. The two
forms are: true false
if (expression) expression
"< (smaller than)
statement1
"> (greater than) Statement 1 Statement 2
"<= (smaller or equal than) if (expression)
">= (greater or equal than) statement1
"== (equal than) else
statement2
"!= (not equal than) if (a >= 3) a = a - 3;
if (a == 3) a = a * 3;
! In both cases, when the expression is true, else a = a * 5;
! && and || are the logical AND and OR operators then statement1 is executed. If the
( a != b) && (c > d) expression is false, then, in the first case,
(a < b) || (c > d) statement1 is skipped (not executed), and,
in the second case, statement2 after the if (a >= 3) { a = a - 3;
else is executed. if ( a == 3) a = a * 3;}
else a = a * 5;

©Gustavo Alonso, ETH Zürich. Programming in C 17 ©Gustavo Alonso, ETH Zürich. Programming in C 18

switch statement (1) Switch statement (2)


! The switch statement is used to
conditionally perform statements based on Switch without break
Switch using break
an integer expression (selector)
selector selector
switch (selector) {
case int-value1 : statement1; break; switch (selector) {
int–value 1 true
case int-value1 : statement1; int–value 1 true
case int-value2 : statement2; break; = selector Statement 1
= selector Statement 1
case int-value3 : statement3; break; false case int-value2 : statement2;
false
default: statement4; int–value 2 true case int-value3 : statement3;
Statement 2 int–value 2 true
} = selector default: statement4; = selector Statement 2
! The exact behavior of the switch statement false
is controlled by the break and default } false
int–value 2 true
commands = selector Statement 3
/* fall through */ int–value 2 true
Statement 3
"break continues execution after the = selector
false
switch statement false
Statement 4
"default is executed if no other match
is found Statement 4

©Gustavo Alonso, ETH Zürich. Programming in C 19 ©Gustavo Alonso, ETH Zürich. Programming in C 20
Switch (example) for statement
char a = ‘A’; a = ‘A’; ! The for statement provides a compact way
switch (a) { switch (a) { to iterate over a range of values.
case ‘A’: x *= x; break; case ‘A’: x *= x; for (initialization; termination; increment) { initialization
case ‘B’: x /= x; break; case ‘B’: x /= x; statement
default: x += 5; default: x += 5; }
} } termination increment
! All elements in the for loop are optional: true
for (; ; ); false
! Once the case ‘A’ is found, x *= x is ! Once case ‘A’ is found, x *= x is ! break can be used to interrupt the loop statement
executed and then we continue after the executed. However, there is no break. This without waiting for the termination
switch statement. in all cases, only one means we continue executing statements condition to evaluate to true
case will be executed (either ‘A’ or ‘B’ or while ignoring the cases (the check is not
‘default’) performed anymore). Thus, the following ! continue can be used to skip execution of
! Note that a is of type char. It does not statements will also be executed the body of the loop and re-evaluate the for (int x =0; x < 100; x = x + 3){
matter, char is treated as an integer using termination condition if (x == 27) continue;
x /= x; else printf(“%d”,x);
type conversion }
x += 5;

©Gustavo Alonso, ETH Zürich. Programming in C 21 ©Gustavo Alonso, ETH Zürich. Programming in C 22

while statement Do-while statement


! The while statement is used to continually ! The do-while is similar to the while
execute a block of statements while a statement except that the loop is always
condition remains true. executed once and the condition is checked
true at the end of each iteration.
expression statement statement
while (expression) { do {
statement false statement
} } while (expression) true
expression
! As before, break and continue can be used main() {
to terminate the loop or to finish an break and continue have the same effect as false
iteration and go back to the evaluation of char t; !
the expression while((t = getchar()) != ‘!’) { before
if (t >= ‘A' && t<= ‘Z')
! for and while are equivalent (can you do printf("%c\n", (char)(t+’a'-’A'));
it? write a for loop using the while
statement and vice versa) else
printf( "%c\n", (char)t);
}
}
©Gustavo Alonso, ETH Zürich. Programming in C 23 ©Gustavo Alonso, ETH Zürich. Programming in C 24
Odd ends Arrays
exit () Goto ! An array is a finite set of variables of the #include <stdio.h>
exit() terminates the execution of the same basic type float data[5]; /* data to average and total */
! ! C was written as a language that is one
program passing an integer error code. e.g. step above assembly language. This can be ! Instead of giving each variable a name, we
float total; /* the total of the data items */
0 -> no error, 1 -> not found, 99 -> seen, for instance, on the existence of a use enumeration and group all of them in
float average; /* average of the items */
crash
goto statement an array main() {
! exit() is a very primitive way to terminate
a program and one that leaves only very ! Do not use goto when programming. There ! The enumeration of elements within an data[0] = 34.0;
limited chance to deal with failures. More are very good reasons to avoid it: array always starts with 0. If the array has data[1] = 27.0;
modern programming languages use "Style: avoid spaghetti code N elements, the last element is in position data[2] = 45.0;
exceptions and exception propagation N-1 data[3] = 82.0;
mechanisms to indicate the occurrence of "Use of stack frames data[4] = 22.0;
an error without having to terminate the ! The C compiler does not check the array
program boundaries total = data[0] + data[1] + data[2] + data[3] +
"this is a very typical error that it is data[4];
if (!(buf = AllocMem (BufSize);)) { very difficult to find (usually happens average = total / 5.0;
inside loops that traverse the array) printf("Total %f Average %f\n", total, average);
printf(“kein Speicher vorhanden"); return (0);
exit(NO_MEM); "always check the array boundaries }
} before accessing a variable in an array

©Gustavo Alonso, ETH Zürich. Programming in C 25 ©Gustavo Alonso, ETH Zürich. Programming in C 26

Multi-dimensional arrays Array traversals (examples)


int a[3][3]
int array[5][5]; int array[5][5];
MEMORY
1 2 3 4 5 6 7 8 9 for (int i=0; i < 5; i++) for (int i=0; i < 5; i++)
for (int j=0; j < 5; j++) for (int j=0; j < i; j++)
array[i][j] = 1;
a[0][0] a[0][1] a[0][2] a[1][0]a[1][1] a[1][2]a[2][0] a[2][1] a[2][2]
array[i][j] = 1;
int a = 1;
for (i=0; i < 3; i++) inner loop traversal inner loop traversal
for (j=0; j < 3; j++) j j
matrix[i][j] = a++; 0 1 2 3 4 0 1 2 3 4
i i
outer loop traversal

outer loop traversal


0 0
1 2 3 4 5 6 7 8 9
1 1
2 2
int a = 1;
for (i=0; i < 3; i++) 3 3
for (j=0; j < 3; j++) 4 4
matrix[j][i] = a++;

1 4 7 2 5 8 3 6 9
©Gustavo Alonso, ETH Zürich. Programming in C 27 ©Gustavo Alonso, ETH Zürich. Programming in C 28
More on arrays Pointers
! Arrays can be initialized when they are ! Strings are arrays of characters terminated ! A variable has a name, an address, a type, ! Pointers are used with the * and &
defined: with the null character \0 and a value: operators:
"the name identifies the variable to the int* px; /*px = pointer to an integer*/
/* a[0] = 3, a[1] = 7, a[2] = 9 */ char str[6] = {‘h’,’a’,’l’,’l’,’o’,’\0’} programmer
int a[3] = {3, 7, 9}; "the address specifies where in main int x; /*x is an integer */
char str[6] = "hello"; memory the variable is located (i.e.,
/* liste[0]=0.0, …, liste[99]=0.0 */ the beginning of the memory region
float list[100] = {}; ! For string manipulation, however, use the reserved for this variable ) px = &x; /* px gets the address of x */
string.h library "the type specifies how to interpret the /* or px points to x */
int a[3][3] = { ! In C, arrays are just a syntactic data stored in main memory and how
{ 1, 2, 3} convenience to make programming easier. long the variable is x = *px; /* x gets the contents of */
{ 4, 5, 6} Arrays are, for the compiler, the same as "the value is the actual data stored in
{ 7, 8, 9}
/* whatever x points to */
pointers (the array name is a pointer to the variable after if has been
}; the beginning of the array) interpreted according to a given type
! Pointers are language constructs that allow
programmers to directly manipulate the
1 2 3 4 5 6 7 8 9 address of variables

©Gustavo Alonso, ETH Zürich. Programming in C 29 ©Gustavo Alonso, ETH Zürich. Programming in C 30

Pointers (I) Pointers (II)


int* int int* int
*nummer_ptr = 7;
int nummer = 3;
int* nummer_ptr = NULL; 0 3 7
nummer_ptr nummer nummer_ptr nummer

int* int
*nummer = 8; /* CAREFUL, 8 is not a pointer but an integer */
nummer_ptr = &nummer;

3
nummer_ptr nummer

int int* int


int* int
nummer = 5;

5
int x = *nummer_ptr;
7 7
x nummer_ptr nummer
nummer_ptr nummer

©Gustavo Alonso, ETH Zürich. Programming in C 31 ©Gustavo Alonso, ETH Zürich. Programming in C 32
Pointers (III) Pointers (IV)
int int* int

int* y_ptr = nummer_ptr;


7 7
x nummer_ptr nummer int int* int
int*
y_ptr = &x;
7 6
x nummer_ptr nummer
y_ptr int*

int int* int

*y_ptr = 6;
7 6 y_ptr

x nummer_ptr nummer
int*

©Gustavo Alonso, ETH Zürich. y_ptr Programming in C 33 ©Gustavo Alonso, ETH Zürich. Programming in C 34

Pointers (V) Pointers (VI)


int** int**

p_ptr_ptr p_ptr_ptr

int int* int int int* int

int* *p_ptr_ptr; *(*p_ptr_ptr) = 5;

p_ptr_ptr = &nummer_ptr; 7 6 7 5
x nummer_ptr nummer x nummer_ptr nummer
int* int*

y_ptr y_ptr

©Gustavo Alonso, ETH Zürich. Programming in C 35 ©Gustavo Alonso, ETH Zürich. Programming in C 36
Pointers, arrays and strings Troubles with pointers
! An array is in reality a pointer: ! Strings can be manipulated through What is printed by the following code? What is printed by the following code?
int a[10], y; pointers:
char* message; #include <stdio.h> #include <stdio.h>
int* px; void f(int *aa, int *bb) { void g(int *aa, int *bb) {
px = a; /* px points to a[0] */ message = “This is a string”;
*bb = 8; bb[2] = aa[-2];
px++; /* px points to a[1] */ ! message is a pointer that now points to the aa[1] = bb[2]; *aa++ = 17;
px=&a[4]; /*px points to a[4] */ first character in the string “This is a aa = bb; *++aa = 10;
string” } }
y = *(px+3) /*y gets the value*/ ! Again, use the string.h for string
/* in a[3] */ manipulation rather than doing it directly main() { main() {
! The pointer arithmetic in C guarantees that (you will avoid many errors) int a[5] = { 1, 2, 3, 4, 5 }, *b; int blap[7] = { 1, 2, 3, 4, 5, 6, 7 };
if a pointer is incremented or decremented, b = a + 2; int *c = blap + 3;
the pointer will vary according to its type. f(a,b); g(c,blap);
For instance, if px points to an array, printf("%d %d %d %d %d\n", printf("%d %d %d %d %d %d %d\n",
px++ will always yield the next element a[0], a[1], a[2], a[3], a[4]); blap[0], blap[1], blap[2], blap[3],
independently of what is the type stored in
} blap[4], blap[5], blap[6]);
the array
}

©Gustavo Alonso, ETH Zürich. Programming in C 37 ©Gustavo Alonso, ETH Zürich. Programming in C 38

Structures Example structures


! Structures allow programmers to define ! Access to the elements of a structure is as
complex data types. A structure is a new follows: int main () {
(user defined) data type: ethz.name = “Gustavo”; struct Typ_kiste {
ethz.telefon = 1234567; char inhalt[50]; /* was ist in der Kiste */
struct Id_card { ! Pointers can also refer to structures, in int anzahl; /* wieviel davon */
char name[100]; /* Name */ which case elements are accessed through float preis; /* was kostet eine Einheit */
char adresse[100]; /*Address */ the ->, or * operators: };
short int geburtsjahr; /*Geburtsjahr*/
int telefon; /* Telefonnummer */
struct Id_card *pid;
short int semester; /* Semester */ pid = &ethz_student; float wert;
const int MAX_KISTEN = 10;
} ethz, uniz; pid->name = “Gustavo”; struct Typ_kiste liste_kisten[MAX_KISTEN];
pid->telefon = 1234567;
struct Id_card erasmus; (*pid).name = “Gustavo”; /* Initialisierung … */
(*pid).telefon = 1234567;
! Structures of the same type can be copied ! In ANSI C, structures can be passed as /* Gesammter Wert */
with the operator = but they should not arguments (by value or by reference) and for (int i = 0; i < MAX_KISTEN; i++)
be compared with == can also be the return type of a function wert += liste_kisten[i].anzahl * liste_kisten[i].preis;
(this is not true in earlier versions of C) …
}

©Gustavo Alonso, ETH Zürich. Programming in C 39 ©Gustavo Alonso, ETH Zürich. Programming in C 40
struct Functions
! C is a modular language where the main ! General syntax:
unit of composition is the function
inhalt
char[50]
inhalt
char[50]
inhalt
char[50] ! A function has the following elements: returntype function_name(def of parameters) {
"a return type: specifies the type of the localvariables
value returned by the function when it functioncode
anzahl anzahl anzahl terminates }
"a function name: identifies the
int int int
function for the programmer ! An example:
preis preis preis "arguments of defined types: float findaverage(float a, float b) {
float float float ... parameters to pass to the function, float average;
which can be
average=(a+b)/2;
liste_kisten[0] liste_kisten[1] liste_kisten[2] • by value: the function gets the a return(average);
copy of the value of the }
liste_kisten[0].inhalt liste_kisten[1].inhalt liste_kisten[2].inhalt parameters but cannot modify the
liste_kisten[0].anzahl liste_kisten[1].anzahl liste_kisten[2].anzahl actual parameters
! In ANSI C functions must be declared as prototypes
liste_kisten[0].preis liste_kisten[1].preis liste_kisten[2].preis • by reference: the function gets the before they are defined:
address (reference) of the float findaverage(float a, float b)
parameters and can modify them

©Gustavo Alonso, ETH Zürich. Programming in C 41 ©Gustavo Alonso, ETH Zürich. Programming in C 42

Examples main() is also a function


/* SWAP.C exchange values */ /* program to print arguments from command line */ \* append one file to the another */
#include <stdio.h> \* FACTORIAL *\ #include <stdio.h> #include <stdio.h>
void swap(float *x, float *y); /* prototype */ \* fact(n) = n*(n-1)*....2*1 *\ main(int argc, char **argv) {
main() { main(int argc, char **argv) { int c;
#include <stdio.h> FILE *from, *to;
float x, y; int i; if (argc != 3) { /* Check the arguments. */
printf("Please input 1st value: "); fprintf(stderr, "Usage: %s from-file to-file\n", *argv);
scanf("%f", &x); fact(n) { printf("argc = %d\n\n",argc); exit(1);
printf("Please input 2nd value: "); int n; for (i=0;i<argc;++i) }
scanf("%f", &y); if (n == 0) return(1); printf("argv[%d]: %s\n",i, argv[i]); if ((from = fopen(argv[1], "r")) == NULL) {
printf("Values BEFORE 'swap' %f, %f\n", x, y); return(n * fact(n-1)); } perror(argv[1]); /* Open the from-file */
swap(&x, &y); /* address of x, y */ } exit(1);
}
printf("Values AFTER 'swap' %f, %f\n", x, y);
main() { ! argc stands for argument count and it if ((to = fopen(argv[2], "a")) == NULL) {
return 0;
int n, m; contains how many arguments have been perror(argv[2]); /* Open the to-file */
} passed in the command line when the exit(1);
printf("Enter a number: "); program is invoked }
/* exchange values within function */ /* Read one file and append to the other until EOF */
void swap(float *x, float *y) { scanf("%d", &n); ! argv is the argument vector (array) and it while ((c = getc(from)) != EOF)
float t; m = fact(n); contains all the arguments passed through putc(c, to);
t = *x; /* *x is value pointed to by x */ printf(”Factorial of %d is %d.\n", n, m); the command line /*close the files */
*x = *y; exit(0); ! argc is always at least 1 since argv[0] is fclose(from);
} fclose(to);
*y = t; the name of the program exit(0);
printf("Values WITHIN 'swap' %f, %f\n", *x, *y); }
}
©Gustavo Alonso, ETH Zürich. Programming in C 43 ©Gustavo Alonso, ETH Zürich. Programming in C 44
Dynamic memory allocation Example dynamic array
! The definition of types and variables help typedef struct node { /* This program simply reads integers into a dynamic /* Read in the numbers. */
the compiler to understand the program we int x,z; array until eof. The array is expanded as needed */ num = 0;
struct node *next; while(scanf("%d", &in) == 1) {
have written /* See if there's room. */
} NODE; #include <stdio.h>
! The declaration of variables leads to the #include <stdlib.h> if(num >= arrsize) {
/* There's not. Get more. */
allocation of memory for those variables. NODE *nptr; #define INIT_SIZE 8 /* Initial array size. */ arrsize *= 2;
In general, this happens automatically and if ((nptr =((NODE)*) malloc(sizeof(NODE))) main() { arr = (int*) realloc(arr, arrsize*sizeof(int));
without intervention of the programmer == NULL) { int num; /* Number of integers */ if(arr == NULL){
printf("No memory - bye bye"); exit(99); int *arr; /* Array of integers. */ fprintf(stderr, "Allocation failed %d.\n");
! C allows the programmer to allocate and } int arrsize; /* The size of the array of integers. */ exit(18);
deallocate memory dynamically int m; /* Index. */ }
int in; /* Input number. */ }
! The functions used for memory allocation ! malloc returns a pointer to the allocated
are in stdlib.h memory. The pointer is generic (void *) /* Allocate the initial space. */
/* Store the number. */
arr[num++] = in;
! Typical function calls are and it is a good practice to cast the pointer arrsize = INIT_SIZE; }
to the appropriate pointer type to avoid arr = (int*) malloc(arrsize*sizeof(int));
"malloc errors. /* Print out the numbers. */
"free ! Allocated memory must be returned to the for(m = 0; m < num; ++m)
printf("%d\n", arr[m]);
system: }
free(nptr);

©Gustavo Alonso, ETH Zürich. Programming in C 45 ©Gustavo Alonso, ETH Zürich. Programming in C 46

Example string library References


#include <stdio.h> printf("The biggest name alphabetically is %s\n", mixed); Some material for these foils and some of the examples have been taken from the following on-
#include <string.h>
line books on C (there are many more):
strcpy(mixed, name1);
void main() { strcat(mixed, " ");
char name1[12], name2[12], mixed[25]; ! C Programming, Steve Holmes: http://www.strath.ac.uk/IT/Docs/Ccourse/
strcat(mixed, name2);
char title[20];
printf("Both names are %s\n", mixed); ! C language tutorial: http://www.graylab.ac.uk/doc/tutorials/C/index.htm
strcpy(name1, "Rosalinda"); }
strcpy(name2, "Zeke");
! Programming in C , A. D. Marshall: http://www.cs.cf.ac.uk/Dave/C/CE.html
strcpy(title, "This is the title.");
For how C was developed, read the tutorial written by Brian W. Kernighan in 1974:
printf(" %s\n\n", title);
printf("Name 1 is %s\n", name1);
printf("Name 2 is %s\n", name2); This is the title. ! Programming in C: A Tutorial, B. W. Kernighan:
if(strcmp(name1, name2) > 0)
http://www.lysator.liu.se/c/bwk-tutor.html
/* returns 1 if name1 > name2 */ Name1 is Rosalinda
strcpy(mixed, name1); Name2 is Zeke
else The biggest name alphabetically is Zeke
strcpy(mixed, name2); Both names are Rosalinda Zeke

©Gustavo Alonso, ETH Zürich. Programming in C 47 ©Gustavo Alonso, ETH Zürich. Programming in C 48

You might also like