Prog C - 201

Download as pdf or txt
Download as pdf or txt
You are on page 1of 110

Advanced C 201

Christian Salim, PhD


Arrays
Declare an Array

 Declare an array of size n:


 type array_name[n] ;
 Reserve n consécutives memory slots

 Ex. : declare an array of 10 integers called tb1 :

 Int tb1[10] ;

3
Access the elements of an array
 Modify the content of an element:

 Tb1[3]=19;

 To fill in the array, you have to modify it element by element

 Use the value of an element:

 x = tb1[3] + 1 ;

 To display all the elements => display element by element

4
Initialization at the declaration

 inttb1[10] = { 21, 32, -4, 1, 37, 88, 9, -1, 0, 7} ;

 inttb1[10] = { 21, 32, -4, 1} ;

 inttb1[ ] = { 21, 32, -4, 1} ;

5
Multidimensional arrays
 A multidimensional array is declared by precising the size of each
dimension:

 Type array_name[size1][size2][size3][…];

 Example:

 Char c[1][3]

 int cube [5][5][5]

 Int tab [4][3]

6
tab
Multidimensional arrays
 Initialization:

 int array[2][3]={{1,8,9},{0,6,4}};

 Int array[2][2][3]={
{{1,8,9},{0,6,4}},
{{1,8,8},{1,7,5}}
};

 We can also initialize an array without precising the first dimension:

 Int array1[][3]={{1,8,9},{0,6,4},{5,3,7},{2,2,2}};
➔int array[4][3]

7
Multidimensional arrays
 Go through a two-dimensional table:

#include<stdio.h>
#define size1 10
#define size2 15
int main()
{
int array[size1][size2];
int i,j;
for(i=0 ; i<size1 ; i++)
{
for(j=0 ; j <size2 ; j++)
{
array[i][j] = 0;
}
}
Return 0; } 8
Multidimensional arrays
 Go through a three-dimensional table:

#include<stdio.h>
#define size1 2
#define size2 3
#define size3 4
int main()
{
int array[size1][size2][size3];
int i,j, k;
for(i=0 ; i< size1 ; i++)
{
for(j=0 ; j < size2 ; j++)
{
for(k=0 ; k < size3 ; k++)
{
tableau[i][j][k] = 0;
}
}
}
Return 0; } 9
Multidimensional arrays
 Example: Transposition of a matrix

#include <stdio.h>
#define size 4
int main() {
int tab[size][size] = {{1,1,1,1},{2,2,2,2}, {3,3,3,3}, {4,4,4,4}};
inttemp, i=0,j=0;
for (i=0; i<size; i++)
{
for (j=i+1; j<size; j++)
{
temp = tab[i][j];
tab[i][j] = tab[j][i];
tab[j][i] = temp;
}
}
for(i=0;i<size;i++)
{
for (j=0;j<size;j++)
{
printf("%d",tab[i][j]);
}
printf("\n");
}
10
Return 0; }
Multidimensional arrays
 Example2: Multiplying 2 matrices
#include <stdio.h>
void main()
{
int A[3][3] = {{1,1,1},{2,2,2}, {3,3,3}};
int B[3][3] = {{1,1,1},{2,2,2}, {3,3,3}};
int C[3][3],i, j, k;
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
C[i][j]=0;
for (k=0; k<3; k++)
C[i][j] += A[i][k]*B[k][j];
}
}
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
printf("%3d", C[i][j]);
}
printf("\n");
}
Return 0; } 11
Lab Arrays
Strings
Definition
 A String is an array of characters that ends with a null character

 Null character:

 ASCII code : 0

 Written: ‘\0’

 All the significative values are stored before this character

 If the null character represents the first element => empty string

 Example:

 Sentence “Toto” is coded this way:

‘T’ ‘o’ ‘t’ ‘o’ ‘\0’ …

14
Declaration
 As a string is an array of chars, we declare it :
 char <String name>[<size>];
 For example, we declare a string c of 200 characters as follows:
 char c[200];
 Be careful! The maximum number of letters that can be placed in c will certainly not
be 200 but 199, because after the last character of the string a null character must be
placed, the \0!

15
Initialization
 A string is initialized at the declaration like this :
 char <string name>[<size>]=<initialization value>;
 Where the initialization value contains the juxtaposition of characters forming the
string surrounded by inverted commas
 e.g. char c[50]= "Toto";
 This instruction declares a string c initialized to "Toto". The first 5 elements of the array
will be occupied by the 4 characters of the string as well as the null character, the
others will contain insignificant values.
 Look closely at the following example : char c[4]= "Toto";
 This declaration will generate a warning at compile time and probably an error at run
time because the assignment of the null character to the 5th position of the array will
result in an index overflow.

16
Access the elements

 Example 1: test if a letter is uppercase:


if (c[0]>= 'A' && c[0] <= 'Z ‘ )
printf( « This sentense starts with a capital letter.\n" ) ;
else
printf( " This sentense does not start with a capital letter.\n" ) ;
 Example 2: Display a String character by character:

int i = 0 ;
while(c[i] != 0)
printf( "%c", c[i++]);

17
Access the elements
 Example 1: test if a letter is uppercase:
if (c[0]>= 'A' && c[0] <= 'Z ‘ )
printf( « This sentense starts with a capital letter.\n" ) ;
else
printf( " This sentense does not start with a capital letter.\n" ) ;

Example 2: Display a String character by character:


int i = 0 ;
while(c[i] != 0)
printf( "%c", c[i++]);

 Display all the string using %s:


printf( « your string is: %s\n" , c ) ;
18
Access the elements
 Example 3: which code is correct to get all the alphabet?

char c [26] ;
int i;
for ( i = 0 ; i < 26 , i++) char c [27] ;
c [i] = 'a' + i ; int i;
for ( i = 0 ; i < 27 , i++)
c [i] = 'a' + i ;

19
Input

#include<stdio.h>
#define N 20
int main ( )
{
char string1 [N] ;
int i;
printf( « Write a sentence: \n » ) ;
gets(string1) ;
for ( i = 0; string1[ i ] != 0 ; i++)
printf( « string1[%d] = %c (code ASCII: %d)\n", i, string1[ i ] ,string1[i]);
return 0 ;
}

20
Input

#include<stdio.h>
#define N 20
int main ( )
{
char string1 [N] ;
int i;
printf( « Write a sentence: \n » ) ;
gets(string1) ;
for ( i = 0; string1[ i ] != 0 ; i++)
printf( « string1[%d] = %c (code ASCII: %d)\n", i, string1[ i ] ,string1[i]);
return 0 ;
}

21
Input
 gets function is never recommended => we use fgets

 Syntax: fgets(<string >, <size>, stdin) ;


 The size of the sting is limited by <size>, counting the null character
 The result is stored in <string>.
 The (<size> -1) first characters are the input of fgets.
 If the user enters more characters they will not be stored in <string>

 In the last example:


fgets(string, 200, stdin);

22
String.h library
This library proposes some functions to manipulate the strings, we cite some of
these functions:

 strlen: size of a string


 strcmp: compare two strings.
 strcat: concatenate two strings
 strcpy: copy a string

23
Strlen (size)

#include <stdio.h>
#include <string.h>
#define CLEAR_BUFFER while (getchar()!='\n’)
#define BUFFER_SIZE 9

int main()
{
char mot[BUFFER_SIZE];
printf(« Write a string: ");
scanf("%s",mot);
printf("size=: %lu\n", strlen(mot));
return 0;
}

24
Strlen (size)
#include <stdio.h>
#include <string.h>
#define CLEAR_BUFFER while (getchar()!='\n’)
#define BUFFER_SIZE 9

int main()
{
char mot[BUFFER_SIZE];
printf(« Write a string: ");
fgets(mot, BUFFER_SIZE, stdin);
while(mot[i]!='\0’)
{
i++;
}
mot[i-1]='\0';
printf("size=: %lu\n", strlen(mot));
return 0;
}
25
Strcat

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

int main()
{
char ch1[50] = "bonjour" ;
char ch2[50] = " monsieur" ;
printf(« first: %s\n", ch1) ;
strcat(ch1, ch2) ;
printf(« later : %s", ch1) ;
return 0;
}

26
Strcpy

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

int main()
{
char ch1[20] = "xxxxxxxxxxxxxxxxxxx" ;
char ch2[20] ;
printf(« write a word: ") ;
gets (ch2) ;
strcpy(ch1, ch2) ;
printf("%s", ch1) ;
return 0;
}

27
Invert a String
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 10
int main() {
int i=0;
char mot[BUFFER_SIZE], mot_inverse[BUFFER_SIZE];
printf("Write a string: ");
fgets(mot, BUFFER_SIZE, stdin);
printf("size = %lu\n",strlen(mot));
while(mot[i]!='\0’)
i++;
mot[i-1]='\0';
mot_inverse[strlen(mot)] = 0; OR mot_inverse[strlen(mot)] = ‘\0’
for(i=0; i<strlen(mot); i++)
mot_inverse[strlen(mot)-1-i] = mot [i];printf("Le mot inverse est: %s\n",
mot_inverse);
return 0;}
28
Detect if the string is a palindrome: strcmp
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 10
int main() {
char mot[BUFFER_SIZE], mot_inverse[BUFFER_SIZE];
printf(« Write a string: ");
fgets(mot, BUFFER_SIZE, stdin);
int i=0;
while(mot[i]!='\0’)
i++;
mot[i-1]='\0';
printf("size mot=%lu\n",strlen(mot));
for(i=0; i<strlen(mot); i++){
mot_inverse[strlen(mot) -1 -i] = mot [i];}
printf("size motinv= %lu\n", strlen(mot_inverse));
printf("Le mot inverse est:%s\n", mot_inverse);
printf("mot= %s\n",mot);
printf("motinv= %s\n",mot_inverse);
if (strcmp(mot,mot_inverse) == 0)
printf("Palindrome");
Else
printf("Non palindrome");
return 0;}
29
Functions
&
Procedures
Procedures
 It is a bloc of instructions that has a name.

 To define a procedure, we use the syntax below:

Void procedure_name()
{
/*
instructions
*/
}

31
Procedures
 To execute a procedure, we must call it in our main program by its
name.

 Both programs below have the same functionality:

#include <stdio.h>
#include <stdio.h>
int main(){ Void displayhello(){
printf(« hello »); Printf(« hello »);
return 0; }
} int main(){
displayhello();
return 0;
}

32
Procedures
 It is a bloc of instructions that have the same obligations as main.

 We can declare variables in a procedure, we call them – local


variables.

 Those variables are only accessible in the procedure

 They are born at their declaration

 They are destructed at the end of the procedure’s execution.

33
Procedures
 A local variable is only visible between its declaration and the end of the
procedure.

#include <stdio.h>
#include <stdio.h> void unADix()
{
void my_procedure(){ int i;
char a=‘b’; for(i = 1 ; i <= 10 ; i++ )
} printf("%d\n", i);
int main(){ }
char b=‘k’; int main()
printf(« %c,%c\n »,a,b); {
return 0; unADix();
} return 0;
}
34
passing of parameters
 It is possible that the value of a local variable in a procedure is only
known at the time the procedure is called.

#include<stdio.h>
void displayInt(int i)
{
printf("%d", i);
}
int main(){
int i;
printf(« Enter a value: ");
scanf("%d", &i);
displayInt(i);
printf("\n");
return 0;}
35
passing of parameters
 The i in displayInt and the i in main are two different variables. The only
thing that links them is that the instruction displayInt(i) initializes the i
in displayInt to the value of the i in main. It would be perfectly possible
to write:
#include<stdio.h>
void displayInt(int j)
{
printf("%d", j);
}
int main(){
int i;
printf(« Enter a value: ");
scanf("%d", &i);
displayInt(i);
printf("\n");
return 0;}
36
passing of parameters
 A parameter is a variable that is initialized at the procedure’s call.

 Example:

 displayInt(4) executes the procedure while initializing the value of ‘i’ to 4.

 We are passing a parameter by value. Value=4.

37
passing of parameters
 It is possible to pass several values as parameters. For example, the
following procedure displays the sum of the two values passed as
parameters
void displaySum(int a, int b)
{
printf("%d", a + b);
Void displaySum(int a, int b) }
{ int main(){
printf(«%d», a + b); int i, j;
} printf(« Enter 2 values\na = ");
scanf("%d", &i);
printf("b = ");
scanf("%d", &j);
printf("a + b = ");
displaySum(i, j);
printf("\n");
}
38
passing of parameters
 Try this code: what is the result and why?

#include<stdio.h>
void incr(int v)
{
v++;
}
int main()
{
int i;
i = 6;
incr(i);
printf("%d\n", i);
return 0;
}
39
Functions
 A function is a sub-program that returns a value for the calling program.

 It is called a return value.

 It has a type which is the same type of the returned value.

 A function returns only 1 value, it cannot return an array.

 Syntax:
 v=function_name(parametres);
 Exemple1: v=carre(2);
 Exemple2:v=sum(2,3);

40
Recursive Functions
 A recursive function is a function that calls itself.
 We call it back in the return.
 It must have a stop condition. (Otherwise => endless function)
 Factorial example:

int facto(int n){


if(n==0)
return 1;
else
return n*facto(n-1);
}

41
Passing of parameters by reference

 In C, when you invoke a function, all the values of the effective


parameters are copied into the formal parameters.
 In this case, we say that the parameter passage is done by value.
 You can therefore, only communicate one value to the calling program.
 only the return value will allow you to communicate a value to the
calling program.

42
Passing of parameters by reference

 When you pass an array as a parameter, the value that is copied into the
parameter forms the address of that aray (the address is a single scalar
value).
 Therefore, any changes made to the elements of an array whose address
has been passed by value as a parameter will be applied to the effective
parameter (i.e. the original array).
 If changes made to a parameter in a sub-program are transferred to the
original parameter, then the parameter is transferred by reference.

43
Passing of parameters by reference
 Try this code:

#include<stdio.h>
void incr(int *v)
{
(*v)++;
}
int main()
{
int i;
i = 6;
incr(&i);
printf("%d\n", i);

return 0;
}

44
Passing of parameters by reference
#include<stdio.h>
void initarr(int K[], int n)
{
int i;
for(i = 0 ; i < n ; i++)
K[i] = i + 1;
}
void displayarr(int K[], int n)
{
int i;
for(i = 0 ; i < n ; i++)
printf("%d\n", K[i]); T is a variable containing a
} memory address, T is
int main() therefore a pointer.
{ T &T[0]
int T[50];
initarr(T, 50);
displayarr(T, 50);
45
}
Pointers
Pointers
 A pointer is a variable that contains the memory address of another
variable.

 Example :

Pointer on x

Address: 12,004,234

47
Pointers
 Declaration:
 General form:
 Type* pointer_name

 Example : int* p
 P is a pointer
 p will point to a variable of type int

48
Pointers
 Declaration example:

x is of type int
#include<stdio.h>
int main() p is of type int*
{ - p is a pointer to an integer,
int x = 3; - p will contain the memory address of an int.
int* p;
p = &x; &x is the memory address of the variable x,
Return 0; -the assignment p = &x places the memory address of x in the
} pointer p.
-From this assignment, p points to x.

49
Pointers
 Display:

#include<stdio.h>
voidmain() Same Value
{
int x = 3;
int* p;
p = &x;
printf(« the value of p is %X, which is the address %X of x", p, &x);
}

50
Pointers
 Access to the pointed variable:

 If p points to x, then it is possible to access the value of x through p

 *p  x

 These are two ways of referring to the same variable

 This is called "aliasing".

51
Pointers
 Access to the pointed variable: Example:

#include<stdio.h>
*p=4  x=4
int main()
{ All changes made to *p will be reflected in the variable
int x = 3; pointed to by p. (x)
int* p;
p = &x; Result:
printf("x = %d\n", x); x=3
*p = 4; x=4
printf("x = %d\n", x);
return 0;
}

52
Pointers
 What each of those programs displays?

#include<stdio.h>
void main()
{
#include<stdio.h>
int x = 3;
Void main()
int y = 5;
{
int* p;
intx = 10;
p = &x;
int* p;
printf("x = %d\n", x);
p = &x;
*p = 4;
printf("%d\n", x);
printf("x = %d\n", x);
printf("%d\n", *p);
p = &y;
printf("%X\n", p);
printf("*p = %d\n", *p);
}
*p = *p + 1;
printf("y = %d\n", y);
}
53
Pointers
 Arrays

 The elements of an array are placed side by side in the memory


 In other words, they are placed next to each other
 int occupies 2 bytes in memory and that &T[0] is the memory address of the first
element of the array T
 What is the address of T[1]?
 Answer: &T[0]+2 (not recommended to use)

 If the address of the first element of a table is known, it is possible to find the
addresses of all the other elements.

54
Pointers
 Arrays
 The compiler will take over this part of the work.
 This means that regardless of the type of elements in the array p, the memory
address of the i-th element is p+i

#include<stdio.h>
void main()
{
int tab[5]={1,2,3,4,5};
int i = 0;
int*p;
while(i<5)
{
p = &tab[0]+i;
printf("%d\n", *p);
i = i+1;
}} 55
Pointers
 Arrays
#include<stdio.h>
void initTab(int K[], int n)
{
inti;
for(i = 0 ; i < n ; i++)
K[i] = i + 1;
}
void afficheTab(int K[], int n)
T is a variable containing a memory {
address, inti;
T is therefore a pointer. for(i = 0 ; i < n ; i++)
&T[0]  T printf("%d\n", K[i]);
}
void main()
{
int T[50];
initTab(T, 50);
afficheTab(T, 50); 56
}
Pointers
 Arrays (How to use Pointers)

#include<stdio.h>
void main()
{
char t[10];
char* p;//p is a char pointer
t[0] = 'a';
p = t; //p = &t[0]
//p points to t[0]
printf(« the first element is %c.\n", *p); //*pt[0]
}

57
Pointers
 Arrays (How to use Pointers)

#include<stdio.h>
void main()
{
char t[10];
char* p;
t[1] = 'b';
p = t;
printf(« the second element is %c.\n", *(p+1)); //*(p+1)t[1]
}

58
Pointers
 Arrays (How to use Pointers)

#include<stdio.h>
#defineN 26
void initTab(char* k, int n)
{ int main()
inti; {
intv = 'A'; char t[N];
for(i = 0 ; i < n ; i++) initTab(t, N);
*(k + i) = v++; afficheTab(t, N);
} return 0;}
void afficheTab(char* k, int n)
{
inti;
for(i = 0 ; i < n ; i++)
printf("%c ", *(k + i));
printf("\n");
} 59
Pointers
Dynamic memory allocation
Size Problem
 When declaring an array, it is mandatory to specify its size.
 The size of an array must be known at compile time.
 What to do if we don't know this size?
 The only solution at the moment is to oversize the array: we give it a very high
size so that no overflow occurs.

60
Pointers
Dynamic memory allocation
Malloc Function
 The function that reserves n bytes is malloc(n).
 malloc(10) the OS reserves 10 bytes.
 This is called a dynamic allocation, i.e. an allocation of memory during
execution.
 Example: to reserve memory space to store an int, just call malloc(2).

61
Pointers
Dynamic memory allocation
Malloc Function
 malloc returns the memory address of the 1st byte of the reserved area.
 Example: p = malloc(2)where p is of type int*.
 Malloc reserves 2 bytes, and returns the memory address of the allocated area.
 This assignment places in p the memory address of the newly created integer

 Since malloc returns a pointer of type char* by default, it will be necessary to


perform what is called a cast when we want to dynamically allocate a pointer
to a type other than char: int* p = (int*)malloc(2);
 Note: char* p= malloc(1); // no cast required

62
Pointers
Dynamic memory allocation
Malloc Function
Example:

#include<stdio.h>
#include<malloc.h>
void main()
{
int* p;
p = (int*)malloc(2);
*p = 28;
printf("%d\n", *p);
}

63
Pointers
Dynamic memory allocation
Calloc function
 It has the same role as the malloc function but it allows to:
 reserve nb-objects objects of nb bytes
 to initialize them to zero.

 Its syntax is: calloc(nb-objects,nb-bytes)


 Library: #include <malloc.h>

 Thus, if p is of type int*, the instruction


 p = (int*)calloc(N,sizeof(int));

 p = (int*)malloc(N * sizeof(int));
64
Pointers
Dynamic memory allocation
Free function
 When performing a dynamic allocation, the reserved space cannot be
allocated for another variable.
 Once you no longer need it, you must explicitly free it if you want another
variable to be stored there.
 The function for freeing the memory is free.
 free(v) where v is a variable containing the memory address of the area to be
freed.
 Every time you allocate a memory area, you must free it!

65
Pointers
Dynamic memory allocation
Free function (Example)

#include<stdio.h>
#include<malloc.h>
void main()
{
int* p;
p = (int*)malloc(2);
*p = 28;
printf("%d\n", *p);
free(p)
}

66
Pointers
Dynamic memory allocation
NULL Value
 A pointer must always be initialized:
 p = &a;//assign to p, the address of a
 p1 = p2; //directly assign the pointer p2 to p1
 p = NULL; //assign to p, the value null (points to nothing)
 A pointer p that points to no address has the value NULL.
 NULL is the value that, conventionally, we decide to give to p if it does not point
to any valid memory area.
 For example, the malloc function returns NULL if no suitable memory area is
found.
 Each time malloc is used, it should be checked whether the value returned by
malloc is different from NULL.
67
Pointers
Dynamic memory allocation
NULL Value (Example):

#include<stdio.h>
#include<malloc.h>
voidmain()
{
int* p;
p = (int*)malloc(2);
if(p == NULL)
return -1;
*p = 28;
printf("%d\n", *p);
free(p);
}
68
Pointers
Dynamic memory allocation
Dynamic allocation of an array:
#include<stdio.h>
#include<malloc.h> int main()
#defineN 26 {
void initTab(int* k, int n) int* p;
{ p = (int*)malloc(N*sizeof(int));
int i; if (p == NULL)
for(i = 0 ; i < n ; i++) return -1;
*(k + i) = i + 1; initTab(p, N);
} afficheTab(p, N);
void afficheTab(int* k, int n) free(p);
{ return 0;
int i; }
for(i = 0 ; i < n ; i++)
printf("%d ", *(k + i));
printf("\n");
} 69
Pointers
Dynamic memory allocation
Passage of parameters by reference (by address):

#include<stdio.h> #include<stdio.h>
void echange(int x, int y) void echange(int* x, int* y)
{ {
tnt t = x; tnt t = *x;
x = y; *x = *y;
y = t; *y = t;
} }
void main() void main()
{ {
int a = 1; int a = 1;
int b = 2; int b = 2;
printf("a = %d, b = %d\n", a, b); printf("a = %d, b = %d\n", a, b);
echange(a, b); echange(&a, &b);
printf("a = %d, b = %d\n", a, b); printf("a = %d, b = %d\n", a, b);
} } 70
Pointers
Exercises (1):
main() Complete this table after each instruction
{
intA = 1;
intB = 2;
intC = 3;
int*P1, *P2;
P1=&A;
P2=&C;
*P1=(*P2)++;
P1=P2;
P2=&B;
*P1-=*P2;
++*P2;
*P1*=*P2;
A=++*P2**P1;
P1=&A;
*P2=*P1/=*P2;
return 0;
}
Pointers
Exercises (1):
main() Complete this table after each instruction
{
intA = 1;
intB = 2;
intC = 3;
int*P1, *P2;
P1=&A;
P2=&C;
*P1=(*P2)++;
P1=P2;
P2=&B;
*P1-=*P2;
++*P2;
*P1*=*P2;
A=++*P2**P1;
P1=&A;
*P2=*P1/=*P2;
return 0;
}
Pointers
Exercises (2):

int A[] = {12, 23, 34, 45, 56, 67, 78, 89, 90};
int*P;
P = A;

What are the values of:


a)*P+2
b)*(P+2)
c)&P+1
d)&A[4]-3
e)A+3
f)&A[7]-P
g)P+(*P-10)
h)*(P+*(P+8)-A[7])
Pointers
Exercises (2):

int A[] = {12, 23, 34, 45, 56, 67, 78, 89, 90};
int*P;
P = A;

a) *P+2 => value14


b) *(P+2) => value 34
c) &P+1 => the address of the pointer behind the P
pointer (rarely used)
d) &A[4]-3 => address of A[1]
e) A+3 => address of A[3]
f) &A[7]-P => value (index) 7
g) P+(*P-10) => address of A[2]
h) *(P+*(P+8)-A[7]) => Value 23
Pointers
Arrays and Pointers
Multidimensional arrays
 The two-dimensional array M is defined as follows: int
M[4][10]={{0,1,2,3,4,5,6,7,8,9},
{10,11,12,13,14,15,16,17,18,19},
{20,21,22,23,24,25,26,27,28,29},
{30,31,32,33,34,35,36,37,38,39}};
 The name of array M represents the address of the first element of the
array and points to the array M[0] which has the value:
{0,1,2,3,4,5,6,7,8,9}.
 The expression(M+1)is the address of the second element of the array
and points to M[1] which value is:{10,11,12,13,14,15,16,17,18,19}.
Pointers
Arrays and Pointers
Multidimensional arrays
Solution
 intM[4][10] = {{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
{10,11,12,13,14,15,16,17,18,19},
{20,21,22,23,24,25,26,27,28,29},
{30,31,32,33,34,35,36,37,38,39}};
 int*P;
 P = (int*)M; /* forced conversion */
 Due to the row-by-row storage of two-dimensional arrays, we can now
treat M with the pointer P as a one-dimensional array of dimension 4*10.
Pointers
Access the elements:
 -mat[i] → *(mat+i)
 -mat[i][j] → *(mat[i] + j)
 -Example:
 int A[3][4];
A[0][0]=1;
A[0][1]=2;
A[1][0]=10;
A[1][1]=20;
 The address of the element A[I][J] is then calculated by:
A + I*4 + J
for I = 1, J = 0 → A[1][0] → A + 1*4 + 0 → A + 4 → &A[0] + 4 → IE0E
 The pointed content can be accessed using:
*((int*) A + I*4 + J).
Pointers
Several methods exist:
 Using 1 single pointer
 int*arr;
 Using an array of pointers
 int*arr[r];
 Using a pointer to pointers
 int**arr;
Pointers
Using 1 Single Pointer:

int main()
{
int r = 3, c = 4, i, j, count = 0;
int* arr= (int*)malloc(r * c * sizeof(int));
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr+ i*c + j) = ++count;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", *(arr+ i*c + j));
return 0;}
Pointers
Using an array of pointers:

void main()
{
int r = 3, c = 4, i, j, count;
int* arr[r];
for (i=0; i<r; i++)
arr[i] = (int*)malloc(c * sizeof(int));
count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);
}
Pointers
Using a pointer to pointers:

void main()
{
int r = 3, c = 4, i, j, count;
int** arr= (int**)malloc(r * sizeof(int*));
for (i=0; i<r; i++)
arr[i] = (int*)malloc(c * sizeof(int));
count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);
}
Pointers
Using a pointer to pointers:
 This type of array is a simple array of pointers, each of which will point to
a space representing a one-dimensional array:
Pointers
Using a pointer to pointers:
 First dimension allocation (ptr)
 This is the array of pointers which will contain several pointers which in turn
point to spaces allocated as arrays.
 Second dimension allocation (*ptr)
 These are the various arrays called "value arrays" in the image above.
 Release of the second dimension (*ptr)
 These are the various tables called “tableaux de valeurs" in the image above.
 Release of the first dimension (ptr)
 These are the various tables called "value tables" in the image above
Pointers
Using a pointer to pointers:

#include<stdio.h>
intmain()
{
inti , taille1=2 , taille2=3;
int**ptr;
ptr= (int**)malloc(taille1 * sizeof(int*));
for(i=0 ; i < taille1 ; i++)
{
ptr[i] = (int*)malloc(taille2 * sizeof(int) );
}
printf("Notre tableau ptr[2][3] est maintenant utilisable...");
//free:
for(i=0 ; i < taille1 ; i++){
free(ptr[i]);
}
free(ptr);
}
Pointers
Using a pointer to pointers:

#include<stdio.h>
intmain()
{
inti , taille1=2 , taille2=3;
int**ptr;
ptr= (int**)malloc(taille1 * sizeof(int*));
if(ptr== NULL)
return 1;
for(i=0 ; i < taille1 ; i++){
ptr[i] = (int*)malloc(taille2 * sizeof(int) ); printf("Notre tableau ptr[2][3] est
if(ptr[i] == NULL) maintenant utilisable...");
{ //Liberation:///////////////////////////////
for(i = i-1 ; i >= 0 ; i--) for(i=0 ; i < taille1 ; i++){
free(ptr[i]); free(ptr[i]);
free(ptr); }
} free(ptr);
} }
Pointers
Transpose a Matrix using Pointers:

#include<stdio.h>
#defineN 3 printf("Matrice donnée :\n");
main() for (i=0; i<N; i++)
{ {
int* A; for (j=0; j<N; j++)
inti, j; printf("%7d", *(A+i*N+j));
A = (int**)malloc(N * sizeof(int*)); printf("\n");
for(i=0 ; i < N ; i++) }
{ printf("Matrice transposée :\n");
A[i] = (int*)malloc(N * sizeof(int) ); for (j=0; j<N; j++)
} {
for (i=0; i<N; i++) for (i=0; i<N; i++)
for (j=0; j<N; j++) printf("%7d ", *(A+i*N+j));
{ printf("\n");
printf("Elément[%d][%d] : ",i,j); }
scanf("%d", A+i*N+j); return 0;
} }
Pointers
Multiply 2 matrices using pointers:
voidmain(){
intA[N][N]= {{1,1,1},{2,2,2}, {3,3,3}};
intB[N][N] = {{1,1,1},{2,2,2}, {3,3,3}};
intC[N][N];
inti, j, k;
for (i=0; i<N; i++)
for (j=0; j<N; j++)
{
*((int*) C+i*N+j)=0;
for (k=0; k<N; k++)
*((int*)C+i*N+j) += *((int*)A+i*N+k) * *((int*)B+k*N+j);
}
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
printf("%7d", *((int*)C+i*N+j));
printf("\n");
}
}
Structures
Structure
 A structure is a variable containing several variables, called
"fields".
 If a structure t contains a char and an int, each of these
fields will have a name
 Example:
 t contains the integer and the character c.
 t.c will be the char of t
 t.i will be the int of t

89
Structures Declaration
 To create a structured type, the following syntax is used:

struct_name_of_the_type
{
typefield_1 namefield_1;
typefield_2 namefield_2;
...
typefield_n namefield_n;
};

90
Structures Declaration
 Example

struct point
{
double x;
double y;
};

 struct point is now a type, it becomes possible to declare a point as any


other variable:

struct point p;

91
Fields access
 The fields of a structured variable are accessed using the dotted
notation

Variable_name.field_name

 Thus, the ‘y’ field of our variable p will be accessible with p.y and
the ‘x’ field of our variable p will be accessible with p.x.

92
Fields access
#include<stdio.h> #include<stdio.h>
struct point typedef struct point
{ {
double abs; double abs;
double ord; double ord;
}; }point;
main() main()
{ {
struct point p; point p;
p.ord= 2; p.ord= 2;
p.abs= p.ord+ 1; p.abs= p.ord+ 1;
printf("p = (%f, %f)\n", p.abs, p.ord); printf("p = (%f, %f)\n", p.abs, p.ord);
} }

Note that the . field access operator has priority over all other unary,
binary and ternary operators! 93
Array of Structures
int main()
{
point p[N];
#include<stdio.h>
inti;
#defineN 10
p[0].ord = 0;
typedef struct point
p[0].abs = 1;
{
for(i = 1 ; i < N ; i++)
double abs;
{
double ord;
p[i].ord = p[i -1].ord + 1.;
}point;
p[i].abs = p[i -1].abs + 2.;
}
for(i = 0 ; i < N ; i++)
{
printf("p[%d] = (%f, %f)\n", i,
p[i].abs, p[i].ord);
}
Return 0;}
94
Structures and Functions
 When passed as parameters, structures behave like scalar
variables, meaning that they can only be passed as parameters by
value.

 On the other hand, a structure array must be passed as a


parameter by reference.

95
Structs and Functions
void affichePoint(point p)
#include<stdio.h> {
#defineN 10 printf("(%f, %f)\n", p.abs, p.ord);
typedef struct point }
{ void afficheTableauPoints(point p[], int n)
double abs; {
double ord; int i;
}point; for(i = 0 ; i < n ; i++)
void initTableauPoints(point p[], int n) {
{ printf("p[%d] = ", i);
inti; affichePoint(p[i]);
p[0].ord = 0; }
p[0].abs = 1; }
for(i = 1 ; i < n ; i++) voidmain()
{ {
p[i].ord = p[i -1].ord + 1.; point p[N];
p[i].abs = p[i -1].abs + 2.; initTableauPoints(p, N);
} afficheTableauPoints(p, N); 96
} }
Structures and Functions
 As a structure behaves like a scalar variable, it is possible to
return a structure in a function.
 It is therefore possible to modify the program we wrote before:

97
Structs and Functions
void initTableauPoints(point p[], intn)
{ int i;
p[0].ord = 0;
#include<stdio.h>
p[0].abs = 1;
#defineN 10
for(i = 1 ; i < n ; i++)
typedef struct point
p[i] = nextPoint(p[i -1]);
{
}
double abs;
void afficheTableauPoints(point p[], intn)
double ord;
{ inti;
}point;
for(i = 0 ; i < n ; i++)
point nextPoint(point previous)
{
{
printf("p[%d] = ", i);
point result;
affichePoint(p[i]);
result.ord= previous.ord+ 1.;
}
result.abs= previous.abs+ 2.;
}
return result;
voidmain()
}
{
void affichePoint(point p)
point p[N];
{
initTableauPoints(p, N);
printf("(%f, %f)\n", p.abs, p.ord);
afficheTableauPoints(p, N); 98
}
}
Files
Definition
 When exiting a program, the data entered is lost.
 If you wish to have them available for a later run, you should
use a persistent memory, i.e. one that holds the data
between two runs.
 A file is used as a source.
 A file is stored permanently on a disk and is accessed with a
name.
 The data in a file is presented sequentially, so it is written
from the beginning to the end.

100
Open and Close a file
 To access the contents of a file for reading or writing, the two functions
fopen and fclose are used.
 fopen opens a file.
 FILE*fopen(const char*path,const char*mode):
 Path is a string containing the path (relative or absolute) and the file
name. If the file is in the directory where the program is running, then
the file name is sufficient.
 Mode is a string containing "r" to open the file in read mode, "w" in write
mode, etc.
 FILE* is a type to reference an open file, and returns NULL if the file
cannot be opened (e.g. the name is not correct).
 The value returned should be placed in a variable of type FILE*, this is
the value that will allow access to the file content.

101
Open and Close a file
 The close function is used to close a file.
 int fclose(FILE*fp):
 Fp is the FILE* type variable used to reference the file to be closed.
 Returns 0 if the file was successfully closed.

102
Read and Write
 There are several ways of writing in a file, each of which is done with
the help of an appropriate function:
 character by character,
 line by line,
 by character, line by line, by character groups,
 A read function is called a cursor function, which causes a cursor in a file
to move until the end of the file is reached.
 The writing function works in a similar way, except that it is necessary to
write the end character of the file, and it is added automatically when
the file is closed.

103
Read and Write
 Reading character by character
 The function intfgetc(FILE* stream) returns a character read from file f.
 Although the read character is a byte, it is returned in an int.
 The character EOF indicates that the end of the file has been reached.

104
Read and Write
#include<stdio.h>
intmain()
{
FILE* f;
char c;
f = fopen("toto.txt", "r");
if (f == NULL)
{
printf("Erreur lors de l'ouverture du fichier toto.txt\n");
return -1;
}
while((c = fgetc(f)) != EOF)
printf("caracterelu : %c\n", c);
if (fclose(f) != 0)
{
printf("Erreur lors de la fermeture du fichier toto.txt\n");
return -1;
}
return 0; 105

}
Read and Write
#include<stdio.h>
intmain()
{
FILE* f;
char c[7] = "Toto !";
inti;
f = fopen("toto.txt", "w"); //We are writing
if (f == NULL)
{
printf("Erreur lors de l'ouverture du fichier toto.txt\n");
return -1;
}
for(i = 0 ; i < 6 ; i++)
fputc(c[i], f); //We use fputc
if (fclose(f) != 0)
{
printf("Erreur lors de la fermeture du fichier toto.txt\n");
return -1;
} 106

return 0;}
Read and Write
 Reading by strings
 The following 2 functions allow you to read and write strings in files:
 char *fgets(char *s, intsize, FILE *stream)
 intfputs(constchar *s, FILE *stream)

107
Read and Write
 Reading by groups of characters
 The following 2 functions are very useful when you want to save an array
to a file, or copy a file to an array:
 size_tfread(void*ptr, size_tsize, size_tnmemb, FILE *stream)
 size_tfwrite(constvoid*ptr, size_tsize, size_tnmemb, FILE *stream)

108
Read and Write
#include<string.h>
#include<stdio.h>
struct personne
{
char nom[30];
int age;
};
int main()
{
FILE* f;
struct personne repertoire[3] = {{"tata", 2}, {"toto", 8}, {"titi", -1}};
f = fopen("toto.txt", "w");
if (f == NULL)
return 1;
fwrite(repertoire, 3, sizeof(structpersonne), f);
fclose(f);
return 0;
} 109
Read and Write
struct personne
{
char nom[30];
int age;
};
int main()
{
FILE* f;
int i, n = 0;
struct personne repertoire[3];
f = fopen("toto.txt", "r");
if (f == NULL)
return 1;
while(fread(repertoire+ n, 1, sizeof(structpersonne), f))
n++;
for (i = 0 ; i < n ; i++)
printf("%s %d\n", repertoire[i].nom, repertoire[i].age);
fclose(f);
return 0; 110

You might also like