0% found this document useful (0 votes)
7 views167 pages

Advanced Programming

The document outlines the agenda and structure of an Advanced Programming course taught by Dr. Anna Fabijańska, covering topics such as data types, control statements, functions, and memory management in C. It includes assessment requirements, course literature, and a brief introduction to the C programming language, highlighting its characteristics and strengths. Additionally, it provides examples of simple C programs and variable declarations.

Uploaded by

milosz.sarnik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views167 pages

Advanced Programming

The document outlines the agenda and structure of an Advanced Programming course taught by Dr. Anna Fabijańska, covering topics such as data types, control statements, functions, and memory management in C. It includes assessment requirements, course literature, and a brief introduction to the C programming language, highlighting its characteristics and strengths. Additionally, it provides examples of simple C programs and variable declarations.

Uploaded by

milosz.sarnik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 167

10.06.

2021

Advanced Programming

Dr hab. inż. Anna Fabijańska, prof. uczelni


Instytut Informatyki Stosowanej PŁ

Agenda
 Basic data types, variables and arrays.
 Control statements.
 Operators (arithmetic, logic, conditional, sizeof, comma,
bitwise).
 Functions (incl. variable-length argument lists).
 Recursion.
 Pointers (declarations, arithmetic, conversions).
 Memory allocation, dynamic arrays and structures.
 Structures, unions and enumerations.
 Disk file support (streams and handles).
 Arguments of the main function.
 Introduction to lists and queues.
 Preprocessor directives, macros, and conditional compilation.

2 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

1
10.06.2021

Assessment & pass requirements


 Laboratory
 Two practical tests (7th and 15th week)
 Both need to be passed

 Lecture
 Written exam with open questions (15th week)
 Oral exam (if necessary)

𝑭𝒊𝒏𝒂𝒍 𝒎𝒂𝒓𝒌
= 𝟎, 𝟓 𝒍𝒂𝒃𝒐𝒓𝒂𝒕𝒐𝒓𝒚 𝒎𝒂𝒓𝒌 + 𝟎, 𝟓 𝒍𝒆𝒄𝒕𝒖𝒓𝒆 𝒎𝒂𝒓𝒌

3 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Course literature
 Kernighan B. W., Ritchie D. M. : C Programming
Language, 2nd Edition, Prentice Hall, 1988
 Schildt H.: Teach Yourself C, 3rd Edition, McGraw-
Hill Osborne, 1997
 King K.N.: C Programming: A Modern Approach,
2nd Edition. W. W. Norton & Company, 2008
 Prata S.: C Primer Plus (Developer's Library),
Addison-Wesley Professional, 2013
 Gustedt J.: Modern C, 2020,
https://modernc.gforge.inria.fr/

4 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

2
10.06.2021

A short introduction
 C is an imperative programming language
 is designed to give computers orders
 C is a permissive programming language
 assumes that you know what you're doing, doesn't mandate the detailed error-
checking
 C is a compiled programming language
 must be compiled to be executed
 the compiler provides the translation between the language that we understand
(C) and the specific needs of the particular platform
 A correct C program is portable between different platforms and
computer architectures
 C is a low-level programming language
 provides access to machine-level concepts, bytes, addresses, provides operations
that correspond closely to a computer's built-in instructions
 C is a small language
 provides a more limited set of features than many other languages, relies heavily
on library standard functions

5 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Source file

Executable
Translation (or binary code)
(compilation)

example.exe
example.out

example.c

6 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

3
10.06.2021

Strengths & Weaknesess of C


Efficiency C programs can be
Portability error-prone
Power difficult to understand
difficult to modify
Flexibility
Standard library
Integration with UNIX

7 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

http://www.ioccc.org/

Obfuscated C
 The International Obfuscated C Code Contest
 held since 1984
 celebrating [C's] syntactical opaqueness
#define/**/Q(x,y)char*/* */q=y#x","#y")",*p,s[x;}
/*IOCCC'20*/#include/* */<stdio.h>/*-Qlock-*/
int(y),x,i,k,r;Q(9/* 12 */<<9];float(o)[03];
void(P)(){*o=r<0/* 11 1 */?r:-r;o[1]=39.5;
o[2]=22.5;for(k/* 10 2 */=0;++k<39;*o*=i
/6875.5/(k%2?k/* */:-k))y=o[1+k%2
]+=*o;k=o[2];/* 9 o-------> 3 */p=s+y+k/2*80;
}int(main)()/* / */{for(p=s;+i<
1839;*q>32?k/* 8 L 4 */=i++/80-11,y
=(750>r*r+k/* 7 5 */*k*4)*4+y/2
,*p++=r<41?/* 6 */y?"0X+0X+!"
[y-1]-1:+*q/* */++:10:*q++)
r=i%80-38;;/* */;for(x=13,r
=20;i=3600*/* \ / -------+ */--x,i;*p++=
"OISEA2dC8e"/* \ / ------ | */[x%10],*p+=x
/10*41)P();r/* \ / ------ | */=10;;sscanf(
__TIME__,"%d"/* \ / ------ | */":%d:%d",&k,&
x,&i);for(i+=(/* X ------ | */k*60+x)*60;18+
r;*p=k%2?*p%2?+/* __/ \__ | | */59:44:*p>39?59:
39,i=!r--?i%3600/* / \ / \ | | */*12:i)P();puts(s
),"#define/**/Q(x"/* \__/ \__/ +--+ */",y)char*q=y#x\","
"\"#y\")\",*p,s[x;}"/* */"/*IOCCC'20*/#inclu"
"de<stdio.h>/*-Qlock-"/* */"*/int(y),x,i,k,r;Q(")

8 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

4
10.06.2021

Obfuscated C
#include/**/<time.h>
#include <ncurses.h>
# include <stdlib.h>
/** */#define O()for(y-= !!\
y;y<H&& /*...Semi-Automatic.*/y< p/W+2;\
y++)for(x=p% W,x-=!!/*..MineSweeper...*/x;x<W&& x<p%W+2;x++)
#define _(x,y)COLOR_##x,COLOR_##y /* click / (R)estart / (Q)uit */
#define Y(n)attrset(COLOR_PAIR(n)),mvprintw(/* IOCCC2019 or IOCCC2020 */
typedef int I;I*M,W,H,S,C,E,X,T,c,p,q,i,j,k;char G[]=" x",U[256];I F(I p){ I
r=0,x,y=p/W,q;O()q=y*W+x,r+=M[q]^=p-q?(M[q]&16)<<8:0;return r;}I K(I p
,I f,I g){ I x=(g+ f/256)%16-(f+g/256)%16,y=p/W,c=0,n=g/4096
,m=x==n?0:x==g /16%16-f/16%16-n?256:-1; if(m+1)O()if
((4368&M[n=y*W +x])==4112){ M[c=1,n]=(M[n]&~16)|m; }
return c;}void D(){I p,k,o=0,n=C,m=0,q=0;if(LINES-1<H
||COLS/2<W)clear (),Y(4)LINES/2,COLS/2-16,"Make the ter\
minal bigger!");else{for (p=0;p<S;o+=k==3,Y(k)p/W+1,p%W*2,G),p++)G[1]=""
"_*!..12345678"[k=E?256&M[p ]?n--,2:E-2||M[p]%2<1?M[p]&16?q=p,m++,3:4+F(p)%16:
1:3];k=T+time(0);T=o||T>=0||E-1?T:k;k=T<0?k:T;Y(7)0,0,"%03d%*s%03d",n>999?999:n,W*
2-6,"",k>999?999:k);Y(9)0,W-1,E>1?"X-(":E-1||o?":-)":"8-)");M[q]|=256*(n==m&&n); }
refresh();}short B[]={_(RED,BLACK),_(WHITE,BLUE),_(GREEN,RED),_(MAGENTA,YELLOW),_(
CYAN,RED)};I main(I A,char**V){MEVENT e;FILE*f;srand(time(0));initscr();for(start\
_color();X<12;X++){init_pair(X+1,B[X&&X<10?X-1:2],B[X?X<3?2:1:0]);}noecho();cbreak
();timeout(9);curs_set(0);keypad(stdscr,TRUE);for(mousemask(BUTTON1_CLICKED|BUTTO\
N1_RELEASED,0);;){S=A<2?f=0,W=COLS/2,H=LINES-1,C=W*H/5,0:fscanf(f=fopen(V[A-1],"r"
),"%d %d %d",&W,&H,&C)>3; ;S+=W*H;M=realloc(M,S*sizeof(I)*2);for(i=0
;i<S;i++)!f?M[i]=i,i&&(k=M[j=rand()%i],M[j]=M[i],M[i]=k):fscanf(f,
"%d",M+i);if(f)fclose(f);T=E=X=0;for(clear();D(),c=getch(),c-'r'
&&(c-KEY_RESIZE||E);){ if(c=='q'){ return(endwin(),0); }if(c==
KEY_MOUSE&&getmouse(&e)==OK&&e.x/2<W&&e.y<=H){if(!e.y&&(W-2<e.x&&
e.x<W+2)){break;}p=e.x/2+e.y*W-W;if(p>=0){if(!E){for(i=0;i<S;i++)M[S+M
[i]]=i,M[i]=16+(M[i]<C);C-=M[p]&1;M[p]=16;E=1;T=-time(0);}if(E<2)M[p]&=(M[p]
&257)==1?T+=time(0),E=2,273:257;}}for(p=0;p<S&&E==1;M[p++]&=273){}for(i=
(X+S-1)%S;E==1&&i!=X;X=(X+1)%S){if(!(M[p=M[X+S]]&272)){if(K(p,c=F(p)
,0)){goto N;} for(k=p/W-2,k=k<0?0:k;k<p/W+3&&k <H;k++)for(j=
p%W-2,j =j<0?0:j;j<W&&j<p%W+3;)if (!(M[q=
k*W +j++]&272)){ if(K(p, c,F
(q))){ goto N; }F(q)
; }F(p); }}N:; } } }
/*(c)Yusukse Endoh*/

9 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Writing a simple program


 The simplest program written in C
main.c
#include <stdio.h> //including standard I/O library

/***************************/
/* Place for documentation */ comments (ignored by compiler)
/***************************/

int main() //function main contains program’s code


{ begin
printf("Hello World!\n");
return 0; //finish and return 0 to the op. system
} end

10 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

5
10.06.2021

The general form of a simple program


 Directives:
 commands intended for preprocessor
 start with # directives
 Function main()
function headers
 mandatory
int main(void)
 it gets call automatically when the
{
program executes declarations
 Statements }
statements

 commands to execute when the


program runs function definitions

 each statement ends with semicolon

11 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Variables and assignment


 Data storage locations (temporary storage during program
execution)
 Variables must be declared
 Basic data types in C language: TYPE name;
 char – a single byte, capable of holding one character in the local
character set
 int – an integer, typically reflecting the natural size of integers on the
host machine
 float – single-precision floating point
 double – double-precision floating point
 Names
 are made up of letters and digits; the first character must be a letter
(the underscore _ counts as a letter)
 upper and lower case letters are distinct
 should be unique and different than keywords

12 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

6
10.06.2021

Variables and assignment


int height; // declaration
int length, width; // declaration

float depth = 3.14; // declaration and assignment


float profit, loss = 1.0;

profit = 0.0; // assignment


loss = profit; // assignment

char y; // declaration
char x = '@'; // declaration and assignment

double sth = 0.0; // declaration and assignment

Variables have no default values


 if not explicitly assigned a value, they remain uninitialized
13 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Long and short


 long – for bigger numbers (int and double)
 short – for smaller numbers (int)
#include <stdio.h>
int main() {
short a;
long b;
long long c; //C99
Operator that returns
double d;
size of a variable or type
long double e;
printf("size of short = %d bytes\n", sizeof(a));
printf("size of long = %d bytes\n", sizeof(b));
printf("size of long long = %d bytes\n", sizeof(c));
printf("size of double = %d bytes\n", sizeof(d));
printf("size of long double = %d bytes\n", sizeof(e));
return 0;
}
14 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

7
10.06.2021

Signed and unsigned


 signed – for numbers with a sign (positive or negative)
 default
 unsigned – for nonnegative numbers
 integers only
Integer Overflow
 when the result of arithmetic operations is too large to represent.
#include <stdio.h>
int main() {
unsigned char a = 250, b = 250, c;
c = a+b;
printf("%d + % d = %d\n", a, b, c);
return 0;
}
15 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Integer Types
Type Storage size Value range
char 1 byte -128 to 127 or 0 to 255
unsigned char 1 byte 0 to 255
signed char 1 byte -128 to 127
-32,768 to 32,767 or -2,147,483,648 to
int 2 or 4 bytes
2,147,483,647
unsigned int 2 or 4 bytes 0 to 65,535 or 0 to 4,294,967,295
short 2 bytes -32,768 to 32,767
unsigned short 2 bytes 0 to 65,535
8 bytes or (4bytes -9223372036854775808 to
long
for 32 bit OS) 9223372036854775807
unsigned long 8 bytes 0 to 18446744073709551615

16 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

8
10.06.2021

Floating-Point Types

Type Storage size Value range Precision


float 4 byte 1.2E-38 to 3.4E+38 6 decimal places
2.3E-308 to
double 8 byte 15 decimal places
1.7E+308
3.4E-4932 to
long double 10 byte 19 decimal places
1.1E+4932

Single precision

Double precision

17 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <stdio.h>
#include <stdlib.h>
#include
#include
<limits.h>
<float.h>
Example
int main(int argc, char** argv) {

printf("CHAR_BIT : %d\n", CHAR_BIT);


printf("CHAR_MAX : %d\n", CHAR_MAX);
printf("CHAR_MIN : %d\n", CHAR_MIN);
printf("INT_MAX : %d\n", INT_MAX);
printf("INT_MIN : %d\n", INT_MIN);
printf("LONG_MAX : %ld\n", (long) LONG_MAX);
printf("LONG_MIN : %ld\n", (long) LONG_MIN);
printf("SCHAR_MAX : %d\n", SCHAR_MAX);
printf("SCHAR_MIN : %d\n", SCHAR_MIN);
printf("SHRT_MAX : %d\n", SHRT_MAX);
printf("SHRT_MIN : %d\n", SHRT_MIN);
printf("UCHAR_MAX : %d\n", UCHAR_MAX);
printf("UINT_MAX : %u\n", (unsigned int) UINT_MAX);
printf("ULONG_MAX : %lu\n", (unsigned long) ULONG_MAX);
printf("USHRT_MAX : %d\n", (unsigned short) USHRT_MAX);

printf("Storage size for float : %d \n", sizeof(float));


printf("FLT_MAX : %g\n", (float) FLT_MAX);
printf("FLT_MIN : %g\n", (float) FLT_MIN);
printf("-FLT_MAX : %g\n", (float) -FLT_MAX);
printf("-FLT_MIN : %g\n", (float) -FLT_MIN);
printf("DBL_MAX : %g\n", (double) DBL_MAX);
printf("DBL_MIN : %g\n", (double) DBL_MIN);
printf("-DBL_MAX : %g\n", (double) -DBL_MAX);
printf("Precision value: %d\n", FLT_DIG );

return 0;
} 18 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

9
10.06.2021

Keywords
auto float sizeof _Atomic (C11)
break for static _Bool (C99)
case goto struct _Complex (C99)
char if switch _Decimal128 (C23)
const inline (C99) typedef _Decimal32 (C23)
continue int union _Decimal64 (C23)
default long unsigned _Generic (C11)
do register void _Imaginary (C99)
double restrict (C99) volatile _Noreturn (C11)
else return while _Static_assert (C11)
enum short _Alignas (C11) _Thread_local (C11)
extern signed _Alignof (C11)

19 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Output on Console
 Standard input/outpt library (stdio.h)
 printf() function for outputing the formated text
#include <stdio.h>

int main()
{
int n = 10;
float m = 1.245;
char c = 'A';
printf("%d \n",n);
printf("%f \n",m);
printf("%.2f \n",m); format specifiers/placeholders
printf("%.3f \n",m);
printf("%c \n",c);
return 0;
}
20 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

10
10.06.2021

Format specifiers
%c Character %Lf Long double
%d Signed integer %lu Unsigned int or unsigned long
Scientific notation of %lli or %lld Long long
%e or %E
floats %llu Unsigned long long
%f Float values %o Octal representation
%g or %G Similar as %e or %E %p Pointer
%hi Signed integer (short) %s String
%hu Unsigned Integer (short) %u Unsigned int
%i Unsigned integer %x or %X Hexadecimal representation
%l, %ld or %li Long %n Prints nothing
%lf Double %% Prints % character

These are the basic format specifiers. We can add some other parts with the format specifiers:
• A minus symbol (-) sign tells left alignment
• A number after % specifies the minimum field width. If string is less than the width, it will be
filled with spaces
• A period (.) is used to separate field width and precision
21 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Escape sequence characters


Escape Sequence Represents
\a Bell (alert)
\b Backspace
\f Form feed
\n New line
\r Carriage return
\t Horizontal tab
\v Vertical tab
\' Single quotation mark
\" Double quotation mark
\\ Backslash
\? Literal question mark
\ ooo ASCII character in octal notation
\x hh ASCII character in hexadecimal notation

Unicode character in hexadecimal notation if this escape sequence is used in a


\x hhhh
wide-character constant or a Unicode string literal.

22 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

11
10.06.2021

Input & Output on Console


 Standard input/outpt library (stdio.h)
 scanf() to read formatted input from the standard input

#include <stdio.h> #include <stdio.h>


int main() int main()
{ {
int testInt; float num1;
printf("Enter an integer: "); double num2;
scanf("%d", &testInt); printf("Enter a number: ");
printf("Number = %d",testInt); scanf("%f", &num1);
return 0; printf("Enter another number: ");
} scanf("%lf", &num2);
printf("num1 = %f\n", num1);
printf("num2 = %lf", num2);
return 0;
}

23 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Input & Output on Console


 I/O Multiple Values in a specified format
#include <stdio.h>

int main()
{
int a;
float b;

printf("Enter integer and then a float: ");

// Taking multiple inputs

scanf("%d %f", &a, &b);


printf("You entered %d and %f", a, b);

return 0;
}

24 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

12
10.06.2021

Input & Output on Console


 I/O Multiple Values in a specified format
#include <stdio.h>

int main()
{
int d, m, y;
printf("Enter date in a format\n");
printf("dd/mm/yyyy\n");

// Taking multiple inputs

scanf("%d/%d/%d", &d, &m, &y);


printf("You entered %02d-%02d-%04d", d, m, y);

return 0;
}

25 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
/*
* Converts a Fahrenheit temperature to Celsius
*/

#include <stdio.h>

#define FREEZING_PT 32.0f


preprocessor directives
#define SCALE_FACTOR (5.0f/9.0f)

int main(void)
{
float fahrenheit, celsius;
printf("Enter Fahrenheit temperature: ");
scanf("%f", &fahrenheit);
celsius = (fahrenheit - FREEZING_PT) * SCALE_FACTOR;
printf("Celsius equivalent: %.1f\n", celsius);
return 0;
}

26 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

13
10.06.2021

Arithmetic operators
 Apply standard mathematical operations to their operands
Operator Operator name Example Result
+ unary plus +a the value of a after promotions
- unary minus -a the negative of a
+ addition a + b the addition of a and b
- subtraction a - b the subtraction of b from a
* product a * b the product of a and b
/ division a / b the division of a by b
% remainder a % b the remainder of a divided by b

Integer division - when both operands are integers the / operator truncates the
result by dropping the fractional part

The % operator requires integer operands

27 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Arithmetic operators
#include <stdio.h>

int main()
{
int a=40,b=21, add,sub,mul,div,div2,mod;
add = a+b;
sub = a-b;
integer division
mul = a*b;
int divided by int gives int
div = a/b; // 40/21 = 1.9047 not float!
div2 = b/a; // 21/40 = 0.5250
mod = a%b;
printf("Addition of a, b is : %d\n", add);
printf("Subtraction of a, b is : %d\n", sub);
printf("Multiplication of a, b is : %d\n", mul);
printf("Division of a, b is : %d\n", div);
printf("Division of b, a is : %d\n", div2);
printf("Modulus of a, b is : %d\n", mod);
}
28 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

14
10.06.2021

Operator precedence and associativity


 The arithmetic operators’ relative precedence
Highest: + - (unary) i + j * k  i + (j * k)
* / % - i * - j  (-i) * (-j)
Lowest: + - (binary) + i + j / k  (+i) + (j / k)

 Left associative: *, / , % , + (binary), - (binary)


 group from the left to right
i - j - k  (i - j) - k
i * j / k  (i * j) / k

 Right associative: + (unary), - (unary)


 group from the left to right
- + i  -(+i)

29 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Assignment and L-values


 Assignment requires an L-value (an object stored in
computer memory) as its left operand
12 = i; /* WRONG */
i + j = 0; /* WRONG */
-i = j; /* WRONG* /

 Compound assignment

i += 2 /* same as i = i + 2; */
i -= 2 /* same as i = i - 2; */
i *= 2 /* same as i = i * 2; */
i /= 2 /* same as i = i / 2; */

30 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

15
10.06.2021

Increment and decrement operators


 ++ adds 1 to its operand
 -- subtracts 1 from its operand
 prefix version ++i and --i (change, then use)
 Postfix version i++ and i– (use, then change)
int i;
i = 1;
printf("i is: %d\n", ++i);
printf("i is: %d\n", i);
printf("\n ******** \n\n");
i = 1;
printf("i is: %d\n", i++);
printf("i is: %d\n", i);

31 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Statements in C language
 Selection statements
 allow a program to select a particular execution path from a set of
alternatives
 if, switch
 Iteration statements
 support iteration (looping)
 while, do-while, for
 Jump statements
 cause an unconditional jump to some other place in the program
 break, continue, return, goto
 Compound statements
 group several statements into a single statement

32 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

16
10.06.2021

Logical expressions
 Relational operators
 Check the relationship between two operands. If the relation is
true, it returns 1; if the relation is false, it returns value 0.
Operator Meaning of Operator Example
== Equal to 5 == 3 is evaluated to 0
> Greater than 5 > 3 is evaluated to 1
< Less than 5 < 3 is evaluated to 0
!= Not equal to 5 != 3 is evaluated to 1
>= Greater than or equal to 5 >= 3 is evaluated to 1
<= Less than or equal to 5 <= 3 is evaluated to 0

The precedence of the relational operators is lower than that of the


arithmetic operators

33 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Logical expressions
 Relational operators
#include <stdio.h>
int main(){
int a = 5, b = 5, c = 10;
printf("%d == %d is %d \n", a, b, a == b);
printf("%d == %d is %d \n", a, c, a == c);
printf("%d > %d is %d \n", a, b, a > b);
printf("%d > %d is %d \n", a, c, a > c);
printf("%d < %d is %d \n", a, b, a < b);
printf("%d < %d is %d \n", a, c, a < c);
printf("%d != %d is %d \n", a, b, a != b);
printf("%d != %d is %d \n", a, c, a != c);
printf("%d >= %d is %d \n", a, b, a >= b);
printf("%d >= %d is %d \n", a, c, a >= c);
printf("%d <= %d is %d \n", a, b, a <= b);
printf("%d <= %d is %d \n", a, c, a <= c);
return 0;
}

34 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

17
10.06.2021

Logical expressions
 Logical operators
 An expression containing logical operator returns either 0 or 1
depending upon whether expression results true or false. Logical
operators are commonly used in decision making in C programming.
Operator Meaning Example
If c = 5 and d = 2 then,
Logical AND.
&& expression ((c==5) && (d>5))
True only if all operands are true
equals to 0.
Logical OR. If c = 5 and d = 2 then,
|| True only if either one operand expression ((c==5) || (d>5))
is true equals to 1.
If c = 5 then,
Logical NOT.
! expression !(c==5)
True only if the operand is 0
equals to 0.

35 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Logical expressions
#include <stdio.h>
int main(){
 Logical
int a = 5, b = 5, c = 10, result; operators
result = (a == b) && (c > b);
printf("(a == b) && (c > b) is %d \n", result);
result = (a == b) && (c < b);
printf("(a == b) && (c < b) is %d \n", result);
result = (a == b) || (c < b);
printf("(a == b) || (c < b) is %d \n", result);
result = (a != b) || (c < b);
printf("(a != b) || (c < b) is %d \n", result);
result = !(a != b);
printf("!(a != b) is %d \n", result);
result = !(a == b);
printf("!(a == b) is %d \n", result);

return 0;
}

36 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

18
10.06.2021

Logical expressions
 Equality operators
Operator Meaning
== equal to
!= not equal to

 Both && and II perform short-circuit evaluation of their


operands
 They first evaluate the left operand, then the right.
 If the value of the expression can be deduced from the left value
of the left operand alone, then the right operand isn't evaluated

i > 0 && ++j > 0 if i<0, j++ is not executed


(side effect)
37 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The if statement
 The if statement allows a program to choose between
two alternatives by testing the value of an expression

if (condition) statement-or-block

 An if statement may have an else clause


if (condition) statement0-or-block0
else statement1-or-block1

if (line_num == MAX_LINES) if (line_num == MAX_LINES)


line_num = 0; line_num = 0;
else
line_num ++;

38 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

19
10.06.2021

The if statement
 Equality (==) vs. assignment (=)
int i = 0; int i = 0;
if (i == 5) if (i = 5)
printf("cond. is false"); printf("cond. is true");

 Multiple conditions

if (0 <= i && i < n) if (i < 0 || i >= n)


// do sth //do sth

39 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The if statement
 Compound statements
 to make if statement control two or more statements, a
compound statement is needed { multiple statements }
if (line_num == MAX_LINES)
{ if (line_num == MAX_LINES)
line_num = 0; {
page_num ++; line_num = 0;
} page_num ++;
}
vs. else
{
if (line_num == MAX_LINES) page_num = 10;
line_num = 0; page_num --;
page_num ++; //unconditional }

40 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

20
10.06.2021

The if statement
 Nested if-else statements
 if statements can be nested to any depth

if (i>j)
if (i>j){ if (i>j){
if (i>k)
if (i>k) if (i>k){
max = i;
max = i; max = i;
else
else }else{
max = k;
max = k; max = k;
else
}else{ }
if (j>k)
if (j>k) }else{
max = j;
max = j; if (j>k){
else
else max = j;
max = k;
max = k; }else{
} max = k;
}
}

41 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The if statement
 Dangling else poblem
 else clause if (y!=0)
if (x!=0)
belongs to the result = x/y;
nearest if else
printf("Error: y is equal to 0\n);
statement that
if (y !=0)
hasn't been paired if (x!=0)
result = x/y;
with an else else
printf("Error: y is equal to 0\n);

if (y !=0){
if (x!=0)
result = x/y;
} else
printf("Error: y is equal to 0\n);

42 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

21
10.06.2021

The if statement
 Cascaded if statements
 if statements can be nested to any depth
if (n<0)
printf("n is less than 0\n");
if (expression) else
if (n==0)
statement
printf("n is equal to 0\n");
else if (expression) else
statement printf("n is greater than 0\n");
else if (expression)
statement
else if (expression) if (n<0)
statement printf("n is less than 0\n");
else else if (n==0)
statement printf("n is equal to 0\n");
else
printf("n is greater than 0\n");

43 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example Program to Find the Roots of a Quadratic Equation

#include <stdio.h>
#include <math.h> /* header for function sqrt */

int main()
{
float a,b,c,delta,x1,x2; /*coefficients, discriminant, roots*/
printf("Program to find the roots of a quadratic equation\n");
printf("Input coefficients a, b, and c ");
scanf("%f %f %f",&a,&b,&c);
if (a!=0)
{
delta=b*b - 4*a*c; /* discriminant of a quadratic equation*/
if (delta< 0) printf("No real roots");
else if (delta == 0) printf ("x1=x2=%.4f", -b/(2*a));
else
{
x1= (-b - sqrt(delta))/(2*a);
x2= (-b + sqrt(delta))/(2*a);
printf("x1 = %.4f, x2=%.4f",x1,x2);
}
}
else printf("Incorrect input\n");
return 0;
}
44 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

22
10.06.2021

Conditional operator
 C provides an operator that allows an expression to produce
one of the two values depending on the condition
result = condition ? expression1:expression2;

 Is equivalent to:
if(condition) result = expression1;
else result = expression2;

 The operator is unique since it requires three operands.


int i, j, k;
i = 1;
j = 2;
k = i > j ? i : j; /*k is now 2*/
k = (i >= 0 ? i : 0) + k; /*k is now 3*/

45 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The switch statement


 a multi-way decision that tests whether an expression matches
one of a number of constant integer values, and branches
accordingly Controlling expression (integer)

switch (expression)
{
case const-expr: statements
case const-expr: statements
...
case const-expr: statements
default: statements
}

 an alternative to cascaded if statements, but usually faster

46 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

23
10.06.2021

The switch statement


int grade; int grade ;

if (grade == 4) switch(grade)
printf("Excellent"); {
else if (grade == 3) case 4: printf("Excellent");
printf("Good"); break;
else if (grade == 2) case 3: printf("Good");
printf("Average"); break;
else if (grade == 1) case 2: printf("Average");
printf("Poor"); break;
else if (grade == 0) case 1: printf("Poor");
printf("Failing"); break;
else case 0: printf("Failing");
printf("Illegal grade"); break;
default: printf("Illegal grade");
break;
}

47 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h> #include <stdio.h>
int main()
{ int main()
int grade; {
printf("input grade: "); int grade ;
scanf("%d", &grade); printf("input grade: ");
switch(grade) scanf("%d", &grade);
{ switch(grade)
case 4: printf("Excellent\n");
break; {
case 3: printf("Good\n"); case 4: printf("Excellent\n");
break; case 3: printf("Good\n");
case 2: printf("Average\n"); case 2: printf("Average\n");
break;
case 1: printf("Poor\n"); case 1: printf("Poor\n");
break; case 0: printf("Failing\n");
case 0: printf("Failing\n"); default: printf("Illegal grade\n");
break; break;
default: printf("Illegal grade\n");
break; }
} return 0;
return 0; }
}

48 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

24
10.06.2021

Example
#include <stdio.h>

int main()
{
char znak;

printf("Program for recognising letters\n");


printf("\nInput letter: ");

znak = getchar();

printf("\nYour input is: %c", znak);

switch(znak) {
case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
printf("\n vowel \n");
break;
case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'p': case 'r': case 's': case 't': case 'w': case 'z':
printf("\n consonant \n");
break;
case 'q': case 'v': case 'x':
printf("\n foreign consonant\n");
break;
default:
printf("\n Input is not a letter \n");
}
return 0;
}
49 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Loops
 A loop is a statement which repeatedly executes some other
statement (loop body)
 In C, every loop has a controlling expression. Each time the loop
body is executed (an iteration of the loop), the controlling
expression is evaluated.
 If the expression is true (has a value that's not zero) loop continues
to execute

 while statement
 used for loops whose controlling expression is tested before the loop
body is executed
 do statement
 used for loops whose controlling expression is tested after the loop
body is executed
 for statement
 is convenient for loops that increment or decrement a counting variable

50 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

25
10.06.2021

The while statement


 tests controlling expression before the loop body is executed

while (condition) statement-or-block

51 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The while statement


while (i < n) /* controlling expression */
i = i * 2; /* loop body */

while (i < n){ // braces allowed while (i<n){ // loop body includes
i = i * 2; // but not required i = i * 2; // two statements
} printf("%d ", i);
}
while (i<n);{ //loop body includes
i = i * 2; //empty statement while (i<n) // loop body includes
printf("%d ", i); i = i * 2; // one statement
} //inifinite loop printf("%d ", i);

while (1){ while (0){


//inifinite loop //loop does not start
} }

52 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

26
10.06.2021

#include <stdio.h>
int main(){ Example
int i, n;
printf("\n *****************\n");
i = 1, n = 11;
while (i<n){
i = i * 2;
printf("%d ", i);
}
printf("\n *****************\n");
i = 1, n = 11;
while (i<n)
i = i * 2; //loop body
printf("%d ", i); //executed once, after loop finishes
printf("\n *****************\n");
i = 1, n = 11;
while (i<n);{ // infinite loop
i = i * 2;
printf("%d ", i);
}
return 0;
}
53 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The do statement
 tests controlling expression after the loop body is executed

do statement-or-block while (condition);

 handy for loops that must execute at least once

54 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

27
10.06.2021

Example
// Program to add numbers until the user enters zero
#include <stdio.h>
int main()
{
double number, sum = 0;

do
{ // the body of the loop is executed at least once
printf("Enter a number: ");
scanf("%lf", &number);
sum += number;
}
while(number != 0.0);

printf("Sum = %.2lf",sum);

return 0;
}
55 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
// Calculating a number of digits in inteager

#include <stdio.h>
int main(void)
{
int digits = 0, n;
printf("Enter a nonnegative inteager: ");
scanf("%d", &n);

do{n /= 10; //divide user input by 10 repeatedly


digits++;
}while (n>0); //until it becomes 0

printf("The number has %d digits(s).\n", digits);

return 0;
}

56 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

28
10.06.2021

The for statement


 convenient for loops that increment or decrement a counter
for (clause; condition; expression) statement-or-block

 clause is an assignment (initialization)


expression or a variable definition; serves to
state an initial value for the iteration domain
 condition tests whether the iteration
should continue
 expression updates the iteration variable
used in clause1; is performed at the end of
each iteration.

57 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The for statement


for(i=1; i<10; i++) printf("i =%d", i);

for(i=10; i>0; i--) printf("i =%d", i);

for (i=10; i>1; i-=2){


x=5+10*i;
printf("i=%d, x=%d\n", i, x);
}

for (; ; ){ //infinite loop


x=5+10*i;
printf("i=%d, x=%d\n", i, x);
}

58 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

29
10.06.2021

Example
/* A program that determines
an average of n numbers */
#include <stdio.h>
int main()
{
int i, n; // loop counter, number of elements
float x, sum; // current number, result
printf("The program determines the average of numbers\n");
printf ("Input number of elements: ");
scanf("%d", &n);
if(n>0) // if number of elements positive
{
sum=0.0;
for(i=0; i<n; i++) //read n numbers
{
printf("Input number %d: ", i+1); //input number
scanf("%f",&x);
sum=sum+x; //increase sum
}
printf("The average is %8.3f", sum/n);
}
else printf("Incorrect input\n");
return 0;
}
59 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
/* A program that prints characters and the corresponding ASCII codes*/
#include <stdio.h>
int main()
{
char character;

for(character='a'; character<='z'; character++)


printf("ASCII code of %c is %d\n", character, character);

for(character='A'; character<='Z'; character++)


printf("ASCII code of %c is %d\n", character, character);

return 0;
}

60

30
10.06.2021

Exiting from a loop


 The break statement
 ends the loop immediately when it is encountered

61 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Exiting from a loop


 The continue statement
 skips the current iteration of the loop and continues with the
next iteration

62 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

31
10.06.2021

break vs. continue example


#include <stdio.h> #include <stdio.h>

int main() int main()


{ {
for (int i = 1; i <= 10; i++) { for (int i = 0; i < 10; i++) {
if (i % 3 == 0) { if (i % 3 == 0) {
break; continue;
} }
printf("%d ", i); printf("%d ", i);
} }

return 0; return 0;
} }

63 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Exiting from a loop


 The goto statement
 is capable of jumping to any statement in a function provided
that the statement has a label
 alows to exit nested loops or switch-case nested in a loop
while (...){
switch(...){
...
goto loop_done; /* break won't work here*/
...
}
}

loop_done: ...

 is not recommended
64 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

32
10.06.2021

#include <stdio.h> Example


int main(){ #include <stdio.h>

int i = 0; int main(){


A: printf("A->");
i++; int i = 0;

if (i < 10) A: printf("A->");


goto C; i++;
else goto C;
goto D;
B: printf("B->"); B: printf("B->");
i++; i++;
goto A; goto A;

C: printf("C->"); C: printf("C->");
i++; i++;
goto B; goto B;
D: printf("End");
return 0;
return 0; } Endless loop
}
65 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Arrays
 Aggregate variables which store collection of values
(elements), all of which have the same type
 elements can be selected individually by their position within the
array
int a[10]; TYPE arrName [size];

subscripts (indices)
count from ZERO one dimensional array

a[0] = 1; // inputs 1 to 1st element


printf("%d\n", a[5]); // prints 5th element
++a[i];
66 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

33
10.06.2021

Example
# include <stdio.h>
# define N 10
int main (void)
{
int i, sum = 0;
int tab [N];
for (i = 0; i < N; i++) // clear tab
tab[i] = 0;
for (i = 0; i < N; i++) {
printf("input element %d: ", i+1);
scanf("%d", &tab[i]); // read data into tab
}
for (i = 0; i < N; i++)
printf("%d\t", tab[i]); //print tab
printf("\n");
for (i = N-1; i >= 0; i--)
printf("%d\t", tab[i]); //print tab in reverse order
for (i=0; i < N; i++)
sum += tab[i]; // sum elements
printf("\nSum of elements: %d\n", sum);
return 0;
} 67 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Array initialization
 Array initializer - a list of constant expressions enclosed in
braces and separated by commas

int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int a[10] = {1, 2, 3, 4, 5, 6};


/* initial value of a is {1, 2, 3, 4, 5, 6, 0, 0, 0 ,0} */

int a[10] = {0};


/* initial value of a is {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0} */

int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


/* array size omitted, set to the length of initializer */

68 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

34
10.06.2021

Array initialization
 Designated initializer – in C99
int a[15] = { [2] = 29, [9] = 7, [14] = 48};
//{0,0,29,0,0,0,0,0,0,7,0,0,0,0,48}
//num in brackets is a designator

int a[15] = { [14] = 48, [9] = 7, [2] = 29};


//{0,0,29,0,0,0,0,0,0,7,0,0,0,0,48}

int b[] = {[5] = 10, [23] = 13, [11] = 36, [15] = 29};
//{0,0,0,0,0,10,0,0,0,0,0,36,0,0,0,29,0,0,0,0,0,0,0,13}
//array size = 24

float c[10] = {5, 1, 9, [4] = 3.14, 7, 2, [8] = 6};


//mixed approach to initialization

69 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

/*Checks numbers for repeated digits*/


#include <stdio.h> Example
#define true 1
#define false 0
typedef int bool;
int main(void){
bool digit_seen[10] = {false};
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
while(n>0){ //get digits of a number
digit = n % 10;
if(digit_seen[digit])
break;
digit_seen[digit] = true; //if seen mark related array element
n /= 10;
}
if (n>0)
printf("Repeated digit\n");
else
printf("No repeated digit\n");
return 0;
}
70 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

35
10.06.2021

Giving a new name to an existing type


 The C programming language provides a keyword called
typedef, which can be used to give a type a new name.
typedef TYPE new-type-name;

typedef int Length; // a new name for int type


Length zm1, zm2; // new variable declaration
Length *len[100]; // new variable declaration

 the original type name is still valid with typedef


 multiple names can be given to a type using typedef

71 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

typedef signed char numbers;

int main(void)
{
numbers i;

for(i=0; i<10; i++)


printf("%d ", i);

return 0;
}

72 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

36
10.06.2021

Giving a new name to an existing type


 Name created by typedef, can be further use to create
new type names

typedef int height;


typedef height length;
typedef length depth;

depth d; // d is int in fact

enum type_w {one, two, three};


typedef enum type_w some_numbers;

some_numbers num; // num is type_w in fact

73 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Multidimensional arrays
 An array can have any number of dimensions
2d array: TYPE name[rows][cols];
3d array: TYPE name[pages][rows][cols];

0 1 2 3 tab
float tab[5][4];
0
tab[2]
1

2
tab[2][2]
3

74 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

37
10.06.2021

Example
#include <stdio.h>
#define N 10
int main() {
double ident[N][N];
int row, col;
/*put 1 on the diagonal and 0 otherwise*/
for (row = 0; row < N; row++) {
for (col = 0; col < N; col++) {
if (row == col)
ident[row][col] = 1.0;
else
ident[row][col] = 0.0;
}
}
/*print content divided into rows and columns*/
for (row = 0; row < N; row++) {
for (col = 0; col < N; col++) {
printf("%.0f\t", ident[row][col]);
}
printf("\n");
}

return 0;
}
75 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Initializing a multidimensional array


 Multidimensional arrays may be initialized by specifying
bracketed values for each row.
int a[3][4] = {
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};
equivalent to: int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

 Except the left most dimension, all other dimensions must be


specified
int a[][2] = {{1,2},{3,4}}; // Works
int a[][2][2] = {{{1,2},{3,4}},{{5,6},{7,8}}}; // Works
int a[][][2] = {{{1,2},{3,4}},{{5,6},{7,8}}}; // Error

76 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

38
10.06.2021

/*Deals a random hand of cards */


#include <stdbool.h> /* C99 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Example
#define NUM_SUITS 4
#define NUM_RANKS 13

int main(void){
bool in_hand[NUM_SUITS][NUM_RANKS] = {false};
int num_cards, rank, suit;
const char rank_code[] = {'2','3','4','5','6','7','8','9','t','j','q','k','a'};
const char suit_code[] = {'c','d','h','s'};

srand((unsigned) time(NULL));
printf("Enter a number of cards in hand: ");
scanf("%d", &num_cards);

printf("Your hand:");

while(num_cards>0){
suit = rand() % NUM_SUITS; /* pick a random suit */
rank = rand() % NUM_RANKS; /* pick a random rank */
if(!in_hand[suit][rank]){
in_hand[suit][rank] = true;
num_cards --;
printf(" %c%c", rank_code[rank], suit_code[suit]);
}
}
printf("\n");
return 0;
} 77 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Variable length arrays (C99)


 The length of VLA is computed when the program is
executed not when the program is compiled
#include <stdio.h>

int main() {

int n;

printf("inupt array size: ");


scanf("%d", &n);

int tab[n];

printf("Array size: %d\n", sizeof(tab)/sizeof(tab[0]));

return 0;
}

78 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

39
10.06.2021

Functions
 Function is a self-contained unit of program code
designed to accomplish a particular task
• function prototype (header) tells the compiler what sort of
function a given function is,
return-type function-name(parameter declarations, if any);

• function call causes the function to be executed,


• function definition specifies exactly what the function does.
return-type function-name(parameter declarations, if any)
{
declarations
statements
}

79 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Functions
Function prototype (header): Formal parameters
return type int power(int base, int n);

Function definition: Formal parameters


(inputs to function)
int power(int base, int n){
int i, p;
p = 1;
for (i = 1; i <= n; ++i)
p = p * base; Output – only one!
return p; (not array!)
}
Function call:
int ret = power(2, 5);

80 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

40
10.06.2021

Example
#include <stdio.h> Ver. 1 #include <stdio.h> Ver. 2
/*function prototype*/ /*function definition*/
float average(int a, int b); float average(int a, int b){

int main(){ float result = (a + b)/2.0;


return result;
int x = 5, y = 6; }
float z;
int main(){
/*function call*/
z = average(x,y); int x = 5, y = 6;
float z;
return 0;
} /*function call*/
/*function definition*/ z = average(x,y);
float average(int a, int b){
return 0;
float result = (a + b)/2.0; }
return result;
}

81 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Prototyping Functions with Arguments


/* valid function header */
void dubs(int x, int y, int z);

/* invalid function header */


void dibs(int x, y, z);

int show_n_char(char ch, int num);

/*variable names can be omitted in the prototype*/


int show_n_char(char, int);

/*function with no inputs and no outputs*/


void do_sth(void);

82 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

41
10.06.2021

Example
/* lesser.c -- finds the lesser of two evils */

#include <stdio.h>

int imin(int, int); no parameter names


int main(void){
int evil1, evil2;
printf("Enter a pair of integers (q to quit):\n");
while (scanf("%d %d", &evil1, &evil2) == 2){
printf("The lesser of %d and %d is %d.\n",
evil1, evil2, imin(evil1,evil2)); actual parameters (arguments)
printf("Enter a pair of integers (q to quit):\n");
}
printf("Bye.\n");
return 0;
}

int imin(int n,int m){ formal parameters


int min;
if (n < m)
min = n;
else
min = m;
return min;
}
83 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Arguments
 In C arguments are passed by value
 each argument is evaluated and its value is assigned to a
corresponding parameter (function uses a copy)
#include <stdio.h>
void test(int);

int main(void){
int n = 10;
printf("before function n is: %d\n", n);
test(n);
printf("after function n is: %d\n", n);

return 0;
}
Changes to variable
made by function are
void test(int n){ forgotten after the
n = n + 10;
printf("in function n is: %d\n", n); function finishes
return;
}

84 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

42
10.06.2021

Array arguments
 When a function parameter is a one-dimensional array,
the length of the array can be (and is normally) left
unspecified. int fun (int[]); /*no length specified*/
...
int fun (int a[]){
//body of a function
}

 C doesn't provide an easy way for a function to


determine the length of an array passed to it
int fun (int a[]){
int len = sizeof(a) / sizeof(a[0]));
/*** WRONG: not the number of elements in a ***/

85 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

total = sum_array(b[], LEN); /*** WRONG ***/


total = sum_array(b[LEN], LEN); /*** WRONG ***/

Example
total = sum_array(b[10], LEN); /*** WRONG ***/
total = sum_array(b[5], LEN); /*** WRONG ***/

#include <stdio.h>
#define LEN 5
int sum_array(int[], int);
int main(void){
int b[LEN] = {1, 2, 1, 3, 1};
Array name only!
int total;
total = sum_array(b, LEN);
printf("Sum is: %d\n", total);

}
int sum_array(int a[], int n){
int i, sum = 0;
for(i=0; i<n; i++)
sum +=a[i];
return sum;
}

86 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

43
10.06.2021

Array arguments
 A function is allowed to change the elements of an
array parameter, and the change is reflected in the
corresponding argument
#include <stdio.h> void print_array(int a[], int n){
#define LEN 5
for(int i=0; i<n; i++)
printf("%d\t", a[i]);
void fill_array(int[], int); printf("\n");
void print_array(int[], int); }

int main(void){ void fill_array(int a[], int n){


int b[LEN] = {0};
for(int i=0; i<n; i++)
a[i] = i + 10;
print_array(b, LEN); }
fill_array(b, LEN);
print_array(b, LEN);
return 0;
}

87 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Array arguments
 If a function parameter is a multidimensional
array only the length of the first dimension
may be omitted when the parameter is declared.
#include <stdio.h> void print_array(int a[][LEN], int n){
#define LEN 5
for(int i=0; i<n; i++) {
void fill_array(int[][LEN], int); for (int j = 0; j < n; j++)
void print_array(int[][LEN], int); printf("%d\t", a[i][j]);
printf("\n");
int main(void){ }
int b[LEN][LEN] = {0}; printf("\n");
}
print_array(b, LEN);
fill_array(b, LEN); void fill_array(int a[][LEN], int n){
print_array(b, LEN);
return 0; for(int i=0; i<n; i++)
} for(int j=0; j<n; j++)
a[i][j] = i + j;
}

88 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

44
10.06.2021

Variable-Length Array Parameters


 Since C99
int sum_array(int a[], int n)
{
// no direct link between n
// and the length of the array a
}

int sum_array(int n, int a[n]) int sum_array(int a[n], int n)


{ {
//a's length explicitly stated as n /*** WRONG ***/
} }

int sum_array(int n, int a[*]) int sum_array(int, int [*])


{ {
// * provides a clue, that the
//...
// length of the array is
} // related to the parameters
// that come earlier in the list
}

int concatenate (int m, int n, int a[m], int b[n], int c[m+n]);

89 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Variable-Length Array Parameters


 Since C99
int sum_two_2D_array(int n, int m, int a[n][m]){
int i, j, sum = 0;

for(i=0; i<n; i++){


for(j=0; j<m; j++){
sum +=a[i][j];
}
}
return sum;
}

/*** CORRECT PROTOTYPES ***/


int sum_two_2D_array(int n, int m, int a[n][m]);
int sum_two_2D_array(int n, int m, int a[*][*]);
int sum_two_2D_array(int n, int m, int a[][m]);
int sum_two_2D_array(int n, int m, int a[][*]);

90 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

45
10.06.2021

Pointers
Pointers
- are special variables used to store addresses rather than values;
- store address of variables or a memory location

WSK – pointer Address Byte content

WSK = 2460
WSK is now pointing to the memory location
with the address 2460

Memory content at adress 2460 is: 11100101

Addresses of the memory cells are integers,


thus pointers only accept integer values.

91 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Declaring Pointers

TYPE *pointer_variable_name;

 TYPE – pointer type can be a basic type of the C language


or a complex type (e.g. a structure) .

int *pi; /*pi is a pointer to integer variable*/


char *pc; /*pc is a pointer to character variable*/
float *pf; /*pf is a pointer to floating point variable*/

 Pointer type and type of a variable it points must agree.

92 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

46
10.06.2021

Assigning Addresses to Pointers


TYPE variable = value;
TYPE *pointer = &variable;

 Until not set, a pointer points nothing meaningful.


 Operator & (ampersand) returns an address of a variable.

int i = 10; float f = 3.14;


int *pi = &i; float *pf;
pf = &f;
Assigning an address to the Assigning an address to the
pointer at the declaration. pointer after the declaration.

93 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointer Dereferencing
TYPE variable = value;
TYPE *pointer = &variable;
TYPE val = *pointer;

 Operator & (ampersand) returns the address of a variable.


 Operator * (dereference operator or indirection operator)
returns an l-value equivalent to the value at the pointer
address.

int x=1, *wsk; x  *wsk


wsk = &x wsk  &x

94 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

47
10.06.2021

Example
#include <stdio.h>

int main(void)
{
int *wsk, x=1;

wsk = &x; // assigning wsk the address of x

/*print x*/
printf("*wsk = %d\n", *wsk); // indirectly
printf("x = %d\n", x); // directly

/*print address of x*/


printf("wsk = %p\n", wsk);
printf("&x = %p\n", &x);

return 0;
}
95 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Changing Value Pointed by Pointers


TYPE variable = value;
TYPE *pointer = &variable;
TYPE val = *pointer;
*pointer = new_value;

float f; float f = 3.14; float f = 3.14;


float *pf = &f; float *pf = &f; float *pf;
*pf = 10.8; *pf = 10.8; *pf = 10.8;

Indirect assignment of a value Indirect change of a value of a ERROR!


to a variable variable Pointer pf points nothing !

96 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

48
10.06.2021

Example
int x, a = 1, b = 2;
int *p;

Changing the value of x:

1. p = &a; x = *p; // x=1


2. *p = 0; x = a; // x=0
3. p = &b; x *= *p; // x=0*2=0
4. x = *p; // x=2
5. x = *p/2; // x=2/2=1

97 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void)
{
double q, *p = &q;
*p = 199.89; /*assigning a value to q */
printf("value of q is: %lf\n", q);
printf("address of q is: %p\n\n", p);

*p = 39.45; /*indirect change of q*/


printf("After indirect change:\n--------------------------\n");
printf("value of q is: %lf\n", q);
printf("address of q is: %p\n\n", p);

q = 100.001; /*direct change of q*/


printf("After direct change:\n--------------------------\n");
printf("value of q is: %lf\n", q);
printf("address of q is: %p\n\n", p);

return 0;
} 98 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

49
10.06.2021

Type Compatibility
unsigned int zm = 65530;
Byte 1 Byte 2

unsigned char *wsk = &zm;


the result of dereferencing wsk is 255
Byte 1

unsigned long int *wsk2 = &zm;


the result of dereferencing wsk2 is 4294639360
Byte 1 Byte 2 Byte 3 Byte 4

99 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void)
{
int *p;
double q, temp;
tymcz = 1234.34;

p = &temp; //ERROR
q = *p; //ERROR – only 2 bytes are copied

printf("%f", q);

return 0;
}

100 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

50
10.06.2021

Pointer arithmetic
 There are four arithmetic operators that can be used on
pointers: ++, --, +, and -.
 Only integers can be used as operands in pointer
arithmetic.
 The pointer arithmetic is performed relative to the base
type of the pointer – after each increment by 1, it will
point to the next memory element (in the sense defined
by the base type) following the currently selected
element.
 Arithmetic operation on pointer changes the
address it points.
 Multiplication and division of pointers is not allowed.
101 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void){

char ch, *cp = &ch;


int i, *ip = &i;
float f, *fp = &f;
double d, *dp = &d ;

printf("%p %p %p %p\n", cp, ip, fp, dp);

cp++; ip++; fp++; dp++;

printf("%p %p %p %p\n", cp, ip, fp, dp);

return 0;
}
102 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

51
10.06.2021

Example
# include <stdio.h>

int main(void){

char ch, *cp = &ch;


int i, *ip = &i;
float f, *fp = &f;
double d, *dp = &d ;

printf("%d %d %d %d\n", cp, ip, fp, dp);

cp++; ip++; fp++; dp++;

printf("%d %d %d %d\n", cp, ip, fp, dp);

return 0;
}
103 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointer arithmetic
 Incrementing a pointed object vs. incrementing a
pointer

Incrementing a pointer: *wsk++

 Incrementing a pointer makes it point a next memory address.

Incrementing a pointed object: (*wsk)++

 To increment a pointed object, it needs to be


dereferenced first.

104 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

52
10.06.2021

Example
#include <stdio.h>

int main(void){

int *p, q;
p = &q;
q = 1;

printf("p = %p\n", p);

*p++;

printf("q = %d, p = %p, *p = %d", q, p, *p);

return 0;
}

105 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void){

int *p, q;
p = &q;
q = 1;

printf("p = %p\n", p);

(*p)++;

printf("q = %d, p = %p, *p = %d", q, p, *p);

return 0;
}

106 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

53
10.06.2021

Pointers and arrays (1)

 Pointers offer an efficient way to deal with arrays; array


notation is a disguised use of pointers.
int a[10];
int *pa;
pa = &a[0]; // pa represents the memory address of array

pa – address of array first element  &a[0]


*pa – value of array first element  a[0]
pa+i – address of array i-th element  &a[i]
*(pa+i) – value of array i-th element a[i]
107 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointers and arrays (2)

 An array name represents the memory address of that


first element.
int a[10];
int *pa;
pa = a; // pa represents the memory address of array

a – address of array first element  &a[0]


*a – value of array first element  a[0]
a+i – address of array i-th element  &a[i]
*(a+i) – value of array i-th element a[i]
108 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

54
10.06.2021

Pointers and arrays (3)

 The difference between the array name and the pointer


int a[10];
int *pa;
pa = a; // pa represents the memory address of array

pa = a; a = pa;
pa ++; a ++;

Correct Incorrect
since a pointer is a since an array name is
variable not a variable

109 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void){

int a[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *pa = a; //assign pa an address of a

/* print 1st, 2nd and 3rd array element*/


printf("%d %d %d\n", a[0], a[1], a[2]);

/* again – using a pointer*/


printf("%d %d %d\n", *pa, *(pa+1), *(pa+2));

/* and again */
printf("%d %d %d\n", *a, *(a+1), *(a+2));

return 0;
}

110 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

55
10.06.2021

Example
#include <stdio.h>

int main(void){

int a[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *pa = a; //assign pa an address of a

/* print 1st, 2nd and 3rd array element*/


printf("%d %d %d\n", a[0], a[1], a[2]);

/* again – using a pointer*/


printf("%d %d %d\n", *pa, *pa+1, *pa+2); Error!!
First dereference, then
/* and again */ increase!
printf("%d %d %d\n", *a, *a+1, *a+2);

return 0;
}

111 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#define SIZE 4

int main(void)
{
short dates[SIZE], *wski;
double bills[SIZE], *wskf;
wski = dates;
wskf = bills;
short id;

printf("%23s %10s\n", "short", "double");

for (id = 0; id <SIZE; id++)


printf("pointer+%d: %10p %10p\n", id, wski+id, wskf+id);

return 0;
}

112 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

56
10.06.2021

Example
#include <stdio.h>

int main(void)
{
int i;
int a[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *pa = a; //assign pa an address of a

for (i=0; i<10; i++)


printf("%d\t", *(pa+i));

return 0;
}

113 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void)
{
int i;
float a[10]={1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1};
float *pa = a; //assign pa an address of a

for (i=0; i<10; i++)


printf("%f\t", *(pa+i));

return 0;
}

114 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

57
10.06.2021

Passing pointers to functions


 Pointers can be parameters of functions
TYPE FunctionName (TYPE* ptr);

 Pointer as a function parameter is used to hold addresses of


arguments passed during function call (call by reference).
 When a function is called by reference any change made to the
reference variable will effect the original variable.
void swap(int x, int y){ void swap(int *x, int *y){
int temp; int temp;
temp = x; temp = *x;
x = y; *x = *y;
y = temp; *y = temp;
} }
int a=5, b=3; int a=5, b=3;
swap(a,b); swap(&a, &b);
// a=5, b=3 // a=3, b=5
115 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

void func_var (int var){


var = 4;
}
void func_pointer (int *var) {
(*var) = 5;
}

int main (void){


int z=3;
printf ("z= %d\n", z);
func_var (z); printf ("z= %d\n", z);
func_pointer (&z);
printf ("z= %d\n", z);
return 0;
}

116 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

58
10.06.2021

Passing arrays to functions - again


 Arrays passed to functions are converted to pointers
 TYPE tab[] and TYPE *tab used as function
arguments are considered equivalent

int sum (int *tab, int n);


int sum(int *, int);
int sum(int tab[], int n);
int sum(int [], int);

117 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

void my_puts(char *p);

int main(void){
char napis1[] = "this is string #1";
my_puts(napis1);
my_puts("this is string #2");
return 0;
}

void my_puts(char *p){


while(*p) { // repeat until string end
printf("%c", *p);
p++; //move to the next character
}
printf("\n");
} strings in C end with terminator '\0'

118 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

59
10.06.2021

Example
#include <stdio.h>

void my_puts(char p[]);

int main(void){
char napis1[] = "this is string #1";
my_puts(napis1);
my_puts("this is string #2");
return 0;
}

void my_puts(char p[]){


int i = 0;
while(p[i]) { // repeat until string end
printf("%c", p[i]);
i++; //move to the next character
}
printf("\n"); strings in C end with terminator '\0'
}

119 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#define SIZE 10

long sum(int *begin, int* end);

int main(void) {
int numbers[SIZE] = {20,10,5,39,4,16,19,26,31,20};
long result;
result = sum(numbers, numbers+SIZE);
printf("Sum of the numbers is: %ld.\n", result);
return 0;
}

long sum(int *begin, int* end){


long result = 0;

while(begin<end){
result += *begin; /* update sum */
begin ++; /* move pointer to the next element */
/* suma += *begin ++*/
}

return result;
}
120 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

60
10.06.2021

strings in C end with terminator '\0'


Example
 Copying strings (arrays of characters)
Version 1 Version 2
void strcpy(char *s, char *t) void strcpy(char *s, char *t)
{ {
int i = 0; while((*s = *t) != '\0')
{
while((s[i] = t[i]) != '\0') s++;
i++; t++;
} }
}

Version 3 Version 4
void strcpy(char *s, char *t) void strcpy(char *s, char *t)
{ {
while((*s++ = *t++) != '\0'); while(*s++ = *t++);
} }

121 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Protecting Array Elements


 Arrays marked as const on the function parameter list can
not be changed by a function

TYPE fun_name(const TYPE* ptr);

long sum(const int *tab, int n); /*prototype*/

long sum(const int *tab, int n) /*definition*/


{
int i;
long result = 0;
for(i=0; i<n; i++)
{
result+=(*(tab+i))++; Error !!
}
return result;
}
122 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

61
10.06.2021

Arrays of pointers
 Array of pointers (pointer arrays) is an array of the
pointer variables.

TYPE *tab[SIZE];

int *ptr[6]; - declaration of a 6-element array


of pointers to integers
ptr[3] = &zm; - assigning the address of the variable zm
to the 4th element of array pa

*ptr[2] = 10; - assigning a value of 10 to the variable


pointed by the 3rd element of array pa

123 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Character pointers
 Character array vs character pointer.
 String literal: "Hello World"
 strings in C end with terminator '\0'

char arr[] = "Hello World"; /*array*/


char *ptr = "Hello World " ; /*pointer*/

124 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

62
10.06.2021

Example
#include <stdio.h>
#include <string.h>

/* the program reads the strings until the word "end" appears */

int main(void)
{
char *p = "end";
char nap[80];

do{
printf("Input text: ");
gets(nap);
puts(nap);
}while(strcmp(p,nap));

return 0;
}

125 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Arrays of character pointers


 Common usage – arrays of strings
char *p[] = {
"Input exceeds field length",
"Out of range",
"Printer off",
"Out of Paper",
"Disk overflow",
"Disk I/O error"
};

void error(int error_id)


{
printf(p[error_id]);
}

126 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

63
10.06.2021

Example
#include<stdio.h>

int main()
{
char *name[5]={
"Jerzy",
"Michal",
"Jan",
Initialization list
"Marek",
"Zosia"};

int ctr;

for(ctr=0; ctr<5; ctr++)


{
printf("String #%d: %s\n",(ctr+1),*(name+ctr));
}

return 0;
}

127 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointers and multidimensional arrays


 In C language a 2D array is 1D array of 1D arrays
int zippo[4][2]; /*an array of int arrays*/

zippo  &zippo[0]  &zippo[0][0]

 zippo+n - address of the n-th row


 zippo[n]+m - address the m-th element in the n-th row
 *(zippo[0]) – value
of the element zippo[0][0]
 *zippo  &zippo[0][0] thus *&zippo[0][0]  **zippo

zippo[2][1] *(*(zippo+2)+1)

128 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

64
10.06.2021

Pointers and multidimensional arrays


 Each element of a two-dimensional array is an array and thus
the address of the first element, hence:
zippo[0]  &zippo[0][0]  *zippo
zippo[i]  &zippo[i][0]  *(zippo+i)

 After dereferencing a pointer with *operator:


*zippo[0]  zippo[0][0]  **zippo
*zippo[i]  zippo[i][0]  *(*(zippo+i))

zippo[m][n]  *(*(zippo+m)+n)

129 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void)
{
int zippo[4][2] = {{2, 4},{6, 8},{1, 3},{5, 7}};

printf("zippo=%p,\t zippo+1=%p\n", zippo, zippo+1);


printf("zippo[0]=%p,\t zippo[0]+1=%p\n", zippo[0], zippo[0]+1);
printf("*zippo=%p,\t *zippo+1=%p\n", *zippo, *zippo+1);
printf("zippo[0][0]=%d\n", zippo[0][0]);
printf("*zippo[0]=%d\n", *zippo[0]);
printf("**zippo=%d\n", **zippo);
printf("zippo[2][1]=%d\n", zippo[2][1]);
printf("*(*(zippo+2)+1)=%d\n", *(*(zippo+2)+1));

return 0;
}

130 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

65
10.06.2021

Pointer to 2D array
 Pointer to two dimensional array:
TYPE (*name)[num_columns]

int tab[4][2] = {{1,2},{2,3},{3,4},{4,5}};


int(*pz)[2];
pz = tab;

 Array of pointers:
TYPE *name[num_rows]

131 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

int main(void)
{
int zippo[4][2] = {{2, 4},{6, 8},{1, 3},{5, 7}};
int (*pz)[2];
pz = zippo;

printf("pz = %p, \t\t pz+1 = %p\n", pz, pz+1);


printf("pz[0] = %p, \t pz[0]+1 = %p\n", pz[0], pz[0]+1);
printf("*pz = %p, \t *pz+1 = %p\n", *pz, *pz+1);
printf("pz[0][0] = %d\n", pz[0][0]);
printf("*pz[0] = %d\n", *pz[0]);
printf("**pz = %d\n", **pz);
printf("pz[2][1] = %d\n", pz[2][1]);
printf("*(*(pz+2)+1) = %d\n", *(*(pz+2)+1));

return 0;
}
132 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

66
10.06.2021

File I/O
 Stream – an idealized flow of data to which the actual
input or output is mapped; interconnected input and
output communication channels between a computer
program.
 File – a collection of data which is stored on a secondary
device, an input/output device
 Most popular is a disk file.
 Three standard streams

133 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Text file vs. Binary file


 There are two types of files:
 text files – all the contents within the file as plain text
(translation to the printable ASCII characters)
 binary files – store data in the binary form (raw 0's and 1's)

number: 32767
00110011 00110010 00110111 00110110 00110111 00110011 00110010
'3' '2' '7' '6' '7' 32767

in a text file in a binary file


(or reverse byte order)

134 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

67
10.06.2021

File I/O
 File processing functions are available in <stdio.h>
 Files are terminated by EOF (ang. End of File)
 File Pointer - needed for communication between the
file and the program.

FILE *f; 1. Open a file in a


selected mode
 It stores current position (position)
in a file (the place where the next access
2. Process file
operation will start).

3. Close file

135 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Working with files


 File opening
FILE *fopen(char* file_name, char* mode);
 returns a file handle, which is a pointer used to reference the
file or NULL if file couldn’t be open
Mode File Open for Create File? Notes
It adds to the end of an existing file; a file is created if it
"a" Appending Yes
doesn’t exist.

"a+" Appending and reading Yes Information is added to the end of the file.

"r" Reading No If the file doesn’t exist, fopen() returns an error.

"r+" Reading and writing No If the file doesn’t exist, an error is returned.

"w" Writing Yes The existing file is overwritten if the same name is used.

"w+" Writing and reading Yes The existing file is overwritten.


136 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

68
10.06.2021

Working with files


 File opening

FILE *fp;
fp = fopen("file.txt", "r");

if (fp==NULL)
{
printf("File opening error\n");
exit(1); /*or error handling procedure*/
}

137 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Working with files


 File closing
 The file (both text and binary) should be closed after reading/writing.

int *fclose(FILE *fp);

 pf is a file pointer associated with the file to be closed


 returns 0 on success
 returns EOF on failure

138 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

69
10.06.2021

Working with files


 Reading and writing bytes (characters)
int fgetc(FILE *fp);

 gets character from stream fp


 returns the character currently pointed by the internal file
position indicator of the specified stream. The internal file
position indicator is then advanced to the next character.
int fputc(int ch, FILE *fp);

 writes a character ch to the stream fp and advances the position


indicator
 on success, the character written is returned.
 If a writing error occurs, EOF is returned and the error indicator
(ferror) is set.
139 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <stdlib.h>
/* file write example */
int main(void) {
char nap[80] = "This is file system test\n";
char *p = nap;
FILE *fp;
int i;
if((fp=fopen("file.txt","w"))==NULL){
printf("File opening error.\n");
exit(1);
}
while(*p){
if(fputc(*p,fp)==EOF){
printf("Wile writing error.\n");
exit(1);
}
p++;
}
fclose(fp);
return 0;
}

140 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

70
10.06.2021

Example
#include <stdio.h>
#include <stdlib.h>
/*file read example*/
int main(void){
FILE *fp;
int i; /*or char i*/
if((fp=fopen("file.txt","r"))==NULL){
printf("File opening error.\n");
exit(1);
}
for(;;){
i=fgetc(fp);
if(i==EOF) break;
putchar(i);
}
fclose(fp);
return 0;
}
141 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Functions feof() and ferror()


 Check end-of-file indicator
int feof(FILE *fp);

 checks whether the end-of-file indicator associated with


stream fp is set, returning a value different from zero if it is
 otherwise, zero is returned.

 Check error indicator


int ferror(FILE *fp);

 checks if the error indicator associated with stream fp is set,


returning a value different from zero if it is
 otherwise, zero is returned.
142 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

71
10.06.2021

Example
FILE *src, *dest;
char *pSrc = "file.txt", *cel = "file2.txt";
char ch;
if((src=fopen(pSrc,"rb"))==NULL) {
printf("Source file opening error\n"); exit(1);
}
if((src=fopen(cel,"wb"))==NULL) {
printf("Destination file opening error\n");
exit(1);
}
while(!feof(src)){
ch = fgetc(src);
if(ferror(src)){
printf("Source file reading error\n");
exit(1);
}
if(!feof(src))fputc(ch, dest);

if(ferror(dest)) {
printf("Destination file writing error\n");
exit(1);
}
}
if(fclose(src)==EOF) {
printf("Source file closing error\n"); exit(1);
}
if(fclose(src)==EOF) {
printf("Destination file closing error\n"); exit(1);
}143 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Writing strings to file


int fputs(char *str, FILE *fp);
 writes the C string pointed by str to the stream fp
 on success, a non-negative value is returned.
 on error, the function returns EOF and sets the error indicator
(ferror).

int fprintf(FILE *fp, char *fmt …);

 writes the C string pointed by format fmt to the stream fp


 on success, the total number of characters written is returned.
 on error, the error indicator (ferror) is set and a negative number is
returned.

144 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

72
10.06.2021

Reading strings from file


char *fgets(char *str, int num, FILE *fp);
 reads characters from stream fp and stores them as a C
string into str until (num-1) characters have been read or
either a newline or the end-of-file is reached, whichever
happens first.

int fscanf(FILE *fp, char *fmt, …);


 reads data from the stream fp and stores them according to
the parameter fmt into the locations pointed by the
additional arguments.

145 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h> /*program reads strings from user*/
#include <stdlib.h> /*and writes them to file until an empty line is input*/
#include <string.h>
int main(void){
FILE *fp;
char str[80];
if((fp=fopen("file.txt","w"))==NULL){
printf("File opening error\n");
exit(1);
}
printf("Input empty line to finish\n");
do{
printf(": ");
fgets(str, 79, stdin);
strcat(str,"\n"); /*add new line*/

if(*str!='\n') fputs(str,fp);

}while(*str!='\n');
fclose(fp);
return 0;
}

146 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

73
10.06.2021

Example
#include <stdio.h> /*program reads lines from file*/
#include <stdlib.h> /*and prints them on a screen*/

int main(void){
FILE *fp;
char str[80];

if((fp=fopen("file.txt","r"))==NULL){
printf("File opening error\n");
exit(1);
}

do{
fgets(str, 80, fp);
if(!feof(fp)) printf(str);
}while(!feof(fp));

fclose(fp);

return 0;
}

147 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example

#include <stdio.h> /*writes data to file*/


#include <stdlib.h> /*in a specified format*/

int main(void)
{
FILE *fp;

if((fp=fopen("file.txt","w"))==NULL){
printf("File opening error.\n");
exit(1);
}

fprintf(fp, "%lf %d %s", 12345.342, 1908, "Hello World!");

fclose(fp);

return 0;
}

148 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

74
10.06.2021

Example
#include <stdio.h> /*reads data from file*/
#include <stdlib.h> /*in a specified format*/

int main(void) {
FILE *fp;
char nap[80];
double ld;
int d;

if ((fp = fopen("file.txt", "r")) == NULL) {


printf("File opening error.\n");
exit(1);
}

fscanf(fp, "%lf %d %s", &ld, &d, nap);


printf("%lf %d %s", ld, d, nap);

fclose(fp);

return 0;
}

149 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Handling binary files


 Reading block of data from stream
size_t fread (void *buffer, size_t size, size_t count, FILE *fp)
 reads an array of count elements, each one with a size of size
bytes, from the stream and stores them in the block of memory
specified by buffer.
 returns the he total amount of bytes read if successful is
(size*count).
 file must be open in binary mode
void* pointer
can point any datatype
size_t (unsigned lub unsigned long)
alias of one of the fundamental unsigned
integer types; it is a type able to represent
the size of any object in bytes:
150 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

75
10.06.2021

Handling binary files


 Writeing block of data to stream

size_t fwrite (void *buffer, size_t size, size_t count, FILE *fp)

 writes an array of count elements, each one with a size of size


bytes, from the block of memory pointed by buffer to the current
position in the stream.
 the total number of elements successfully written is returned
 file must be open in binary mode

151 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <stdlib.h>

int main(void){
int i;
FILE *fp;
double d[10] = {10.23, 19.87, 1002.13, 12.9, 0.897, 11.45, 75.34,
0.0, 1.01, 875.875};

if((fp=fopen("file.txt","wb"))==NULL){
printf("File opening error.\n");
exit(1);
}

if(fwrite(d, sizeof d, 1, fp)!=1){


printf("Error when writing file");
exit(1);
}

fclose(fp);
return 0;
}
152 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

76
10.06.2021

Example
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i;
FILE *fp;
double d[10];
if((fp=fopen("file.txt","rb"))==NULL){
printf("File opening error.\n");
exit(1);
}
if(fread(d, sizeof d, 1, fp)!=1){
printf("File reading error");
exit(1);
}
fclose(fp);
for (i=0; i<10; i++){
printf("%lf\n", *(d+i));
}
return 0;
}

153 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Random file access


 Reading or writing information anywhere in the data file
int fseek (FILE *fp, long offset , int origin)

 sets the position indicator associated with the stream to a new


position.
 for streams open in binary mode, the new position is defined by
adding offset to a reference position specified by origin
 origins:
 SEEK_SET – beginning of file
 SEEK_CUR – current position of the file pointer
 SEEK_END – end of file
 if successful, the function returns zero; otherwise, it returns non-
zero value.
154 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

77
10.06.2021

Random file access


 Get current position in stream
long ftell (FILE *fp)

 returns the current value of the position indicator of the


stream fp, or -1 on error

155 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h> /*copies files in reverse order*/
#include <stdlib.h>
int main(void){
long offset;
FILE *source, *destination;
char ch;
if((source=fopen("zrodlo.txt","rb"))==NULL){
printf("Source file openning error.\n"); exit(1);
}
if((destination=fopen("cel.txt","wb"))==NULL){
printf("Destination file openning.\n"); exit(1);
}
fseek(source, 0L, SEEK_END);
offset = ftell(source);
offset = offset - 1; /*skip EOF*/
while(offset >= 0L){
fseek(source, offset, SEEK_SET);
ch = fgetc(source);
fputc(ch, destination);
offset --;
};
fclose(source);
fclose(destination);
return 0;
} 156 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

78
10.06.2021

Other file-functions
 Changing file name
int rename (char* old_name, char* new_name);

 Removing file
int remove (char* file_name);

 Setting file pointer at the beginning of the file


void rewind (FILE *fp);

 Cleaning stream

int fflush(FILE *fp);

157 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Void pointer
 A pointer that has no associated data type with it.
void* wsk;

 It can hold address of any type and can be typcasted to any type.
void *wskv;
int *wski;
float *wskf
wskv = wski; // correct
wskv = wskf; // correct

 Reverse assignment requires typecasting


wski = wskv; // ERROR !!
wski = (int*)wskv; // correct
wskf = (float*)wskv; // correct

158 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

79
10.06.2021

Example
#include <stdio.h>
int main(){
void *wskv;
char c = 'a';
int i=10;
float f=3.14;
wskv = &c;
printf("c=%c\n", *(char*)wskv);
wskv = &i; typecasting
printf("i=%d\n", *(int*)wskv);
wskv = &f;
printf("f=%f\n", *(float*)wskv);
return 0;
}

159 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

C structs
 In C programming, a struct (or structure) is a collection of
variables (can be of different types) under a single name.
 The struct statement defines a new composite data type,
with more than one member.
struct structure-name{
TYPE member1;
TYPE member2;
.
.
.
TYPE memberN;
}variable-names;

 variable-names are optional.

160 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

80
10.06.2021

Defining structures
names of structural types

struct point{
int x; struct coutry{
int y; char* capitol;
}; long population;
struct complex{ float area;
float im; char* continent;
float re; };
};

When a struct type is declared, no storage or memory is allocated.


To allocate memory of a given structure type and work with it, we need to create
variables.
161 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Defining structures
structural type

struct directory {
char surname [40]; /*author's name*/
char title [40]; /*title*/
char publisher [40];/*publisher*/
unsigned date; /*release date*/
unsigned char ed; /*edition*/
}card;
struct variable

Structure member names do not conflict with variables with the same names.

162 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

81
10.06.2021

Creating struct variables

struct directory{ struct directory{


char surname[40]; char surname[40];
char title[40]; char title[40];
char publisher[40]; char publisher[40];
unsigned date; unsigned date;
unsigned char ed; unsigned char ed;
}card; }
struct directory card;

Define structural type and create Define structural type, later create variable.
variable (at once).

163 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Creating struct variables

struct structure-name list of variables;

struct directory zm1;


struct directory zm2, zm3;

 Each struct variable contains its own copy of the


members

zm1.title != zm2.title

164 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

82
10.06.2021

Accessing members of a structure


 Accessing members of a structure requires using the member
access operator (.)

struct catalog{
char name[40];
char title[40];
char publisher[40];
unsigned date;
unsigned char ed; Name of a struct variable not
}card; name of a struct type!

card.date = 1776;
printf("Release date: %u",card.date);
scanf("%c",&card.ed);
fgets(card.name,39,stdin);
printf("%c",card.title[2]);

165 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
struct type_s{
int i;
char ch;
double d;
char nap[80];
}s;
int main(void){
printf("Input integer: ");
scanf(" %d", &s.i);
printf("Input character: ");
scanf(" %c", &s.ch);
printf("Input floating-point number: ");
scanf(" %lf", &s.d);
printf("Input string: ");
scanf("%s", s.nap);
printf("%d %c %lf %s", s.i, s.ch, s.d, s.nap);
return 0;
}

166 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

83
10.06.2021

Structure initialization
 Elelement by element
struct catalog{
struct catalog c1; char name[40];
strcpy(c1.name,"Sienkiewicz"); char title[40];
strcpy(c1.title,"Potop"); char publisher[40];
strcpy(c1.publisher,"Literatura"); unsigned date;
c1.date = 2001; unsigned char ed;
c1.ed = 2; };

 Initializers
struct catalog c2 = { struct catalog c3 = {
"Sienkiewicz", .ed = 2,
"Potop", .date = 2001,
"Literatura", .name = "Sienkiewicz",
2001, .publisher = "Literatura",
2 .title = "Potop"
}; };

167 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <string.h>
struct catalog{
char name[40];
char title[40];
unsigned date;
unsigned char ed;
};
int main(void){
struct catalog c1;
strcpy(c1.name,"Sienkiewicz");
strcpy(c1.title,"Potop");
c1.date = 2001;
c1.ed = 2;
struct catalog c2 = {"Mickiewicz","Pan Tadeusz",2012,3};
struct catalog c3 = {.ed = 1,.date = 2021,.name = "Tokarczuk",.title = "Bieguni"};
printf("%s %s %d %d\n", c1.name, c1.title, c1.date, c1.ed);
printf("%s %s %d %d\n", c2.name, c2.title, c2.date, c2.ed);
printf("%s %s %d %d\n", c3.name, c3.title, c3.date, c3.ed);

return 0;
}

168 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

84
10.06.2021

Array of Structures
 In an array of structures, each element of an array is of
the structure type.
struct type-name array-name[size];

struct catalog{
char name[40];
char title[40];
unsigned date;
unsigned char ed;
};

struct catalog cat[100]; //an array of 100 catalog structures

cat[0] // 1st structure in cat array


cat[33].ed = 2; // accessing member ed in 34th structure in cat array

169 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>

struct subscriber{
char name[20];
char surname[50];
char phone_number[15];
};

int main(void){

int i;
struct subscriber list[5];

for (i=0; i<5; i++){


printf("\nInput first name: ");
gets(list[i].name);
printf("Input family name: ");
gets(list[i].surname);
printf("Input phone number: ");
gets(list[i].phone_number);
}

for (i=0; i<5; i++){


printf("%d) %s %s %s\n", i+1, list[i].name, list[i].surname, list[i].phone_number);
}

return 0;
}

170 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

85
10.06.2021

Passing struct to function


 A structure can be passed to any function from main
function or from any sub function.
TYPE fun-name (struct type-name);
TYPE fun-name (struct type-name[SIZE]);

struct subscriber{
char name[20];
char surname[50]; Data type NOT a variable
char phone[15];
formal parameter
};
void print (struct subscriber); //function definition

void print (struct subscriber data) //function declaration
{
printf("%s %s %s\n", data.name, data.surname, data.phone);
}
171 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(1)
#include <stdio.h>
#include <stdlib.h>

/*define structural type*/


struct subscriber{
char name[20];
char surname[50];
char phone[15];
};

/*declare functions with structural parameters*/


int menu(void);
void input_data(struct subscriber[]);
void print_data(struct subscriber[]);
void save_to_file(struct subscriber[]);
void load_from_file(struct subscriber[]);

172 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

86
10.06.2021

Example(2)
int main(void){
int choice;
struct subscriber data[5];
do{
choice = menu();
switch(choice)
{
case 1:
input_data(data); break;
case 2:
print_data(data); break;
case 3:
save_to_file(data); break;
case 4:
load_from_file(data); break;
}

}while(choice!=5);
return 0;
} 173 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(3)
int menu(void){
int i;
char str[80];
printf("\n\nSelect option:\n");
printf("1. Input data\n");
printf("2. Print list content\n");
printf("3. Save to file\n");
printf("4. Load from file\n");
printf("5. End\n");
do{
printf("Select option: ");
gets(str);
i=atoi(str);
printf("\n\n");
}while(i<1 || i> 5);

return i;
}

174 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

87
10.06.2021

Example(4)
void input_data(struct subscriber list[]){
int i;
for (i=0; i<5; i++){

printf("\nInput first name: ");


gets(list[i].name);
printf("Input family name: ");
gets(list[i].surname);
printf("Input phone number: ");
gets(list[i].phone);
}
return;
}
void print_data(struct subscriber list[]){

int i;
for (i=0; i<5; i++){
printf("%d) %s %s %s\n", i+1, list[i].name, list[i].surname,
list[i].phone);
}
return;
}
175 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(5)
void save_to_file(struct subscriber list[]){

FILE *fp;

if((fp = fopen("database","wb"))==NULL){
printf("Database opening error\n");
exit(1);
}

if ((fwrite(list, sizeof (struct subscriber), 5, fp))!=5){


printf("Database writting error\n");
exit(1);
}

fclose(fp);
}

176 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

88
10.06.2021

Example(6)
void load_from_file(struct subscriber list[]){

FILE *fp;

if((fp = fopen("database","rb"))==NULL){
printf("Database opening error\n");
exit(1);
}

if (fread(list, sizeof (struct subscriber), 5, fp)!=5){


printf("Database reading error\n");
exit(1);
}

fclose(fp);
}

177 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointers to struct
 A pointer to structure can point to the address of a structure
variable.

struct type_s{
struct variable
int i;
char str[80];
}s, *p
a pointer to struct type_s
p = &s;
p stores address of s
struct type_s t, *q;
q = &t;

178 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

89
10.06.2021

Pointers to struct
 To access members of a structure using pointers, we use
the -> operator.
struct type-name s, *pt;
pt = &s;
s. member  pt->member

struct type_s{
int i;
char str[80];
}s, *p
p = &s;
Direct member access Member access via pointer
s.i = 10; p->i = 10;
gets(s.str); gets(p->str);

179 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <string.h>
struct type_s{
int i;
char str[80];
} s, *p;
int main(){
p=&s;
s.i = 10;
strcpy(s.str,"Hello World!");
printf("Directly: i=%d, str=%s\n", s.i, s.str);
printf("Indirectly: i=%d, str=%s\n", p->i, p->str);
p->i = 11;
strcpy(p->str,"New Test String");
printf("\nDirectly: i=%d, str=%s\n", s.i, s.str);
printf("Indirectly: i=%d, str=%s\n", p->i, p->str);
return 0;
}

180 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

90
10.06.2021

Example a
#include <stdio.h>
#include <string.h>
/********************************************************************************************************************/
struct type_s{
int i;
char str[80];
};
/********************************************************************************************************************/
void fill_struct (struct type_s*, int, char[]);
/********************************************************************************************************************/
int main(){
struct type_s s;
fill_struct(&s, 10, "Hello World!");
printf(" i=%d\n str=%s\n", s.i, s.str);

return 0;
}
/********************************************************************************************************************/
void fill_struct (struct type_s *s, int i, char str[]){
s->i = i;
strcpy(s->str, str);
}

181 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example b
#include <stdio.h>
#include <string.h>
/********************************************************************************************************************/
struct type_s{
int i;
char str[80];
};
/********************************************************************************************************************/
void fill_struct (struct type_s*, int, char[]);
/********************************************************************************************************************/
int main(){
struct type_s s, *p=&s;
fill_struct(p, 10, "Hello World!");
printf(" i=%d\n str=%s\n", s.i, s.str);

return 0;
}
/********************************************************************************************************************/
void fill_struct (struct type_s *s, int i, char str[]){
s->i = i;
strcpy(s->str, str);
}

182 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

91
10.06.2021

Nested Structures
 A structure can be nested inside another structure - the members
of a structure can be of any other type including structure.

struct book_t { struct catalog{


unsigned date; char name[80];
unsigned char ed; char title[80];
unsigned pages; char publisher[80];
} struct book_t book;
}record;

 Accessing the members of the inner structure:

record.book.date = 2001;
record.book.ed = 2;
record.book.pages = 201;

183 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Nested Structures
struct addressInfo {
char address[30];
char city[10];
char state[2];
long int zip;
}

struct employees { struct customers {


char empName[30]; char custName[30];
struct addressInfo eAddress; struct addressInfo cAddress;
double salary; double balance;
} }

184 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

92
10.06.2021

Example a
#include <stdio.h>

typedef struct type_t{


int p1;
char p2; struct type definition
double p3;
} new_type;

void print (new_type); new name for the existing type

int main(){
new_type s1 = {1, 'a', 3.16};
struct type_t s2 = {2, 'b', 4.20};

print(s1);
print(s2);

return 0;
}

void print (new_type s){


printf("p1=%d, p2=%c, p3=%f\n", s.p1, s.p2, s.p3);
return;
}
185 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example b
#include <stdio.h>

typedef struct{
int p1;
char p2;
double p3;
} new_type;

void print (new_type);

int main(){
new_type s1 = {1, 'a', 3.16};
new_type s2 = {2, 'b', 4.20};

print(s1);
print(s2);

return 0;
}

void print (new_type s){


printf("p1=%d, p2=%c, p3=%f\n", s.p1, s.p2, s.p3);
return;
}
186 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

93
10.06.2021

Bit Fields
 Declares a struct member with explicit size, in bits.
 Adjacent bit field members may be packed to share and
straddle the individual bytes.
TYPE: size;

the number of bits


 TYPE – int or unsigned
 Bit fields members can not be accessed via pointers as
they may not start at a byte boundary.

187 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Bit Fields
 Example: one byte used instead of four
struct type_b {
unsigned department: 3; / * up to 7 departments * /
unsigned in_stock: 1; / * 1 if yes, 0 if not * /
unsigned ordered: 1; / * 1 if yes, 0 if not * /
unsigned advance: 3; / * up to 7 months * /
} inv [MAX_ELEM];

 Accessing bit fields


inv[9].department = 3;

if(!inv[4].in_stock)
printf("Product not available");
else
printf("Product available – department %d\n",
inv[4].department);
188 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

94
10.06.2021

Bit Fields
 It is not necessary to define all bits up to the full byte
struct type_b{
int a: 2;
int b: 3;
}

 It is not necessary to name every bit in a byte

struct type_b{
unsigned first: 1; use of the first and last bit in a byte
int: 6;
unsigned last: 1;
}

189 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <stdio.h>
#include <stdlib.h>
Example(1) #include <time.h>
struct telemetry{
unsigned fuel: 1;
unsigned radio: 1;
unsigned tv: 1;
unsigned water: 1;
unsigned meals: 1;
unsigned trash: 1;
}flight_status;
/**************************************/
void display(struct telemetry i);
void save(struct telemetry i);
/**************************************/
int main(void){
int i;
srand(time(NULL));
for (i=0; i<10; i++){
flight_status.fuel = rand()%2;
flight_status.radio = rand()%2;
flight_status.tv = rand()%2;
flight_status.water = rand()%2;
flight_status.meals = rand()%2;
flight_status.trash = rand()%2;
display(flight_status);
save(flight_status);
}
return 0;
}
190 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

95
10.06.2021

Example(2)
void display(struct telemetry i){

if(i.fuel) printf("Fuel OK\n");


else printf("Fuel reserve\n");

if(i.radio) printf("Radio OK\n");


else printf("Radio failure \n");

if(i.tv) printf("TV system OK\n");


else printf("TV system failure\n");

if(i.water) printf("Water supply OK\n");


else printf("No water supply\n");

if(i.meals) printf("Food supply OK\n");


else printf("No food\n");

if(i.trash) printf("Waste storage system OK\n");


else printf("Failure of the waste storage system\n");
}

191 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(3)
void save(struct telemetry i){

FILE *fp;
int ile;

if((fp=fopen("lot","wb"))==NULL){

printf("Blad otwarcia pliku");


exit(1);
}

if ((ile=fwrite(&i, sizeof i, 1, fp))!=1){

printf("Blad zapisu");
exit(1);
}

fclose(fp);
}

192 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

96
10.06.2021

Unions
 A union is a special data type that allows to store different
data types in the same memory location.
 It can comprise many members, but only one member
can contain a value at any given time.
 Unions provide an efficient way of using the same memory
location for multiple-purpose.

union union-name{
TYPE member1;
TYPE member2;

TYPE memberN;
}list-of-variables;

193 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Union type
 Storage of unions in memory:
union typ_u{ c[0] c[1]
int i;
char c[2];
double d; i
}sample, *ptr; d
ptr = &sample;

 Structure allocates storage space for all its members separately.


 Union allocates one common storage space for all its members.
 Accessing union members:
 directly: union_variable.member_name:
 sample.i = 10;
 indirectly: union_pointer->member_name
 ptr->i = 10;
194 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

97
10.06.2021

Union type
 Define union type:

union store{
int digit;
double numDouble; size: 8 bytes (64 bits)
char letter;
};

 Declare union variables:


union store fit; /* union, 8 bytes */
union store tab[10];/* array of 10 unions, 10 x 8 bytes */
union store *wu; /* union pointer, 8 bytes */

195 dr hab. inż. Anna Fabijańska, prof. PŁ, Podstawy Programowania II

Example
#include <stdio.h>
#include <string.h>
union type_u{
int i;
char c[2];
double d;
}sample, *ptr = &sample;
int main(void){
sample.d = 19.11;
printf("sample.d = %f\n", sample.d);
printf("sample.c = %s\n", sample.c);
printf("sample.i = %d\n\n", sample.i);
ptr->i = 0;
printf("sample.d = %f\n", sample.d);
printf("sample.c = %s\n", sample.c);
printf("sample.i = %d\n\n", sample.i);
strcpy(sample.c, "x");
printf("sample.d = %f\n", sample.d);
printf("sample.c = %s\n", sample.c);
printf("sample.i = %d\n", sample.i);
return 0;
}
196 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

98
10.06.2021

Example
#include <stdio.h>
struct point1{
int x, y;
};
union point2 {
int x, y;
};
int main() {
struct point1 t1 = {1,2};
union point2 t2;
t2.x = 3;
printf ("Member values - union: %d %d\n\n",t2.x, t2.y);
t2.y = 4;
printf ("Member values - union: %d %d\n\n", t2.x, t2.y);
printf("Member values - struct: %d %d\n\n",t1.x,t1.y);
t1.x = 4;
printf ("Member values - struct: %d %d\n\n", t1.x, t1.y);
return 0;
} 197 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Encrypt an integer by changing its two lowest bytes

Example
int encrypt(int); int encrypt(int i){

int main(void){ union type_cipher{


int num;
int i; char c[2];
}cipher;
i = encrypt(10); unsigned char ch;
printf("10 encrypted: %d\n", i);
i = encrypt(i); cipher .num=i;
printf("decrypted i is: %d\n", i); /*change byte order*/

return 0; ch = cipher.c[0];
} cipher.c[0] = cipher.c[1];
cipher.c[1] = ch;
return cipher.num;
}

198 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

99
10.06.2021

Wyświetlanie binarnej reprezentacji znaku


Example wprowadzonego z klawiatury

#include <stdio.h> 1. int main(void){ 2.


struct sample{ printf("Press key: ");
unsigned a: 1; key.ch = getchar();
unsigned b: 1;
printf("\nBinary representation: ");
unsigned c: 1;
unsigned d: 1; key.bits.h ? printf("1"): printf("0");
unsigned e: 1; key.bits.g ? printf("1"): printf("0");
unsigned f: 1; key.bits.f ? printf("1"): printf("0");
unsigned g: 1; key.bits.e ? printf("1"): printf("0");
unsigned h: 1; key.bits.d ? printf("1"): printf("0");
}; key.bits.c ? printf("1"): printf("0");
key.bits.b ? printf("1"): printf("0");
union key_t{
key.bits.a ? printf("1"): printf("0");
char ch;
return 0;
struct sample bits;
}
}key;

199 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include<stdio.h>
struct student {
union {
char name[10];
int id;
};
int mark;
}; union nested in struct
int main() {
alternative use of a member
struct student stud;
char choice; in a structure
printf("You can enter either name or id\n");
printf("Do you want to input name (y or n): ");
scanf(" %c",&choice);
if(choice=='y'||choice=='Y') {
printf("Input name: ");
scanf("%s",stud.name);
printf("Name:%s",stud.name);
}
else {
printf("Input student id: ");
scanf("%d", &stud.id);
printf("Student id: %d",stud.id);
}
printf("\nInput mark:");
scanf("%d",&stud.mark);
printf("Mark: %d",stud.mark);
return 0;
Example
}
200 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

100
10.06.2021

#include<stdio.h>
Example
struct job_t{
union {
char * company;
char * school;
char * project;
};
union {
char * location;
char * url;
};
union { Three nested anonymous unions
char * title;
char * program;
};
char * description;
}; Initialization
int main(){
struct job_t yelp = {
.company = "Yelp, Inc.",
.location = "San Francisco, CA",
.title = "Software Engineer, i18n",
.description = "Developed several internal tools and libraries"};
printf("Job: %s\n", yelp.project);
printf("Place: %s\n", yelp.url);
printf("Title: %s\n", yelp.program);
printf("Desc: %s\n", yelp.description);
return 0;
}
201 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Enumeration
 An enumeration type (also called enum) is a data type
that consists of integral constants.

 It is mainly used to assign names to integral constants, the


names make a program easy to read and maintain.

enum type-name {constant-list} variables;

 Either type-name or variables are optional.

202 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

101
10.06.2021

Enumeration
enum color {red, green, yellow};

enum logical{true, false};

type name
list of constants (enum names)

 An enum variable can take only one value.

 Create (declare) variables of enum types:


enum color zm;
enum logical x, y, z;

 Enumerations are not strings!

203 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example a
#include <stdio.h>

enum color {red, green, yellow, blue, cyan, magenta};


enum color k;

int main(){

k=red;

if (k==red) printf("It's red!\n");


if (k==0) printf("It's red!\n");

k=yellow;

if (k==yellow) printf("It's yellow!\n");


if (k==2) printf("It's yellow!\n");

for(int i=red; i<magenta; i++)


printf("%d ", i);

return 0;
}

204 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

102
10.06.2021

Example b
#include <stdio.h>

enum color {red, green, yellow, blue, cyan, magenta};


enum color k;

int main(){

k=red;

if (k==red) printf("It's red!\n");


if (k==0) printf("It's red!\n");

k = 2; // Error!

if (k==yellow) printf("It's yellow!\n");


if (k==2) printf("It's yellow!\n");

for(int i=red; i<magenta; i++)


printf("%d ", i);

return 0;
}

205 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum transportation{car, train, plane, bus};
int main(void){
srand(time(NULL));
int choice, i = 10;
while(i-->0) choice = rand()%4;
if (choice == car)
printf("\nCar selected \n");
else if (choice == train)
printf("\nTrain selected \n");
else if (choice == plane)
printf("\nPlane selected \n");
else if (choice == bus)
printf("\nBus selected \n");
return 0;
}

206 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

103
10.06.2021

Enumeration
 If not all values are specified, items are assigned increasing
integer values starting with the last explicitly specified
value.
enum day {MON = 1, TUE, WED, THU, FRI, SAT, SUN};

/* MON is 1, TUE is 2, SUN is 7 */

enum brand {VOLKSWAGEN, AUDI, SKODA = 9, BENTLEY,


BUGATTI = 32, LAMBORGHINI};

/* VOLKSWAGEN = 0, AUDI = 1,
* SKODA = 9, BENTLEY = 10,
* BUGATTI = 32, LAMBORGHINI = 33 */

207 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Enumeration
 Enum names can not repeat
 Inteager values assigned to enum names can repeat

enum boolean {NO = 0, FALSE = 0, YES = 1, TRUE = 1};

/* or shorter: */

enum boolean {NO,FALSE = 0, YES,TRUE = 1};

208 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

104
10.06.2021

Bool type definition

Example a
#include <stdio.h>
#include <ctype.h>

enum bool{TRUE = 1, FALSE = 0};

int main(){
char c;
enum bool dig;

printf("Input character\n");
scanf("%c", &c);
dig = isdigit(c) == 0 ? FALSE : TRUE;
if ( dig == TRUE )
printf("Input is a digit\n");
else
printf("Input is not a digit\n");

return 0;
}
209 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Bool type definition

Example b
#include <stdio.h>
#include <ctype.h>

typedef enum {TRUE = 1, FALSE = 0} bool;

int main(){
char c;
bool dig;

printf("Input character\n");
scanf("%c", &c);
dig = isdigit(c) == 0 ? FALSE : TRUE;
if ( dig == TRUE )
printf("Input is a digit\n");
else
printf("Input is not a digit\n");

return 0;
}
210 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

105
10.06.2021

Stack
 Stack is a linear data structure (a sequential collection),
 LIFO (ang. last-in-first-out)
 the push and pop operations occur only at one end of the structure,
referred to as the top of the stack

211 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Static implementation of stack


 Static stack has a fixed size and is implemented as array

struct stack{
int top;
TYP elements[MAXLENGTH];
}

10 first element
23 second element
12
30
14
13 last (deepest) element

212 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

106
10.06.2021

A bounded stack

 PUSH(x, S)  x = POP(S)

START START

YES IS NO TAK IS NIE


STACK STACK
FULL? EMPTY?

ERROR TOP = TOP - 1 ERROR x = ELEMENTS[TOP]


ELEMENTS[TOP] = x TOP = TOP + 1

STOP STOP

Stack is full when TOP = 0 Stack is empty if TOP = MAXLENGTH

213 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(1)
#include <stdio.h>

#define MAXLENGTH 5
/*****************************************/
struct stack{
int top;
int elements[MAXLENGTH];
};
/*****************************************/
int top (struct stack S);
int pop (struct stack* S);
int empty (struct stack S);
void print(struct stack S);
void makenull(struct stack* S);
void push (int x, struct stack* S);
/*****************************************/

214 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

107
10.06.2021

Example(2)
int main(void){
int x;
struct stack s;
makenull(&s);
push (7, &s);
push (5, &s);
push (3, &s);
push (1, &s);
print(s);
push (10, &s);
push (11, &s);
print(s);
x = top(s);
printf("Top of the stack is: %d\n", x);
x = pop(&s);
printf("Poped from stack: %d\n", x);
print(s);
return 0;
}
215 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(3)
void makenull(struct stack* S){
S->top = MAXLENGTH;
}
/*****************************************************/
int empty (struct stack S){
if(S.top == MAXLENGTH)
return 1;
else
return 0;
}
/*****************************************************/
int top (struct stack S){
if(empty(S)){
printf("Stack is empty\n");
return -1;
}
else
return S.elements[S.top];
}
/*****************************************************/
void push (int x, struct stack* S){
if (S->top == 0)
printf("Stack is full\n");
else {
S->top --;
S->elements[S->top] = x;
}
}
216 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

108
10.06.2021

Example(4)
void print(struct stack S){
int i;
printf("---STACK CONTENT---\n");
if(empty(S)){
printf("Stack is empty\n");
}
else{
for(i=S.top; i<MAXLENGTH; i++){
printf("%d ", S.elements[i]);
}
}
printf("\n----------------------\n");
}
/*****************************************************/
int pop (struct stack* S){
int x;
if(empty(*S)){
printf("Stack is empty\n");
return -1;
}
else{
x = S->elements[S->top];
S->top ++;
}
return x;
}
217 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Dynamic memory allocation


 Dynamic memory allocation is the process of
assigning the memory space during the execution
time or the run time.
 Heap:
 used for dynamic memory allocation,
 controlled by a programmer,
 limited in size,
 there's no enforced pattern to the allocation and
deallocation of blocks from the heap.
 Stack:
 used for static memory allocation,
 not directly controlled by a programmer,
 limited in size,
 always reserved in a LIFO (last in first out) order; the
most recently reserved block is always the next block
to be freed.

218 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

109
10.06.2021

Dynamic memory allocation


 Dynamic memory allocation requires <stdlib.h>
header

void *malloc(size_t size);


void *calloc(size_t num, size_t size);

 malloc() allocates a block of size bytes of memory


 calloc() allocates a block of memory for an array of num
elements, each of them size bytes long, and initializes all its
bits to zero)
 returns:
 on success: a pointer to the beginning of the block
 on failure: NULL pointer

219 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Dynamic memory allocation


Save the address of the allocated
block of memory in a pointer variable

Memory block size (in bytes)

p = (TYP*)malloc(SIZE);

if(!p){
printf("Memory allocation error");
exit(1);
}
The type of this pointer is always void*,
which can be cast to the desired type
Check if success
of data pointer in order to be
dereferenceable.

220 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

110
10.06.2021

Example
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *p;
long l;
l=0;
do{
p = (char*)malloc(1024);
if(p) l++;
}while(p);
printf("Approx. %ld kB of available memory.",l);
return 0;
}

221 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Dynamic memory allocation


double *wsk1;
wsk1 = (double*) malloc(30*sizeof(double));

char *wsk2;
int n = 100;
wsk2 = (char*) malloc(n*sizeof(char));

struct typ_s{
int i;
char c;
double d;
};

struct typ_s *wsk3;


wsk3 = (struct typ_s*) malloc(sizeof(struct typ_s ));
222 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

111
10.06.2021

Reallocate memory block


 Change the size of the memory block pointed to by ptr.
void *realloc(void *ptr, size_t size);

 May move the memory block to a new location.


 The content of the memory block is preserved up to the
lesser of the new and old sizes, even if the block is moved to
a new location.
 If the new size is larger, the value of the newly allocated
portion is indeterminate.
 In case that ptr is a null pointer, behaves like malloc()

223 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Deallocate memory block


 Deallocate a block of memory previously allocated by a call to
malloc(), calloc() or realloc(), making it available again for further
allocations.
void free(void *ptr);

 If ptr does not point to a block of memory allocated with the


above functions, it causes undefined behavior.
 If ptr is a null pointer, the function does nothing.
 This function does not change the value of ptr itself, hence it
still points to the same (now invalid) location.
 Call of free() should accompany each call of malloc() or calloc()

double *wsk1;
wsk1 = (double*) malloc(30*sizeof(double));
wsk1 = NULL; //ERROR – memory leak!
224 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

112
10.06.2021

Example a
#include <stdio.h>
#include <stdlib.h>
int main(){
int *tab;
int size;
int i;
printf("Input array size: ");
scanf("%d", &size);
tab = (int*)malloc(size * sizeof(int));
if(tab == NULL){
printf("Memory allocation error");
exit(0);
}
for(i=0; i<size; i++){
printf("tab[%d] = ", i);
scanf("%d", &tab[i]);
}
printf("\n");
for(i=0; i<size; i++)
printf("tab[%d] = %d\n", i, tab[i]);
free(tab);
return 0;
225 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming
}

Example b
#include <stdio.h>
#include <stdlib.h>
int main(){
int *tab;
int size;
int i;
printf("Input array size: ");
scanf("%d", &size);
tab = (int*)malloc(size * sizeof(int));
if(tab == NULL){
printf("Memory allocation error");
exit(0);
}
for(i=0; i<size; i++){
printf("tab[%d] = ", i);
scanf("%d", (tab+i));
}
printf("\n");
for(i=0; i<size; i++)
printf("tab[%d] = %d\n", i, *(tab+i));
free(tab);
return 0;
226 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming
}

113
10.06.2021

Example a
#include <stdio.h>
#include <stdlib.h>
1 iteration:
void alloc (int);
10 iterations
int main(void){
50 iterations
int i;
I00 iterations
for(i=0; i<1000; i++){
alloc(2000);
} 500 iterations

return 0; 1000 iterations


}
void alloc (int n){
double *wsk;
wsk = (double*) malloc(n*sizeof(double));
//memory leak!
//wskaźnik do bloku pamięci (zmienna automatyczna) jest niszczony po
//zakończeniu funkcji, ale pamięć pozostaje niezwolniona i brak do niej dostępu

}
227 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <stdlib.h>
1 iteration
void alloc (int);
10 iterations
int main(void){
50 iterations
int i;
for(i=0; i<1000; i++){ 100 iterations
alloc(2000);
} 500 iterations

return 0; 1000 iterations


}
void alloc (int n){
double *wsk;
wsk = (double*) malloc(n*sizeof(double));
free(wsk);
}
228 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

114
10.06.2021

2D dynamic arrays
 Dynamic allocation of 2D block
 Step 1: declaration of a pointer to an array of pointers
 Step 2: allocation of pointer array (pointers to individual rows)
 Step 3: allocation of rows (each pointer points 1D memory block)

Step 1 Step 2 Step 3

229 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

2D dynamic arrays
 Dynamic allocation of 2D block
 Step 1: declaration of a pointer to an array of pointers
 Step 2: allocation of pointer array (pointers to individual rows)
 Step 3: allocation of rows (each pointer points 1D memory block)

// Step 1:
TYPE ** tab = NULL;
int w;
// Step 2:
tab = (TYPE **)calloc(num_rows, sizeof(TYPE *));
// Step 3:
for (w=0; w<num_rows; w++)
*(tab+w) = (TYPE*) calloc(num_cols, sizeof(TYPE));

230 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

115
10.06.2021

2D dynamic arrays
 Free 2D block of dynamic memory:
 Step 1: free consecutive rows
 Step 2: free array of pointers to rows

// Step 1:
for (w=0; w<num_rows; w++)
free(*(tab+w) );
// Step 2:
free(tab);
tab = NULL;

231 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(1)
#include <stdio.h>
#include <stdlib.h>
/********************************************************/
float ** alloc(int, int);
void fill(float**, int, int);
void print(float**, int, int);
void _free(float ***, int);
/********************************************************/
int main(){
int r = 40; //num rows
int c = 60; //num cols
float ** tab = alloc(r, c);
fill(tab, r, c);
print(tab, r, c);
_free(&tab, r);
return 0;
}
232 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

116
10.06.2021

Function returns pointer to 2D block


Example(2) of dynamic memory
float ** alloc(int rows, int cols){
float ** tab = NULL;
int w;
tab = (float **)calloc(rows, sizeof(float *));
for (w=0; w<rows; w++)
*(tab+w) = (float*) calloc(cols, sizeof(float));
return tab;
}
/***************************************************************/
void print(float** tab, int rows, int cols){
int w, k;
pointer to 2D block of dynamic memory
for (w=0; w<rows; w++){ as function argument
for(k=0; k<cols; k++){
printf("%.2f ", *(*(tab+w)+k));
}
printf("\n");
}
return;
}
233 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointer to a pointer to 2D block of memory

Example(3)
void _free(float ***tab, int rows){
int w;
for (w=0; w<rows; w++){
free(*((*tab)+w));
}
free(*tab);
*tab = NULL;
return;
}
/***************************************************************/
void fill(float** tab, int rows, int cols){
int w, k;
for (w=0; w<rows; w++){
for(k=0; k<cols; k++){
*(*(tab+w)+k) = 1.0/(1+rand()%10);
}
}

234
return; dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming
}

117
10.06.2021

Dynamic structures
 The C language allows to allocate memory for any data
type.Thus, structures can be dynamically allocated.

struct type_s{
int i;
char c;
double d;
};

struct type_s *wsk;


wsk = (struct type_s*) malloc(sizeof(struct type_s));

 Above the mechanism is useful for functions that modify


structures.
235 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(1)
#include <stdio.h>
#include <stdlib.h>
/*******************************************************/
struct type_s{
int i;
char c;
double d;
};
/*******************************************************/
struct type_s* fill(int i, char c, double d);
void print (struct type_s s);
/*******************************************************/
int main(){

struct type_s* wsk = fill(10, 'a', 31.34);


print(*wsk);
free(wsk);

return 0;
}

236 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

118
10.06.2021

Example(2)
/*******************************************************/
struct type_s* fill(int i, char c, double d){
struct type_s *wsk;
wsk = (struct type_s*) malloc(sizeof(struct type_s));
wsk->i = i;
wsk->c = c;
wsk->d = d;
return wsk;
}
/*******************************************************/
void print (struct type_s s){
printf(" d=%i\n c=%c\n d=%.2lf\n", s.i, s.c, s.d);
return;
}
/*******************************************************/

237 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Dynamic data structures


 Dynamic data structures are data structures that grow and
shrink as you need them to by allocating and deallocating
memory from a place called the heap.
 They allow the programmer to exactly control memory
consumption.
 Dynamic data structures allocate blocks of memory from the
heap as required, and link those blocks together into some
kind of data structure using pointers.
 When the data structure no longer needs a block of memory,
it will return the block to the heap for reuse.
 This recycling makes very efficient use of memory.

238 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

119
10.06.2021

Singly-linked list
List element:

NULL
next next next next struct node{
struct node* next;
TYPE data;
DATA DATA DATA DATA };
List:
struct list{
begin struct node* head;
(head) };
Basic operations:
 Each item at a singly linked list contains Add element:
two components: data and a pointer to - at the beginning
- at the end
the next item of the same type. - inside
 Singly-linked list can be traversed Remove element:
forward (from the head, towards the end - from the beginning
- from the end
– following the direction of next pointers) - from the middle of the list
Traverse (forward)
239 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list
 Add an item to the front (push front)
Case 1: Empty list begin
NULL List is empty if: head == NULL
(head)
begin next
(head)
NULL

DATA element->next = NULL


head = element
Case 2: Not empty list

begin next next next


(head)
NULL

DATA DATA DATA


next

DATA element->next = head


head = element

240 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

120
10.06.2021

Pointer to the added item


(we assume the item was before
Singly-linked list allocated and filled with data)

 Add an item to the front:


Pointer to the list

void push_front(struct list* l, struct node* el)


{
if (l->head == NULL)
{ Empty list
el->next = NULL;
l->head = el;
}
else
{
el->next = l->head; Not empty list
l->head = el;
}
}

241 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list
 Traverse list (iterate over list items):
 implemented with a pointer, which is initially set to the beginning of the
list, and then "travels" with next pointers to individual elements, until a
NULL value is encountered
begin next next next next
(head) NULL

DATA DATA DATA DATA


End!

wsk = head wsk = wsk->next wsk = wsk->next wsk=wsk->next wsk=wsk->next

void moveForward(struct list* l){


struct node* wsk = l->head;
while(wsk){
wsk = wsk->next;

}
242 } dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

121
10.06.2021

Singly-linked list
 Add an item to the back (push back):
begin
Case 1: Empty list NULL List is empty if: head == NULL
(head)

begin next
(head)
NULL
element->next = NULL
DATA head = element

Case 2: Not empty list


wsk = wsk->next wsk = wsk->next
wsk = head

begin next next next


(head) NULL

DATA DATA DATA

next
element->next = NULL
DATA
wsk->next = element
243 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointer to the added item


Singly-linked list (we assume the item was before
allocated and filled with data)
 Add an item to the back:
Pointer to the list

void push_back(struct list *l, struct node* el)


{
if (l->head == NULL){
el->next = NULL; Empty list
l->head = el;
}
else
{
struct node *wsk = l->head;
while(wsk->next!=NULL)
Move to the end
wsk = wsk->next;
el->next = NULL;
wsk->next = el; Add element
}
}
244 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

122
10.06.2021

Singly-linked list
 Insert item at n-th position:

wsk = wsk->next
wsk = head (n-1 times)

begin next next next


(head)
NULL

DATA DATA DATA


next

DATA

element->next = wsk->next
wsk->next = element

245 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Pointer to the added item


(we assume the item was before
Singly-linked list allocated and filled with data)
 Insert item at n-th position:
Pointer to the list position
void insert(struct list *l, int n, struct node* el){
int i = 0;
int len = listLength(l); Check list length
if(n<=1)
push_front(l, el); Add elemement to the front
else if(n>len)
push_back(l, el); Add element to the back
else {
struct node *wsk = l->head;
for(i=1; i<n-1; i++)
wsk = wsk->next; Move to position n-1

el->next = wsk->next;
wsk->next = el; Add element
}
246 } dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

123
10.06.2021

Singly-linked list
 Delete item from the beginning of the list:

begin next next next next


(head) NULL

DATA DATA DATA DATA

temp = head
head = head->next;
+ free memory under temp

The need to "remember" the old head in the auxiliary temp


variable so as not to lose access to it.

List cannot be empty to remove the element from it.

247 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list
 Delete item from the beginning of the list:

struct node* pop_front(struct list *l){

if (l->head != NULL){
struct node* wsk = l->head;
l->head = l->head->next;
return wsk;
}
else{
printf("Empty list!\n");
return NULL;
}
}

248 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

124
10.06.2021

Singly-linked list
 Delete item from the end of the list:

wsk = wsk->next wsk = wsk->next


wsk = head

begin next next next next


(head) NULL

DATA DATA DATA DATA

temp = wsk->next
wsk->next = NULL
+ free memory under temp

249 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list
struct node* pop_back(struct list *l){
Delete an item from the n-th position:

struct node* temp;


if (l->head != NULL){ Check if not empty
if(l->head->next){ Check if longer than 1 item
struct node* wsk = l->head;
while((wsk->next)->next!=NULL) Move to the end
wsk = wsk->next;
}
temp = wsk->next;
wsk->next = NULL; Remove element
}
else{
temp = l->head; One-item list case
l->head = NULL;
}
}
else{
printf("Empty list!\n");
temp = NULL;
}

250 return temp; dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming
}

125
10.06.2021

Singly-linked list
 Delete an item from the n-th position:

wsk = wsk->next
wsk = head (n-1 times)

begin next next next next


(head)
NULL

DATA DATA DATA DATA

temp = wsk->next
wsk->next = wsk->next->next
+ free memory under temp

251 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list position


struct node* del(struct list *l, int n){
Delete an item from the n-th position:

int i = 0;
int len = listLength(l); Check list length
struct node* temp;

if(n<=1)
Remove an item from the beginning
temp = pop_front(l);
else if(n>len)
temp = pop_back(l); Remove an item from the end
else {
struct node *wsk = l->head;

for(i=1; i<n-1; i++)


wsk = wsk->next; Move to the n-th position

temp = wsk->next;
wsk->next = wsk->next->next; Delete element
}
return temp;
}

252 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

126
10.06.2021

Example(1)
#include <stdio.h>
#include <stdlib.h>
/*************************************************************************/
struct node{
struct node *next;
int data;
};
/*************************************************************************/
struct list{
struct node* head;
};
/*************************************************************************/
void init(struct list *l);
void print(struct list *l);
struct node* createElement(int data);
struct node* pop_back(struct list *l); /* defined earlier */
struct node* pop_front(struct list *l); /* defined earlier */
struct node* del(struct list *l, int n); /* defined earlier */
void push_back(struct list *l, struct node* el); /* defined earlier */
void push_front(struct list *l, struct node* el); /* defined earlier */
void insert(struct list *l, int n, struct node* el); /* defined earlier */
int listLength(struct list *l);
void clear(struct list *l);

253 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(2)
int main(){
struct list l;
init (&l);
struct node* el1 = createElement(11);
struct node* el2 = createElement(12);
struct node* el3 = createElement(13);
struct node* el4 = createElement(0);
struct node* el5 = createElement(100);
push_front(&l, el1); push_front(&l, el2); push_front(&l, el3); print(&l);
insert(&l, 2, el4); print(&l); printf("Length: %d\n", listLength(&l));
push_back(&l, el5); print(&l);
printf("Removed: %d\n", (del(&l,3))->data); print(&l); //memory leak
printf("Removed: %d\n", (pop_back(&l))->data); print(&l); //memory leak
printf("Removed: %d\n", (pop_front(&l))->data); print(&l); //memory leak
printf("\nLength : %d\n", listLength(&l));
clear(&l);
printf("\nLength : %d\n", listLength(&l));
return 0;
}
254 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

127
10.06.2021

Example(3)
void init(struct list *l){
l->head = NULL;
}
/**************************************************************/
struct node* createElement(int data){
struct node* el = (struct node*) malloc (sizeof(struct node));
el->data = data;
el->next = NULL;
return el;
}
/**************************************************************/
void print(struct list *l){
struct node* wsk = l->head;
while(wsk){
printf("%d\t", wsk->data);
wsk = wsk -> next;
}
printf("\n");
}

255 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(4)
int listLength(struct list *l){
int i = 0;
struct node* wsk = l->head;
while(wsk){
i++;
wsk = wsk->next;
}
return i;
}
/*************************************************************************/
void clear(struct list *l){
struct node *wsk = l->head;
struct node *temp;
while(wsk){
temp = wsk;
wsk = wsk->next;
free(temp);
}
l->head = NULL;
}

256 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

128
10.06.2021

Singly-linked list
 Reverse items order
 If list is not empty:
 remember the address of the first element
 as long as there is a successor of the memorized element:
 „unclip” successor from the list
 move the successor to the beginning

257 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(1)
void reverse(struct list *l){
struct node* wsk; /*continuation of the
struct node* temp; list implementation*/
if(l->head){
wsk = l->head; Remember first element

while(wsk->next){ Until the successor exists


temp = wsk->next; Remember the successor
wsk->next = temp->next; „Unclip” successor

temp->next = l->head; Move remembered item to the


beginning
l->head = temp;
}
}
}
258 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

129
10.06.2021

Example(2)
int main(){
struct list l;
init (&l);
struct node* el1 = createElement(11);
struct node* el2 = createElement(12);
struct node* el3 = createElement(13);
struct node* el4 = createElement(0);
struct node* el5 = createElement(100);
push_front(&l, el1);
push_front(&l, el2);
push_front(&l, el3);
push_front(&l, el4);
push_front(&l, el5);
print(&l);
reverse(&l);
print(&l);
clear(&l);
return 0;
} 259 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list
 List search:
 starting from the list head, go through all the items until you
find the item you are looking for or the end of the list
 return the address of the found item, or NULL if the item is
not found

260 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

130
10.06.2021

struct node* find(struct list* l, int d){


struct node* wsk = l->head;

Example while(wsk){
if(wsk->data == d){
return wsk;
}
wsk = wsk->next;
}
return NULL;
int main(){
}
struct list l; init (&l);
push_front(&l, createElement(11));
push_front(&l, createElement(12));
push_front(&l, createElement(13));
push_front(&l, createElement(0));
push_front(&l, createElement(100));
struct node* wsk = find(&l, 0);
if(wsk!=NULL)
printf("Item found%d\n", wsk->data);
else
printf("Item not found\n");

clear(&l);
return 0; /*continuation of the
} list implementation*/

261 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Singly-linked list
 List division into two lists
 by selecting (copying) successive items from the beginning of a
split list and adding them one by one, then into another target
list

262 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

131
10.06.2021

/*continuation of the
list implementation*/
Example(1)

Original list Resulting


const because it will not be modified lists
void split(const struct list *l, struct list *l1, struct list *l2){
struct node* wsk = l->head;
int s = 1;
while(wsk){
if(s%2) push_back(l1,createElement(wsk->data));
else push_back(l2,createElement(wsk->data));
wsk = wsk->next;
s++;
}
}

263 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(2)
int main(){
srand(time(NULL));
int i;
struct list l;
init (&l);
for(i=0; i<10; i++)
push_front(&l, createElement(rand()%10));
print(&l);
struct list l1, l2;
init (&l1);
init (&l2);
split(&l, &l1, &l2);
print(&l1);
print(&l2);
getchar();
clear(&l);
clear(&l1);
clear(&l2);

return 0;
} 264 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

132
10.06.2021

List item:
struct node{
Doubly-linked list struct node* next;
struct node* prev;

NULL
next next next next TYP data;
NULL

};
prev prev prev prev
List:
struct list{
DATA DATA DATA DATA
struct node* head;
struct node* tail;
};
begin
(head) Basic operations:
end (tail)

 Each item of a doubly-linked list contains three Add element:


- at the beginning
components: data and pointers to the - at the end
previous and next item of the same type. - inside

 A doubly-linked list can be traversed "forward" Remove element:


- from the beginning
starting from the beginning (head), following - from the end
the next pointers, and "backward" starting - from the middle of the list
Traverse (forward)
from the tail, following the prev pointers. Traverse (backward)
265 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Doubly-linked list
NULL

next next next next


NULL

prev prev prev prev

DATA DATA DATA DATA

begin
(head)
end (tail)

 If list is empty: head == tail == NULL


 For the first list item head->prev == NULL
 For the last list item: tail->next == NULL
 For the one-item list: head == tail != NULL

266 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

133
10.06.2021

Doubly-linked list
 Add item to beginning of a list:
 Case 1 – empty list next NULL

element->next = NULL; NULL prev


element->prev = NULL; DATA

list->head = element;
list->tail = element; head tail

 Case 2 – not empty list


element->next = head;
element->prev = NULL;
list->head->prev = element;

NULL
list->head = element; next next next
NULL prev prev prev
DATA DATA DATA

head tail

267 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Doubly-linked list
 Add item to the end of a list:
 Case 1 – empty list next NULL

element->next = NULL; NULL prev


element->prev = NULL; DATA

list->head = element;
list->tail = element; head tail

 Case 2 – not empty list


element->next = NULL;
element->prev = list->tail;
list->tail->next = element;
NULL

list->tail = element; next next next


NULL prev prev prev
DATA DATA DATA

head tail
268 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

134
10.06.2021

Doubly-linked list
 Insert item to list:
 wsk – pointer to item after which a new item is inserted
element->next = wsk->next;
element->prev = wsk;
wsk->next = element;
wsk->next->prev = element;

wsk = wsk->next
wsk = head (n-1 times)

head next next next NULL

NULL prev prev prev


next tail
DATA DATA DATA
prev

DATA

Doubly-linked list
 Delete item from the beginning of a list:
 Case 1 – one item list
list->tail=NULL;
free(list->head);
list->head=NULL;

 Case 2 – more than one item list


temp=list->head->next;
list->head->next->prev=NULL;
free(list->head);
NULL

list->head=temp; next next next


NULL prev prev prev
NULL

DATA DATA DATA

head tail
270 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

135
10.06.2021

Doubly-linked list
 Delete item from the beginning of a list:
 Case 1 – one item list
list->tail=NULL;
free(list->head);
list->head=NULL;

 Case 2 – more than one item list


temp=list->tail->prev; temp
temp->next=NULL;

NULL
free(list->tail);

NULL
list->tail=temp; next next next
NULL prev prev prev
DATA DATA DATA

head tail

271 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Doubly-linked list
 Delete item from the middle of a list:
 wsk – pointer to the item to be deleted
wsk->prev->next = wsk->next;
wsk->next->prev = wsk->prev;

wsk

head next next next next NULL


NULL prev prev prev prev
tail
DATA DATA DATA DATA

272 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

136
10.06.2021

Doubly-linked list
 Traversing the list
 from head to tail (forward)
wsk = list->head;
while(wsk){
//do sth
wsk = wsk->next;
}

 from tail to head (backward)


wsk = list->tail;
while(wsk){
//do sth
wsk = wsk->prev;
}

273 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

List variants
 Stack
 LIFO (ang. last-in-first-out)
 Queue
 FIFO (ang. first-in-first-out)

274 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

137
10.06.2021

Recursion
 Recursion occurs when a thing is defined
in terms of itself or of its type.
 In computer science, recursion is a method of solving a
problem where the solution depends on solutions to
smaller instances of the same problem.
 Recursion solves such recursive problems by using
functions that call themselves from within their
own code.

275 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <stdio.h>
#include <time.h>
long long factorial_it (int n);
long long factorial_rec (int n); Example
int main(void){
int i;
time_t start, stop;
start = clock();
for (i=0; i<1000000; i++) factorial_it(120);
stop = clock();
printf("Factorial iteratively: %ld clocks\n", stop - start);
start = clock();
for (i=0; i<1000000; i++) factorial_rec(120);
stop = clock();
printf("Factorial recursively: %ld clocks\n", stop - start);
return 0;
}
long long factorial_rec(int n){
long long factorial_it(int n){
long long res;
long long res;
if(n>0)
for(res = 1; n>1; n--) res = n* factorial_rec(n-1);
res*=n; else
res = 1;
return res;
} return res;
}

276 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

138
10.06.2021

Example
#include <stdio.h>
/***********************************************/
void up_and_down(int);
/***********************************************/
int main(void){
up_and_down(1);
return 0;
}
/***********************************************/
void up_and_down(int n){
printf("Level: %d: variable n's address: %p\n\n", n, &n);
if(n<4)
up_and_down(n+1);
printf("Level: %d: variable n's address: %p\n\n", n, &n);
}

277 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Recursion
 each nested call of the recursive function has its variables
 there is one return for each function call
 call statements in a recursive function before the point
where the function calls itself are executed in the order
in which the calls are executed
 instructions in a recursive function after the point where
it calls itself are executed in the reverse order
 the function code for subsequent calls is not multiplied
 recursive function should have a stopping condition
(ends the sequence of recursive calls)

278 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

139
10.06.2021

Example a
#include <stdio.h>
/************************************/
void recursion(int);
/************************************/
int main(void){

recursion (0);
getchar();
return 0;
}
/************************************/
void recursion(int i){

if(i<10){
printf("%d ", i);
recursion(i+1);
}
}

279 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example b
#include <stdio.h>
/************************************/
void recursion(int);
/************************************/
int main(void){

recursion(0);
getchar();
return 0;
}
/************************************/
void recursion(int i){

if(i<10){
recursion(i+1);
printf("%d ", i);
}
}

280 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

140
10.06.2021

Example
#include <stdio.h>
/************************************************************************************/
void to_binary(int);
/************************************************************************************/
int main(void){
int num;
printf("Input integer number (q to finish): \n");
while(scanf("%d", &num) == 1) {
printf("Binary representation: ");
to_binary(num);
printf("\n\n");
printf("Input integer number (q to finish): \n");
}
return 0;
}
/************************************************************************************/
void to_binary(int n){
int r;
r = n%2;
if(n>=2)
Recursively find the binary
to_binary(n/2); representation of a decimal number
putchar('0'+r);
return;
}
281 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
void rcopy(char *s1, char *s2);
int main(void){
char nap[80];
rcopy(nap, "This is a test string");
printf(nap);
getchar();
return 0; Recursively copy strings
}
void rcopy(char *s1, char *s2){
if(*s2){ /*if not the end of s2*/
*s1++ = *s2++;
rcopy(s1,s2);
}
else
*s1 = '\0'; /*null terminator*/
}

282 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

141
10.06.2021

Fibonacci sequence
int FibRek(int n){
if (n < 2) return n;
else return FibRek(n-1)+FibRek(n-2); int main(){
} int i;
for(i=0; i<10; i++)
RECURSIVELY
printf("%d) rek: %d,
it: %d\n", i,
int FibIt(int n){ FibRek(i),FibIt(i));
int a = 0, b = 0, i, result = 0;
return 0;
if (n<2) return n;
else{ }
for(i=2; i<=n; i++){
result = a + b;
a = b;
b = result;
}
return result;
}
} ITERATIVELY

283 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Horner’s scheme
 Horner’s scheme – an algorithm for polynomial evaluation.
After the introduction of computers, this algorithm became
fundamental for computing efficiently with polynomials.

𝑛(𝑛 + 1)/2 - multiplications 𝑛 - additions

𝑛- multiplications 𝑛 - additions

𝒂𝒏 𝒇𝒐𝒓 𝒏 = 𝟎
𝑾𝒏 𝒙 =
𝑾𝒏 𝟏 𝒙 ∗ 𝒙 + 𝒂𝒏 𝒇𝒐𝒓 𝒏 > 𝟎
284 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

142
10.06.2021

Horner’s scheme
int HornerRek(int coef[],int n, int x) {
if (n == 0)
return coef[0];

return x * HornerRek(coef, n - 1, x) + coef[n];


}
RECURSIVELY

int HornerIt(int coef[],int n, int x){


int i, result = coef[0];

for(i=1;i<=n;i++)
result = result*x + coef[i];

return result;
} ITERATIVELY

285 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Horner’s scheme
int main(){
int *coef, n, arg, i;
printf("Enter the degree of the polynomial: ");
scanf("%d", &n);
coef = (int*)malloc((n+1)*sizeof(int)); Allocate memory
//Read coefficients
for(i=0; i<=n; i++) {
printf("Enter coefficient at %d-nt degree :", n-i);
scanf("%d", &coef[i]);
}
printf("Input x: ");
scanf("%d", &arg);
printf("rek: W(%d) = %d\n", arg, HornerRek(coef,n,arg));
printf("it: W(%d) = %d\n", arg, HornerIt(coef,n,arg));
free (coef); Free memory
return 0;
}
286 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

143
10.06.2021

Determinant of a square matrix


𝑎 𝑓𝑜𝑟 𝑛 = 1
det 𝐴[ × ] =
𝑎 −1 det(𝐴 ) 𝑓𝑜𝑟 𝑛 > 1

where:
i – row selected for expansion
Aik – submatrix of A (after removal of i-th row and j-th comumn)

287 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

double det(int n, int w, int * WK, double ** A){


int i, j, k, m, *KK;
double s; Example(1)
if(n == 1) // 1 element case
return A[w][WK[0]];
else {
KK = (int*) malloc ((n-1) * sizeof (int)); // vector of columns
s = 0; m = 1;
for(i = 0; i < n; i++) { // loop expanding sub-matrices
k = 0; // vector of columns for recursion
for(j = 0; j < n - 1; j++) {
if(k == i) k++; // skip recent column
KK[j] = WK[k++]; // copy remaining columns to KK
}
s += m * A[w][WK[i]] * det(n - 1,w + 1, KK, A);
m = -m; // next multiplier
}
free (KK);
return s;
}
}
288 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

144
10.06.2021

int main(){
int n, i, j, *WK; Example(2)
double ** A;
printf("Input matrix size: ");
scanf("%d", &n); Dynamic matrix allocation
A = (double**) malloc (n * sizeof(double*));
for(i = 0; i < n; i++){
A[i] = (double*) malloc(n * sizeof(double));
for(j = 0; j < n; j++) scanf("%lf", &A[i][j]);
}
WK = (int*) malloc (n*sizeof(int));
for(i = 0; i < n; i++)
WK[i] = i;
printf("Determinant equals": %lf", det(n, 0, WK, A));
Free memory
free(WK);
for(i = 0; i < n; i++) free(A[i]);
free(A);
}

289 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

The result of merging two sorted sets:


{1 3 6 7 9} and { 2 3 4 6 8 }
Merge Sort is set: {1 2 3 3 4 6 6 7 8 9}.

 Algorithm of merging two sorted sets: Divide and Conquer algorithm.


 compare the first elements of each of the
merged sets;
 insert the smaller element into the new set,
removing it from the source set at the same
time;
 repeat steps 1 and 2 until both the merged
sets are empty.
 Merge sort:
 if the set contains more than one element,
divide it into two equal subsets (or almost
equal if the sorted set has an odd number of
elements);
 sort the first subset using the same
recursion

algorithm;
 sort the second subset using the same
algorithm;
 merge two ordered subsets into one
ordered set.
290 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

145
10.06.2021

Example(1)
#include <stdio.h>
#define N 20
/*********************************************************************/
void merge(int, int, int, int[]);
void mergesort(int, int, int[]);
/*********************************************************************/
int main(){

int i;
int tab[N] = {29,28,27,25,1,2,3,5,6,24,22,20,18,8,10,11,17,15,13,12};

printf("Unsorted set:\n");
for (i=0; i<N; i++)
printf("%d ", tab[i]);

mergesort(0,N-1, tab); Call of the sorting function


printf("\nSorted set:\n");
for (i=0; i<N; i++)
printf("%d ", tab[i]);

return 0;
}
291 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(2)
void merge(int start, int mid, int stop, int tab[N]){

int i, j, q;
int t[N];

for (i=start; i<=stop; i++)


Copy data to temporary buffer
t[i]=tab[i];

i=start; j= mid+1; q=start;

while (i<=mid && j<=stop) {


if (t[i]<t[j]) Move data with sorting from
tab[q++]=t[i++]; temporary buffer to the main array
else
tab[q++]=t[j++];
}

while (i<=mid) Moving non-copied data from the first array


tab[q++]=t[i++]; in case the second array has finished
}

292 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

146
10.06.2021

Example(3)
void mergesort(int start, int stop, int tab[N]){
int mid;
if (start<stop){
mid=(start+stop)/2;
mergesort(start, mid, tab); sort left sub-array
mergesort(mid+1, stop, tab); sort right sub-array
merge(start, mid, stop, tab); merge sub-arrays
}
}

293 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Binary tree
 Binary tree is a dynamic data structure composed of nodes
 each node (parent) has at most two children, which are referred to as the
left child and the right child
 orphan node (i.e., node with no parent) is a root node
 node having no children is a leaf
 a binary tree can have many leafs, but only

struct node
Tree node

{ node * parent;
node * left;
node * right;

};

294 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

147
10.06.2021

Representation of a binary tree


 Binary trees can be represented by adjacency lists:
 L[i] = {parent, left child, right} w r l p
1 0 2 3
2 1 4 5
3 1 6 7
4 2 8 9
5 2 0 0
6 3 0 10
7 3 11 12
8 4 0 0
9 4 0 0
10 6 0 0
w – node r – parent 11 7 0 0
l – left child p – right child
12 7 0 0
295 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Tree traversal
 Tree traversal refers to the process of visiting (checking
and/or updating) each node in a tree data structure, exactly
once.
 pre-order
 root-> left subtree -> right subtree
 in-order
 left subtree -> root -> right subtree
 post-order
 left subtree -> right subtree -> root
 Bridth First Search
 where every node on a level is visited before going to a lower level
(level-order).

296 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

148
10.06.2021

Tree traversal
Pre-order: In-order: Post-order:

FBADCEGIH ABCDEFGHI ACEDBHIGF


preorder(v) inorder(v) postorder(v)
• process node v • if (L[v].left > 0) • if (L[v].left > 0)
• if(L[v].left > 0) inorder(L[v].left) postorder(L[v].left)
preorder(L[v].left) • process node v • if(L[v].right > 0)
• if(L[v].right > 0) • if(L[v].right > 0) postorder(L[v].right)
preorder(L[v].right) inorder(L[v].right) • process node v
• end • end • end
297 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(1)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/***********************************************************************/
struct list_elem{
int parent;
int left;
int right;
};
/***********************************************************************/
void preorder(int v, struct list_elem L[], int nr_preorder[], int *nr)
{
nr_preorder[v] = (*nr)++;
if(L[v].left) preorder(L[v].left, L, nr_preorder, nr);
if(L[v].right) preorder(L[v].right, L, nr_preorder, nr);
}
/***********************************************************************/
void inorder(int v, struct list_elem L[], int nr_inorder[], int *nr)
{
if(L[v].left) inorder(L[v].left, L, nr_inorder, nr);
nr_inorder[v] = (*nr)++;
if(L[v].right) inorder(L[v].right, L, nr_inorder, nr);
}
/***********************************************************************/
void postorder(int v, struct list_elem L[] , int nr_postorder[], int *nr)
{
if(L[v].left) postorder(L[v].left, L, nr_postorder, nr);
if(L[v].right) postorder(L[v].right, L, nr_postorder, nr);
nr_postorder[v] = (*nr)++;
}
298 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

149
10.06.2021

Example(2)
/*************************************************************************/
struct list_elem* createAdjacencyList(int n, int m)
{
int i, c,l,r;
struct list_elem* L =
(struct list_elem*)malloc((n+1)*sizeof(struct list_elem));
for (i=1; i<=n; i++) {
L[i].parent = 0;
L[i].left = 0;
L[i].right = 0;
}
for(i = 1; i <= m; i++) {
printf("Input id of node, and its right and left child: ");
scanf("%d %d %d", &c, &l, &r);
L[c].left = l; L[c].right = r;
if(l) L[l].parent = c;
if(r) L[r].parent = c;
}
return L;
}
/*************************************************************************/

299 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(3)
/****************************************************************************/
void printAdjacencyList(struct list_elem L[], int n)
{
int i;
printf("---------------------------------\n");
for(i = 1; i <= n; i++)
printf("%d:|\t%d\t%d\t%d\n", i, L[i].parent, L[i].left, L[i].right);
printf("---------------------------------\n");
}
/****************************************************************************/
void printNodes(int preorder[], int inorder[], int postorder[], int n)
{
int i;
printf("---------------------------------\n");
printf("w\t pre\t in\t post\n");
printf("---------------------------------\n");
for(i = 1; i <= n; i++)
printf("%d\t | %d\t | %d\t | %d \t|\n",
i, preorder[i], inorder[i], postorder[i]);
printf("---------------------------------\n");
}
/****************************************************************************/

300 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

150
10.06.2021

Example(4)
int main(void) {
int n, m, i, nr;
printf("Input the number of nodes: ");
scanf("%d", &n);
printf("Input the number of nodes with a child: ");
scanf("%d", &m);
int* nr_preorder = (int*)malloc((n+1)*sizeof(int));
int* nr_inorder = (int*)malloc((n+1)*sizeof(int));
int* nr_postorder = (int*)malloc((n+1)*sizeof(int));
struct list_elem* L = createAdjacencyList(n, m);
printAdjacencyList(L, n);
nr = 1; preorder(1, L, nr_preorder, &nr);
nr = 1; inorder(1, L, nr_inorder, &nr);
nr = 1; postorder(1, L, nr_postorder, &nr);
printNodes(nr_preorder, nr_inorder, nr_postorder, n);
free(nr_preorder);
free(nr_inorder);
free(nr_postorder);
free(L);
return 0;
} 301 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example(5)

Adjacency list Order of nodes


302 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

151
10.06.2021

Mutual recursion
 In computer science, mutual recursion is a form of
recursion where two computational objects, such as
functions or datatypes, are defined in terms of each other.
 Two functions are called mutually recursive if the first
function makes a recursive call to the second function
and the second function, in turn, calls the first one.

303 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
/********************************************/
void f1(int);
void f2(int);
/********************************************/
int main(void){
f1(30);
getchar();
return 0;
}
/********************************************/
void f1(int a){
if(a) f2(a-1);
printf("%d ", a);
}
/********************************************/
void f2(int b){
if(b) f1(b-1);
printf(".");
}

304 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

152
10.06.2021

Hofstader Sequence
 In mathematics, a Hofstadter sequence is a member of a
family of related integer sequences defined by non-linear
recurrence relations. In this example we are going to
focus on Hofstadter Female and Male sequences:

305 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
int hofstaderFemale(int);
int hofstaderMale(int);
int hofstaderFemale(int n)
{
return (n == 0) ? 1 : n - hofstaderFemale(n - 1);
}
int hofstaderMale(int n)
{
return (n == 0) ? 0 : n - hofstaderMale(n - 1);
}
int main()
{
int i;
printf("F: ");
for (i = 0; i < 25; i++)
printf("%d ", hofstaderFemale(i));
printf("\n");
printf("M: ");
for (i = 0; i < 25; i++)
printf("%d ", hofstaderMale(i));
return 0;
}

306 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

153
10.06.2021

Selected library functions


 Header files of standard C library:
• <assert.h> diagnostics
• <float.h> floating-point characteristics
• <math.h> math library
• <stdarg.h> variable arguments
• <stdlib.h> general utilities
• <ctype.h> character handling
• <setjmp.h> non-local jumps
• <stddef.h> common definitions
• <string.h> string and memory blocks handling
• <errno.h> error reporting
• <locale.h> localization
• <signal.h> sygnal handling
• <stdio.h> standard I/O library
• <time.h> date and time

307 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

<assert.h>
diagnostics
 This header <assert.h> file defines assert()as a macro.

void assert(int expression)

 The expression used as an argument is typically a relational or


logical expression that should be true at that point in the program
if the program is functioning properly.
 If expression evaluates to nonzero, the macro does nothing.
 If it evaluates to zero, assert() displays:
Assertion failed: expression, file filename, line number

 Then it calls abort() .

308
dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

154
10.06.2021

Example
#include <stdio.h>
#include <assert.h>

int test_assert (int x)


{
assert(x <= 4);
return x;
}
int main (void)
{
int i;
for (i=0; i<=9; i++){
test_assert( i );
printf("i = %i\n", i);
}
return 0;
}
309 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <math.h>
#include <assert.h>
int main(){
double x, y, z;
puts("Input two numbers (0 0 ends program): ");
while(scanf("%lf %lf", &x, &y) == 2 && ( x!=0 || y!=0 ))
{
z = x * x - y * y;
assert( z >= 0);
printf("The result is %f\n", sqrt(z));
puts("Input the next two numbers: ");
}
return 0;
}

310 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

155
10.06.2021

<ctype.h>
character handling
int isalnum(int c); Returns true if c is alphanumeric (alphabetic or numeric).
int isalpha(int c); Returns true if c is alphabetic.
int isblank(int c); Returns true if c is a space or a horizontal tab. (C99)
int iscntrl(int c); Returns true if c is a control character, such as Ctrl+B.
int isdigit(int c); Returns true if c is a digit.
int isgraph(int c); Returns true if c is any printing character other than a space.
int islower(int c); Returns true if c is a lowercase character.
int isprint(int c); Returns true if c is a printing character.
int ispunct(int c); Returns true if c is a punctuation character (any printing character
other than a space or an alphanumeric character).
int isspace(int c); Returns true if c is a whitespace character: space, newline, form feed,
carriage return, vertical tab, horizontal tab.
int isupper(int c); Returns true if c is an uppercase character.
int isxdigit(int c); Returns true if c is a hexadecimal-digit character.
int tolower(int c); If the argument is an uppercase character, returns the lowercase
version; otherwise, just returns the original argument.
int toupper(int c); If the argument is a lowercase character, returns the uppercase
version; otherwise, just returns the original argument.
311 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <ctype.h>
int main(){
char ch;
for(;;){
ch = getchar();
if(ch == EOF) break;
if(isalnum(ch)) printf("%c is alphanumeric\n", ch);
if(isalpha(ch)) printf("%c is alphabetic\n", ch);
if(iscntrl(ch)) printf("%c is a control character\n", ch);
if(isdigit(ch)) printf("%c is a digit\n", ch);
if(isgraph(ch)) printf("%c is a printing character other than a space\n", ch);
if(islower(ch)) printf("%c is a lowercase character\n", ch);
if(isupper(ch)) printf("%c is an uppercase character\n", ch);
if(isprint(ch)) printf("%c is a printing character\n", ch);
if(ispunct(ch)) printf("%c is a punctuation character\n", ch);
if(isspace(ch)) printf("%c is a whitespace character\n", ch);
if(isxdigit(ch)) printf("%c is a hexadecimal-digit character\n", ch);
printf("-----------------------\n");
while(getchar()!='\n');
}
return 0;
}
312 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

156
10.06.2021

<string.h>
string and memory blocks handling
 void *memchr(const void *s, int c, size_t n);
 searches for the first occurrence of c in the initial n characters of the object pointed to by s ;
returns a pointer to the first occurrence, NULL if none is found.
 void *memrchr(const void *s, int c, size_t n);
 searches for the first occurrence of c in the last n characters of the object pointed to by s ;
returns a pointer to the first occurrence, NULL if none is found.
 int memcmp (const void *s1, const void *s2, size_t n);
 compares the first n characters of the object pointed to by s1 to the first n characters of the
object pointed to by s2, interpreting each value as unsigned char.
 void *memcpy (void* s1, const void* s2 size_t n);
 Copies n bytes from the location pointed to by s2 to the location pointed to by s1;
 void *memmove (void* s1, const void* s2, size_t size);
 Copies n bytes from the location pointed to by s2 to the location pointed to by s1; behaves as
if copying;
 void * memset ( void * s, int v, size_t n);
 Copies the value v (converted to type unsigned char ) to the first n bytes pointed to by s ;
313 returns s . dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <stdio.h>
#include <string.h>
#define SIZE 10
void show_array(const int tab[], int n);
Example(1)
int main() {
int src[SIZE] = {1,2,3,4,5,6,7,8,9,10};
int dest[SIZE];
double sth[SIZE/2] = {1.0, 2.0, 3.0, 4.0, 5.0};
puts("Using memcpy(): ");
puts("source (original): ");
show_array(src, SIZE);
memcpy(dest, src, SIZE*(sizeof(int)));
puts("destination (copying source: ");
show_array(dest, SIZE);
puts("\nUsing memmove() with overlapping regions: ");
memmove(src+2, src, 5*sizeof(int));
puts("source -- elements 0-5 copied to 2-7: ");
show_array(src, SIZE);
puts("\nUsing memcpy() for copying double buffer to int buffer: ");
memcpy(dest, sth, (SIZE/2) * sizeof(double));
puts("destination -- 5 double 10 int: ");
show_array(dest, SIZE);
return 0;
}
314 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

157
10.06.2021

Example(2)
void show_array(const int tab[], int n)
{
int i;

for(i=0; i<n; i++)


printf("%d ", tab[i]);

putchar('\n');
}

315 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <stdio.h>
#include <string.h>

Example
#define SIZE 5
struct complex_t{
float im, re;
};
void show_array(const struct complex_t[], int n);
int main() {
struct complex_t source[SIZE] = {{1,1},{2,2},{3,3},{4,4},{5,5}};
struct complex_t destination[SIZE] ={{0,0}};
puts("source (original data): ");
show_array(source, SIZE);
puts("destination (original data): ");
show_array(destination, SIZE);
memcpy(destination, source, SIZE*(sizeof(struct complex_t)));
puts("destination (source copied): ");
show_array(destination, SIZE);
return 0;
}
void show_array(const struct complex_t tab[], int n){
for(int i=0; i<n; i++)
printf("%.2f + j%.2f\n", (tab+i)->im, (tab+i)->re);
printf("\n");
}
316
dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

158
10.06.2021

Example
#include <string.h>
#include <stdio.h>
#define BUF_SIZE 20
int main(void)
{
char buffer[BUF_SIZE + 1];
char *string;
memset(buffer, 0, sizeof(buffer));
string = (char *) memset(buffer,'A', 10);
printf("\nBuffer contents: %s\n", string);
memset(buffer+10, 'B', 10);
printf("\nBuffer contents: %s\n", buffer);
memset(buffer, '*', 5);
printf("\nBuffer contents: %s\n", buffer);
return 0;
}

317 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

<string.h>
string and memory blocks handling
 char* strcat(char* s1, char* s2)
 Appends a copy of the string pointed to by s2 (including the null
character) to the location pointed to by s1; the first character of
the s2 string overwrites the null character of the s1 string; returns
s1.
 int strcmp(const char* s1, const char* s2)
 Compares the strings pointed to by s1 and s2 ; two strings are
identical if all pairs match; otherwise, the strings compare as the
first unmatching pair
 char* strcpy(char* s1, char* s2)
 Copies the string pointed to by s2 (including the null character)
to the location pointed to by s1; returns s1.
size_t strlen(const char* s)
 Returns the number of characters (excluding the terminating null
character) in the string s .
318 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

159
10.06.2021

<string.h>
string and memory blocks handling
char* strchr(const char* s, char c)
 Searches for the first occurrence of c (converted to char )
in the string pointed to by s ; the null character is part of
the string; returns a pointer to the first occurrence, or
NULL if none is found.
char* strstr(const char* s1, const char* s2)
 Returns a pointer to the location of the first occurrence
in s1 of the sequence of characters in s2 (excluding the
terminating null character); returns NULL if no match is
found.
char* strtok(char *s1, const char* s2)
 Decomposes the string s1 into separate tokens; the string
s2 contains the characters that are recognized as token
separators.The function is called sequentially.
319 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <string.h>

int main() {

char str1[50] = {"Hello"};


char str2[50] = {" World!"};

puts(str1);
puts(str2);

strcat(str1, str2);
puts(str1);

char *x = strstr(str1,"ll");
puts(x);

x = strchr(str1, 'W');
puts(x);

return 0;
}

320 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

160
10.06.2021

<math.h>
mathematical functions

321 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

<time.h>
date and time
 clock_t clock (void) struct tm {
Returns approximation of the processor int tm_sec; /*Seconds after the minute*/
time elapsed since the program was invoked int tm_min; /*Minutes after the hour*/
int tm_hour;/*Hours after midnight*/
 char* ctime (const time_t * tp) int tm_mday;/*Day of the month*/
Converts the calendar time pointed to by tp int tm_mon; /*Months since January*/
int tm_year; /*Years since*/
into a string int tm_wday; /*Days since Sunday*/
 double difftime(time_t t1, time_t t2) int tm_yday; /*Days since January 1*/
Calculates the difference between two int tm_isdst;/*Daylight Savings Time*/
calendar times };

 struct tm*localtime(const time_t *tp)


Converts the calendar time pointed to by tp into a broken-down time, expressed as local
time. Stores a tm structure and returns a pointer to that structure.
 time_t time(time_t *tp) returns the current calendar time and also places it in the
 location pointed to by tp , provided tp is not NULL . Returns (time_t)(-1) if the calendar
time is not available.

322 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

161
10.06.2021

Example
#include <stdio.h>
#include <time.h>

int main(){

struct tm *wsk;
time_t time_loc;

time_loc = time(NULL);
printf(ctime(&time_loc));

wsk = localtime(&time_loc);
printf(asctime(wsk));

getchar();
return 0;
}

323 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <time.h>
int main(){
struct tm *local, *universal;
time_t t;
t = time(NULL);
local = localtime(&t);
printf("Local date and time:\n %s\n", asctime(local));
printf("tm_sec: %d\n", local->tm_sec);
printf("tm_min: %d\n", local->tm_min);
printf("tm_hour: %d\n", local->tm_hour);
printf("tm_mday: %d\n", local->tm_mday);
printf("tm_mon: %d\n", local->tm_mon);
printf("tm_year: %d\n", local->tm_year);
printf("tm_wday: %d\n", local->tm_wday);
printf("tm_yday: %d\n", local->tm_yday);
printf("tm_isdst: %d\n", local->tm_isdst);
universal = gmtime(&t);
printf("\nUniversal date and time :\n %s", asctime(universal));
return 0;
}

324 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

162
10.06.2021

<locale.h>
Local settings
 A locale is a group of settings that controls items such as the
symbol used as a decimal point.
 Locale values are stored in a structure of type struct lconv,
defined in the locale.h header file.
 A locale can be specified by a string, which acts to specify a
particular set of values for the structure members. The default
locale is designated by the string "C" .

struct lconv *localeconv(void);

 Returns a pointer to a struct lconv structure filled in with


the values of the current locale

325 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

<locale.h>
Local settings
char *setlocale(int category, const char *locale)

 The function sets certain locale values to the values specified by the
locale and indicated by locale.
 The category value controls which locale values get set

326 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

163
10.06.2021

#include <locale.h>
#include <stdio.h>
#include <time.h> Example
int main () {
time_t currtime;
struct tm *timer;
char buffer[80];
time( &currtime );
timer = localtime(&currtime );
printf("Locale is: %s\n", setlocale(LC_ALL, "en_GB"));
strftime(buffer,80,"%c", timer );
printf("Date is: %s\n", buffer);
printf("Locale is: %s\n", setlocale(LC_ALL, "de_DE"));
strftime(buffer,80,"%c", timer );
printf("Date is: %s\n", buffer);
printf("Locale is: %s\n", setlocale(LC_ALL, "pl_PL"));
strftime(buffer,80,"%c", timer );
printf("Date is: %s\n", buffer);
printf("Locale is: %s\n", setlocale(LC_ALL, "ja_JP.UTF-8"));
strftime(buffer,80,"%c", timer );
printf("Date is: %s\n", buffer);
return(0);
}

327 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <locale.h>
#include <stdio.h>
int main () { Example
struct lconv* loc;
printf("Locale is: %s\n", setlocale(LC_ALL, "en_GB.UTF-8"));
loc = localeconv();
printf("Currency symbol is: %s (%s)\n",
loc->currency_symbol,
loc->int_curr_symbol);

printf("Locale is: %s\n", setlocale(LC_ALL, "de_DE.UTF-8"));


loc = localeconv();
printf("Currency symbol is: %s (%s)\n",
loc->currency_symbol,
loc->int_curr_symbol);
printf("Locale is: %s\n", setlocale(LC_ALL, "pl_PL.UTF-8"));
loc = localeconv();
printf("Currency symbol is: %s (%s)\n",
loc->currency_symbol,
loc->int_curr_symbol);
printf("Locale is: %s\n", setlocale(LC_ALL, "ja_JP.UTF-8"));
loc = localeconv();
printf("Currency symbol is: %s (%s)\n",
loc->currency_symbol,
loc->int_curr_symbol);
return(0);
}
328 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

164
10.06.2021

<stdlib.h>
general utilities
 String to number conversion:
 atoi(), atof(), atol() – decimal system
 strtod(), strtof(), strtol() – any numerical system

329 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <stdlib.h>

int main ()
{
char szOrbits[] = "365.24 29.53";
char* pEnd;
double d1, d2;
d1 = strtod (szOrbits, &pEnd);
d2 = strtod (pEnd, NULL);
printf ("The moon completes %.2f orbits per Earth year.\n", d1/d2);

printf("\n*******************\n\n");

char str[30] = "2030300 This is test";


char *ptr;
long ret;
ret = strtoul(str, &ptr, 10);
printf("The number(unsigned long integer) is %lu\n", ret);
printf("String part is |%s|", ptr);

return 0;
}

330 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

165
10.06.2021

<stdlib.h>
quick sort
void qsort(void *base, size_t nmem,size_t size,
int(*comp) (const void*, const void *));
 Sorts the array pointed to by base in the order provided by the function
pointed to by comp;
int comp (const void *arg1, const void *arg2);

 the array has nmem elements, each of size bytes;


 the comparison function will return a value less than zero if the object
pointed to by the first argument is less than the object pointed to by the
second argument, zero if the objects are equivalent, or a value greater than
zero if the first object is greater.

331 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

Example
#include <stdio.h>
#include <stdlib.h>
int por(const void *, const void *);
int main(void){
int i;
int num[10] = {1,3,6,5,8,7,9,6,2,0};
printf("Original array: ");
for(i=0; i<10; i++)
printf("%d ", num[i]);
qsort(num, 10, sizeof(int), por);
printf("\n\nSorted array: ");
for(i=0; i<10; i++)
printf("%d ", num[i]);
return 0;
}

int por(const void *ch, const void *s){

return *(int *)ch - *(int *)s;


}

332 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

166
10.06.2021

Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare (const void * a, const void * b ) {
return strcmp(*(char **)a, *(char **)b); Function compares names
}
int main(){
int i, n;
char* names[] = {
"Kowalski",
"Iksinski",
"Adamczyk",
"Adamczewski",
"Nowak",
"Nowakowski",
"Wojciechowski"};
n = sizeof(names) / sizeof(char *);
qsort (names, n, sizeof (char*), compare); Array sorting
for(i=0; i<n; i++)
puts(*(names+i));

return 0;
} 333 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
struct complex_t{
float im, re;
};
float module (struct complex_t *c){
return sqrt(pow(c->im,2) + pow(c->re,2));
}
Example
int compare(const void * a, const void * b ) {
float mod1 = module((struct complex_t*)a);
float mod2 = module((struct complex_t*)b);
float diff = mod1 - mod2;
Function compares modules
if (diff < 0) return -1;
else if (diff > 0) return 1;
else return 0;
}
void print (struct complex_t* s, int size){
for (int i=0; i<size; i++)
printf("(%.2f + j%.2f) ", (s+i)->im, (s+i)->re);
printf("\n****\n");
}
int main(){
struct complex_t data[5] = {{2,2},{5,5},{1,1},{3,3},{4,4}};
print(data,5);
qsort(data,5,sizeof(struct complex_t),compare); Array sorting
print(data,5);
return 0;
} 334 dr hab. inż. Anna Fabijańska, prof. PŁ, Advanced Programming

167

You might also like