0% found this document useful (0 votes)
2 views

Lecture C 03

The document provides an overview of the C Standard Library, detailing its components such as the ISO C Standard and POSIX C Library, which includes functions for input/output, math, string manipulation, and memory management. It explains key header files like stdio.h and stdlib.h, along with their functions for file operations and memory management. Additionally, it covers mathematical functions from math.h and complex.h, string manipulation functions from string.h, and the use of preprocessor directives for including header files and defining constants.

Uploaded by

Mohamed Askar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Lecture C 03

The document provides an overview of the C Standard Library, detailing its components such as the ISO C Standard and POSIX C Library, which includes functions for input/output, math, string manipulation, and memory management. It explains key header files like stdio.h and stdlib.h, along with their functions for file operations and memory management. Additionally, it covers mathematical functions from math.h and complex.h, string manipulation functions from string.h, and the use of preprocessor directives for including header files and defining constants.

Uploaded by

Mohamed Askar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

This Lecture:

Advanced C Topics II
Introduction to the Standard Library
The ISO C Standard
Introduction to the Standard Library
The ISO C Standard

▶ defines a standard library to provide basic functions on every platform and allows portable
programming
▶ consists of about 20 different header files
▶ around 200 function for input/output, basic math, string manipulation, and memory
management

POSIX C Library
▶ important extension to the standard C library
▶ provides more operating system dependent operations
▶ contains functions for networking, inter process communication, threading, and many more

Starting with the C11 standard, threading has also become part of the standard C library.
stdio.h and stdlib.h
Introduction to the Standard Library
stdio.h and stdlib.h

These two headers files provide the basic functionality of the C library. They provide
input/output operations, control statements, and memory management.
The file-io operations will be demonstrated by examples in a separate section.

The input/output functions introduced later in this section contain format strings determining
what is to be read or printed. These format strings contain format specifiers for the
representation of the variables contents. They will be introduced first.
Introduction to the Standard Library
stdio.h and stdlib.h

d integers of the type int


ld integers of the type long
u integers of the type unsigned int
g float pointing numbers of the type float or double
e float pointing number in [-]d.ddde+dd notation
c a single character of type char
s strings (see Section 2.4 in lecture notes)
% the % sign.
The full format specification has the form
% [flags][width][.precision][l]type

The [l]type part is what is shown above. The [flags] influence the alignment and
printing of signs. All bracketed specifiers are optional.
Introduction to the Standard Library
stdio.h and stdlib.h

Example

double pi = 3.14159265;
printf("pi = %8.6g\n",pi);

prints:
pi = 3.141593

Note that the decimal dot is consuming one of the 8 digits.


The placeholders and modifiers are described in man 3 printf
Introduction to the Standard Library
stdio.h and stdlib.h

int printf(const char *formatstring, arguments, ...);


int fprintf(FILE *f, const char *formatstring, arguments, ...);
int sprintf(char *buf, const char *formatstring, arguments, ...);

The printf-function writes a text to the standard output. The fprintf-function is the
equivalent for files, whereas sprintf stores the result in the output string buf. The
return-value is the number of characters written.

stdio.h defines stdout and stderr file descriptors to use fprintf for printing output
and error messages separately.
Introduction to the Standard Library
stdio.h and stdlib.h

int scanf(const char *formatstring, arguments, ...);


int fscanf(FILE *f, const char *formatstring, arguments, ...);
int sscanf(const char *string, const char *formatstring, arguments, ...);

▶ scanf-function reads a formatted input from the standard input. This is the keyboard in
most cases. The arguments are pointers to the variables where the values read from the
input are stored.
▶ fscanf-function is the equivalent to read data from a file.
▶ sscanf reads from another string.
▶ fscanf stops reading when either the end of a line, or the end of the file is reached.
▶ sscanf terminates upon reaching the 0-byte.
Introduction to the Standard Library
stdio.h and stdlib.h

FILE *fopen(char *filename, char *mode);

The fopen-function opens the file specified by the filename and returns a pointer to the
file stream. mode is a string determining the access to the file:
Mode Meaning Remarks
r open for reading Only possible if the file exists otherwise
NULL is returned.
w create a file for writing If the file already exists the content is
destroyed.
a append data to a file If the file already exists, the new data
is appended to the end. If it does not
exist, the behavior is like ”w”.
fopen returns NULL in case of an error.
Introduction to the Standard Library
stdio.h and stdlib.h

int fclose(FILE *stream);

The fclose-function closes a given file stream. Any buffered data is written to the file. The
stream is no longer associated with the file.

int feof(FILE *stream);

The feof-function returns true if the given file stream reached the end of the file otherwise
false is returned.

void perror(const char *s);

The perror-function displays the most recent error from the C library. The string s is used as
a prefix to the error message.
Introduction to the Standard Library
stdio.h and stdlib.h

void *malloc(size_t size);


void *realloc(void *ptr, size_t new_size);
void free(void *ptr);

The memory management functions explained earlier.

void abort();
void exit(int exit_code);

▶ abort terminates a program immediately without any clean up


▶ exit terminates a program immediately with clean up

int atoi(char *s):


double atof(char *s);

The atoi-function converts a string to an integer if possible. The atof-function does the
same with a floating point number.
math.h and complex.h
Introduction to the Standard Library
math.h and complex.h

math.h and complex.h


▶ Provide common mathematical functions and constants
▶ A program that uses at least one of them needs to be linked with -lm
▶ All of the following functions take double arguments and produce double return values
Introduction to the Standard Library
math.h and complex.h

fabs(x) absolute value of x


exp(x) returns e x
exp2(x) returns 2x
log(x) returns ln x
log10(x) returns log10 x
log2(x) returns log2 x

sqrt(x) returns px
hypot(x,y) returns x 2 + y 2
pow(x,y) returns x y
sin(x) returns sin x
cos(x) returns cos x
tan(x) returns tan x
asin(x) returns sin−1 x
acos(x) returns cos−1 x
atan(x) returns tan−1 x
Introduction to the Standard Library
math.h and complex.h

▶ The C99 standard introduces the data types float complex and double complex
for handling complex numbers.
▶ The header file complex.h defines these data types along with the imaginary unit as I
and the following functions for double precision complex arguments and return values.
Introduction to the Standard Library
math.h and complex.h

creal(x) real part of x


cimag(x) imaginary part of x
carg(x) computes the phase angle of a complex number
cabs(x) computes the magnitude of a complex number
conj(x) returns x̄
cexp(x) returns e x
clog(x) returns ln x

csqrt(x) returns x
cpow(x,y) returns x y
csin(x) returns sin x
ccos(x) returns cos x
ctan(x) returns tan x
casin(x) returns sin−1 x
cacos(x) returns cos−1 x
catan(x) returns tan−1 x
Introduction to the Standard Library
math.h and complex.h

▶ The list of mathematical functions presented here is not complete.


▶ More can be found in the man pages or the C standard.
▶ For nearly all double precision functions there exists a corresponding single precision
function with an f as suffix.
▶ For example the single precision square root is computed by sqrtf(x).

Some predefined constants are:


M PI π = 3.14159265358979323846
π
M PI 2 2 = 1.57079632679489661923
M E e√= 2.7182818284590452354
M SQRT2 2 = 1.41421356237309504880
string.h
Introduction to the Standard Library
string.h

The string.h-header file contains various functions to manipulate and work with strings.
The important ones are:
size_t strlen(char *s);

The strlen-function returns the length of the string not including the terminating 0
character.
char *strcpy(char *dest, char *src);

▶ Copies a string from src to dest and returns the dest pointer.
▶ dest needs to be a preallocated string with at least strlen(src)+1 elements.
▶ The destination string is not 0-terminated if the source string does not contain the 0-byte
within the length of the destination string.
▶ The behavior in case the destination is to short is unspecified and may depend on the
actual implementation of the compiler.
Introduction to the Standard Library
string.h

char *strcat(char *dest, char *src);

The strcat-function appends the string from src to dest and returns the dest pointer
again. dest needs to be a preallocated string with at least
strlen(src)+strlen(dest)+1 elements.

int *strcmp(char *lhs, char *rhs);

The strcmp-function compares two strings lexicographically. It returns a negative value if


lhs < rhs, a positive value if lhs > rhs and 0 if they are equal.
Additional Memory Manipulation Functions in string.h
Introduction to the Standard Library
Additional Memory Manipulation Functions in string.h

Beside the string operations string.h defines a variety of memory actions like:

void *memcpy(void *dest, void *src, size_t n);

The memcpy-function copies n bytes from src to dest and returns the dest pointer again.
dest needs to be preallocated with n bytes. src and dest must not overlap each other.
memmove does the same but allows overlapping. It is slower than memcpy.

void *memset( void* dest, int ch, size_t count );

The memset-function converts the value ch to an unsigned char and copies it into each
of the first count characters of the location referred by dest.
File I/O
Examples
File I/O
Examples

fopen
opens a specified file in the desired mode. To avoid undefined behavior we have to check if
NULL was returned.

Example
We create file "test.txt" for writing:
FILE *fp;
fp = fopen("test.txt","w");
if ( fp == NULL ) {
perror("can not open test.txt for writing.");
return -1;
}

If we want to read data from a file we have to use "r" instead.


File I/O
Examples

The fprintf and fscanf functions in the following are only useful for human readable files.
For individual access to binaries we refer to fread, fwrite and other functions from
stdio.h.

Example
The access modes "w" and "a" open files for writing. fprintf is used like printf on this
file:
int x = 10;
double y = 145.1;
fprintf(fp, "x = %d , y = %lg\n", x, y);
File I/O
Examples

The access mode "r" allows fscanf to read data from it. If the feof()-function evaluates
to true, no more data can be read from the file.
Example
We consider a human-readable file with the following layout:

x1 y1
x2 y2
...
File I/O
Examples

Example
The code-snippet to read all values and print them to the screen will be:
FILE *fp;
double x, y;
fp = fopen("test.txt","r");
if ( fp == NULL ) {
perror("can not open test.txt for reading.");
return -1;
}
while (!feof(fp)){
fscanf("%g %g",&x,&y);
printf("x=%g \t y=%g\n",x,y);
}

After reading or writing to a file it needs to be closed by fclose(fp).


The Preprocessor and Header Files
#include
The Preprocessor and Header Files
#include

▶ used to include other files into the current source code


▶ mostly used for header files of libraries containing function-headers, data-structures or
constants
▶ entire content of the included file is temporarily copied to the position of the
include-statement

Two Versions of Includes



#include <header.h>

searches default include path and all directories specified with -I at the gcc command
line for header.h

#include "header.h"

checks the local project directory and can also be used to include other .c-files.
#define
The Preprocessor and Header Files
#define

1.) Constants:
Example
The preprocessor statements:
#define PI 3.14519
#define SQRT2 sqrt(2)

will replace any occurrence of PI with 3.14159 and of SQRT2 with sqrt(2) in the current
source file.
The Preprocessor and Header Files
#define

2.) Preprocessor Macros


Example
The following macro will give the absolute value of the parameter:
#define ABS(X) (((X)>0)?(X):(-(X)))

This replaces y = ABS(z+1); with:


y = (((z+1)>0)?(z+1):(-(z+1)));

If X is not enclosed with parentheses this is evaluated to:


y = ((z+1>0)?z+1:-z+1));

This is not the desired behavior because the minus in the second part is only applied to z and
not to the whole expression as it was intended.
The Preprocessor and Header Files
#define

3.) boolean variables for the #ifdef-statement.


▶ evaluates to true when the define exists
▶ preprocessor variables can be set using the -D command line option of the compiler, i.e.,
gcc -DDEBUG ..., makes the Macro-variable DEBUG set, i.e., evaluate to true, in the
preprocessor.
The Preprocessor and Header Files
#define

3.) boolean variables for the #ifdef-statement.


▶ evaluates to true when the define exists
▶ preprocessor variables can be set using the -D command line option of the compiler, i.e.,
gcc -DDEBUG ..., makes the Macro-variable DEBUG set, i.e., evaluate to true, in the
preprocessor.

Remark
The preprocessor acts stupid on all replacements of define. It does not check whether or not
the resulting code is valid C code. The programmer has to make sure that the define
statements are extended to correct C code.
#ifdef
The Preprocessor and Header Files
#ifdef

ifdef-directive
▶ allows conditional compiling of the source code
▶ works like the if-else construct, but is evaluated by the preprocessor at compile time

#ifdef PREPROCESSOR_DEFINE
// Code compilied if PREPROCESSOR_DEFINE exitsts
#else
// Code compiled otherwise
#endif

This technique is used to handle different environment situations in a single source file
The Preprocessor and Header Files
#ifdef

Example
In order to debug a program easily somebody defined an INFO-macro which prints the given
parameter to the screen. In the final version of the program this is not necessary. However,
removing all outputs in the code may be unwanted to be able to insert them again for later
debugging purposes:
#ifdef DEBUG
#define INFO(X) printf(X)
#else
#define INFO(X)
#endif

If DEBUG is defined the INFO-macro is expanded to a printf-statement, otherwise it is


replaced with nothing.

The #ifndef statements is the opposite of #ifdef. It simply negates the condition of the
#ifdef statement.
Header-Files
The Preprocessor and Header Files
Header-Files

Header-Files
▶ tell the compiler which functions, data-structures, and constants exist in other source files
▶ compiler can only check the function headers and the calling sequence in the current file
▶ similar to a normal source file but consist only of definitions
▶ come without any implementation

Cyclic inclusions should be avoided using the preprocessor commands #define and #ifndef
The Preprocessor and Header Files
Header-Files

Example
exfct.c implements the function something:
#include <math.h> // for sqrt
#include "exfct.h" // Ensure that the function header
// fits to the one from exfct.h
double something(double x, double y, double z){
return sqrt(x*x+y*y+z+z*z);
}
The Preprocessor and Header Files
Header-Files

Example
exfct.h contains:
▶ the function header (its signature)
▶ a preprocessor trick preventing double inclusion in one file:

#ifndef EXFCT_H
#define EXFCT_H
double something(double x, double y, double z);
#endif

The main program can now include the header and knows how the function something is
called correctly.
Makefiles
Make
Makefiles
Make

▶ automates build procedures


▶ controlled by a textfile usually called Makefile
▶ Makefile contains the build instructions and interdependencies
▶ deals with dependencies
▶ only recompiles files that really changed

Different Vendor Versions


▶ GNU Make
▶ BSD Make
▶ Microsoft nmake
Makefiles
Make

Makefile
▶ works as a simple dependency tree
▶ compiles the files that are outdated in the order they depend on each other
▶ consists of so called targets, which may depend on each other

A target is defined by a rule:


targetname: dependencies
command1
command2
...

The indentation in front of the commands must be a <tab> and not spaces!
Makefiles
Make

Makefile
▶ works as a simple dependency tree
▶ compiles the files that are outdated in the order they depend on each other
▶ consists of so called targets, which may depend on each other

A target is defined by a rule:


targetname: dependencies
command1
command2
...

The targetname should be equal to or closely related to the output file generated by the
commands.
Makefiles
Make

Makefile
▶ works as a simple dependency tree
▶ compiles the files that are outdated in the order they depend on each other
▶ consists of so called targets, which may depend on each other

A target is defined by a rule:


targetname: dependencies
command1
command2
...

dependencies is a space separated list of other targets that need to be compiled prior to the
target or names of files which need to exist.
Makefiles
Make

Example
Consider a small software project consisting of main.c, file1.c and file1.h. A makefile
to create the final program prog looks like:
prog: main.c file1.c file1.h
gcc -c main.c
gcc -c file1.c
gcc -o prog main.o file1.o

If the makefile is named Makefile or makefile, use:


make targetname

If the makefile has another name, use:


make -f makefilename targetname

If no targetname is specified, the first one in the makefile is used.


Makefiles
Make

Variables
▶ make supports definition of variables
▶ often they contain lists of files
▶ or they are used to inherit compiler settings from include files

A variable is set by
VARNAME=VALUE

and accessed with $(VARNAME). To change the extension of all files listed in a variable the
substitute command is used. The syntax is
NEWVAR = ${OLDVAR:.old=.new}

This replaces the extension of every file ending with .old in OLDVAR to .new and stores the
list to NEWVAR. This is normally used to create a list of object files form the list of source files.
Makefiles
Make

Suffix Rules
▶ avoid separate rules for all input files
▶ create targets for all files matching the suffix
▶ apply to all files that have not been processed by a separate rule before

.SUFFIXES: .in .out


.in.out:
command1
command2
...

▶ create a target for every file ending on .in


▶ transform it into the same filename with the extension .out
▶ used to compile source code from file.c to an object file file.o
Makefiles
Make

▶ Two placeholders exist referring to the input and the output filenames. The input file is
referred to using $< and the output file using $@.
▶ Finally, we define a clean up target. The target clean removes all object files or
intermediate outputs. Because this target does not produce an output file and does not
depend on a file called clean, it needs to be declared as .PHONY target.
▶ Other techniques extend the make file such as automatic dependency creation using the
GCC compiler, pattern rules as a generalization of the suffix rules, include statements, if
directives, and many more.
▶ Other tools like CMake2 or the GNU Autotools3 provide high level scripting languages to
create complex makefiles automatically.

2 https://www.cmake.org
3 https://en.wikipedia.org/wiki/GNU_build_system
Makefiles
Make

Example
SRC=main.c file1.c
OUTPUT=prog
CC=gcc
CFLAGS= -O2
OBJECTS=${SRC:.c=.o}
.PHONY: clean
.SUFFIXES: .c .o

$(OUTPUT): $(OBJECTS)
$(CC) -o $(OUTPUT) $(CFLAGS) $(OBJECTS)

.c.o:
$(CC) -c -o $@ $(CFLAGS) $<

clean:
rm -f $(OBJECTS)

You might also like