Procedural Programming & Fundamentals of Programming Exercise 3 (SS 2018) 29.05.2018 What will I learn in the 4. exercise Pointer (and a little bit about memory allocation) Structure Strings and String functions in strings.h Exercise(s) FoP & PP 2 1
Task 8 Write a program which compares the length of 2 vectors of the form V1=(X1,X2,X3), V2=(Y1,Y2,Y3). The program should print out the result in the form: V1 > V2 or V1 < V2 or V1 = V2 The vectors should be read in into 2 arrays. The comparison of the vectors length should be realized by the function: int compveclen(int v1[], int v2[]) Hint: The length of a vector is calculated by V = x 2 + y 2 +z 2 FoP & PP 3 Why pointer? Allow us to get access to dedicated memory addresses. Advantages: allows low level programming (Example: access to registers of a micro controller) handling of unknown amount of data possibilty to return via a function more than one result (pass by reference) creation of complex data structures (binary trees or linked lists, etc.) FoP & PP 4 2
Pointer operators There are two pointer operators in C, known as: & The address of operator. Returns the memory address of a variable. * The dereferencing operator. Allows to access the content of that memory cell where the pointer refers to. (Hint: The asteriks * is also used for the declaration of a pointer) FoP & PP 5 Pointer declaration A pointer to an address where the value of a data type is or can be stored is defined by: <data type> * <identifier>; Examples: int *ip; //declaration of a pointer to addresses //where integer values are stored. char *cp; //declaration of a pointer to addresses //where character values are stored. FoP & PP 6 3
Memory management When we declare a normal variable like char or int or double the compiler takes care that the program will reserve the appropiate memory for that variable. Reserved memory depends on data type and machine architecture. When we declare a pointer variable the compiler reserves sufficient memory for storing an address. FoP & PP 7 Address assignment When we define a pointer variable without initialization, where does the pointer refer to? Answer: It points to an arbitrary address. In order to assign a valid address to the pointer we can do the following: int i; // define an integer variable i int *ip // define an integer pointer ip ip = &i;// ip refers now to the address // where the value of i is stored. => Take care that your pointer are working with the right addresses. FoP & PP 8 4
Pointer: simple example int main() int i; // no init => random values; int *ip; // no init => points to anywhere printf( value of i=%d, address of i=%p,i,&i); printf( value of ip=%d, address of ip=%p,ip, &ip); i = 5; //assign 5 to i ip = &i; //assignment of the address of i to ip printf( value of i=%d, address of i=%p,i,&i); printf( value of ip=%d, address of ip=%p,ip, &ip); printf( value of memorycell refered by ip:%d,*ip); FoP & PP 9 Memory values before and after init (assignments) Address (32 bit) : FFFF0000 FFFF0001 FFFF0002 FFFF0003 FFFF0004 FFFF0006 FFFF0007 FFFF0008 FFFF0009 : FFFFFFFF Value (8bit) random VALUE random VALUE 4 bytes reserved for variable i at address FFFF0000 4 bytes for the pointer pi at address FFFF0004 i = 5; => pi = &i; => Access to the value 5 via the pointer pi is possible by: *pi Address (32 bit) : FFFF0000 FFFF0001 FFFF0002 FFFF0003 FFFF0004 FFFF0006 FFFF0007 FFFF0008 FFFF0009 : FFFFFFFF Value (8bit) 5 FFFF0000 FoP & PP 10 5
Pointer and arrays (1) Pointers and arrays have a close relationship and can be treated in the same way. If you declare an array like int a[10] then a itself can be seen as pointer to the address where the first element is stored. Example: int iarr[10], *ip; ip = iarr; // ip and iarr refer same address // access to the first element possible by iarr[0] = 5; or *ip = 5; or *iarr = 5; FoP & PP 11 Pointer and arrays (2) How can we access the second (and following) element(s) by the pointer? Answer: Increment the pointer. That means, assuming we did ip = iarr then: ip points to memory cell of iarr[0] (ip+1) points to memory cell of iarr[1] (ip+2) points to memory cell of iarr[2] => *ip=5 //equal to iarr[0]=5 => *(ip+1)=6 //equal to iarr[1]=6 => *(ip+2)=7 //equal to iarr[2]=7 FoP & PP 12 6
Pointer and arrays (3) Address (32 bit) : FFFF0000 FFFF0001 FFFF0002 FFFF0003 FFFF0004 FFFF0006 FFFF0007 FFFF0008 FFFF0009 FFFF000A : Value (8bit) (Iarr[0]) 5 (Iarr[1]) 6 (Iarr[2]) 7 Initialization pi = iarr; pi points to *(pi) accesses (pi+1) points to *(pi+1) accesses (pi+2) points to *(pi+2) accesses Address (32 bit) : FFFF0000 FFFF0001 FFFF0002 FFFF0003 FFFF0004 FFFF0006 FFFF0007 FFFF0008 FFFF0009 FFFF000A : Value (8bit) (Iarr[0]) 5 (Iarr[1]) 6 (Iarr[2]) 7 FoP & PP 13 Pointer and arrays (4) Keep in mind: Declaring an array means that the right memory space is reserved for you. Declaring a pointer reserves only the space to store a memory address. FoP & PP 14 7
Pointer arithmetic It is allowed to do arithmetic operations with a pointer like increment, add an integer value,etc. The new calculated address where the pointer refers to depends on the data type used for the pointers definition. Example: int pointer ip (int *ip), int uses 4 byte memory space, assumption: ip refers to addr FFFF0000 doing increment ip++ => pointer ip refers then to FFFF0004 FoP & PP 15 Pass by reference If we pass arguments to a function we can also use pointers as arguments. Called pass by reference. In our function we use the dereference * parameter in order to access the value which is stored under the address where the argument (pointer) refers to. => Allows us to return multiple function results via the arguments. FoP & PP 16 8
Task 9 A program should add two vectors x,y (length 3). This should be done by a function addvec with 3 arguments: - v1: reference to the first vector - v2: reference to the second vector - n: number of elements in the vector The result (sum of the vectors) should be stored in the array where v1 refers to. FoP & PP 17 Request for memory during runtime What can we do if our program must be able deal with a variable amount of data? We request new memory during runtime! Can be done by the function: void *malloc(size_t size); Function reserves a continguos memory area of size bytes and returns a void pointer to the new memory. Memory can be released by function free FoP & PP 18 9
Sizeof Used memory space of a variable depends on data type and machine architecture. How can I determine the space of memory which is used for a special data type? Answer: sizeof operator. The sizeof (data type) returns the number of bytes used for that data type. Example : sizeof (char)=> 1 sizeof (int) => 2 or 4 (depends on architecture) FoP & PP 19 Request for memory to store n characters int main() unsigned int i,n; // no init => random value; char *cp; // no init => points to anywhere printf( How many character values: ); scanf( %d,&n); cp = (char*)malloc(sizeof(char)*n); for(i=0;i < n; i++) printf( \nnext char: ); scanf( %c,(cp+i)) //could be also cp[i] printf("\nchar[0]:%c, char[%d]:%c",*cp,n-1,*(cp+n-1)); FoP & PP 20 10
Structures A collection of related variables of the same and or/different data types. Declaration example for a point which is specified by x,y,z coordinates and a color struct point int x,y,z; //coordinates unsigned char color; //256 colors possible ; FoP & PP 21 Definition of new data types C allows the definition of new data types by use of typedef. Useful because new data types can be treated like normal data types. Example: typedef struct int x,y,z; unsigned char R,G,B; point; //new data type point is defined //declare variable apoint and a pointer pp point apoint, *pp; point.x = 5; point.y = 6; point.z = 7; FoP & PP 22 11
Task 10 Write a program which is able to handle exam results by use of an array of structures. The data for an exam are: - Mark: 0.7-5.0 - Exam identifier : simple number 6 digits - Matriculation-No.: simple number 6 digits Requirements: The program asks for the number of exams Declare a structure exam which contains (Mark, Exam-ID, Matr) The program reserves memory via malloc in dependency of the number of exams The program aks for all exams all data (Mark, Exam-ID, Matr) The program determines the number of passed (Mark <= 4.0) exams. FoP & PP 23 Task 11 A program should be created which is able to sort points regarding its x-coordinates. A point is defined by its x,y,z coordinates and its color (R,G,B values). - The user is asked how many points he wants to enter. - For every point the coordinates must be entered - The color values of a new point are initialized - The sorted list of points is printed FoP & PP 24 12
Strings C does not have an own String datatype Implemented as array of characters A constant string is enclosed in double quotes like Hello The end of the string is determined by the NULL character \0. Must be considered as an additional char (array length). VERY IMPORTANT because it is required for all string functions FoP & PP 25 String Example char mystr[] = Hello //requires 6 chars is equal to char mystr[6] = Hello ; is equal to char mystr[6] = H, e, l, l, o, \0 ; NULL character determines end of string FoP & PP 26 13
Strings and Pointer Because pointer and arrays have a close relation, pointer are often used together with strings. Example: char str[]= Hello students ; char *strp; strp = str; //strp refers now to str //print out Hello students printf( %s,strp); //print out llo students ; printf( %s,strp+2); //print out s, s printf %c, %c, strp[6],str[6]); FoP & PP 27 String operations Typical string operations are: Get the length of a string Copy a string into another Concatenate two strings Find a char or a substring within a string Compare two strings Functions doing all these are available in string.h FoP & PP 28 14
strlen size_t *strlen(const char* str) string length returns the length of the string. The terminating null character \0 is not counted. size_t is typically defined as unsigned int. Example: char source[] = Hello ; int i; i = strlen(source); //i = 5 FoP & PP 29 strcpy char *strcpy(char * dest, const char* src) string copy copies the string pointed to by src into the array pointed to by dest. The array pointed by dest must be large enough to contain the same C string as src (including the terminating null character ( \0 ). Example: char source[] = World ; char dest[6] ; strcpy(dest, source); // dest is now World // altogether 6 characters including \0 FoP & PP 30 15
strcat char *strcat(char * dest, const char* src) string concatenate appends a copy of source (src) to the destination string (dest). The array pointed by dest must be large enough to contain both the orginal source string and the destination string. Example: char source[]= Students ; char dest[15] = Hello ; strcat(dest, source); //dest is now Hello Students //(15 chars including \0 ) FoP & PP 31 strchr, strstr char *strchr(const char str*, int c) string character returns a pointer to the first appearance of c in str or a null pointer if c does not appear in str char *strstr(const char *s1, const char *s2) string in string returns a pointer to the first occurrence of s2 in s1, or a null pointer if s2 is not part of s1. FoP & PP 32 16
strcmp int strcmp(const char *s1, const char *s2) string compare compare the string s1 with s2. A zero value indicates that both strings are equal. A value greater than zero indicates that the first character that does not match has a greater value in s1 than in s2. For example: aab is larger than aaa A value less than zero indicates the opposite. FoP & PP 33 Task 12 A program should allow the user to enter two strings s1 and s2. This two strings should then combined together to a new string s12. The array for the new string should have exactly the right length. Then the user can enter a third string s3. It should be checked if the string s3 is part of the new string s12. FoP & PP 34 17
Programming style Use spaces in source code (easier to read) Use BlockCodes Descriptive names for variables and use CamelCase. Example: (int nrofadders) Initialize your variables Use constant or defines for fixed values Use comments Avoid long lines and complex statements FoP & PP 35 18
#include <stdio.h> //Task 8 #include <stdlib.h> #define ARR_MAX 3 int compveclen(int v1[], int v2[], int n) long v1len = 0, v2len= 0; for (--n; n >=0; n-- ) v1len = (long)v1[n] * (long)v1[n] + v1len; v2len = (long)v2[n] * (long)v2[n] + v2len; if (v1len == v2len) return 0; if (v1len > v2len) return 1; return 2; //v1len < v2len int main() int v1arr[arr_max],v2arr[arr_max], i=0; char coch[] = '=','>','<' ; do printf("\nplease, input x%d:",i+1); scanf("%d",&v1arr[i]); fflush(stdin); printf("please, input y%d:",i+1); scanf("%d",&v2arr[i]); fflush(stdin); while(++i < ARR_MAX); i = compveclen(v1arr, v2arr, ARR_MAX); printf("\n V1 %c V2 ",coch[i]); return EXIT_SUCCESS; 15
//Task 9 #include <stdio.h> #include <stdlib.h> #define ARR_MAX 3 void addvec(int *v1, int *v2, int n) while(--n >=0) v1[n] = v1[n] + v2[n]; //*(v1+n) = *(v1+n) + *(v2+n); //*(v1) = *v1 + *v2; v1++; v2++; int main() int v1arr[arr_max],v2arr[arr_max], i=0; do printf("\nplease, input x%d:",i); scanf("%d",&v1arr[i]);fflush(stdin); printf("please, input y%d:",i); scanf("%d",&v2arr[i++]);fflush(stdin); while(i < ARR_MAX); addvec(v1arr, v2arr, ARR_MAX); printf("\nsum of x,y ="); for (i=0; i < ARR_MAX; i++ ) printf("%d, ",v1arr[i]); return EXIT_SUCCESS; 2
// Task 10 #include <stdio.h> #include <malloc.h> #include <stdlib.h> typedef struct float mark; unsigned long examident, matr; exam; int main() unsigned int i,n, cp=0; exam *pexam; printf("how many exams :"); scanf("%d",&n); pexam = (exam*)calloc(n, sizeof(exam)); for(i=0;i < n; i++) printf("\nexam(%d) mark:",i+1); fflush(stdin); scanf("%f",&pexam[i].mark); printf("exam(%d) examident:",i+1); flush(stdin); scanf("%d",&pexam[i].examident); printf("exam(%d) Matriculation:",i+1); fflush(stdin); scanf("%d",&pexam[i].matr); if (pexam[i].mark <= 4.0) cp++; printf("\nnumber of passed exams:%d",cp); free(pexam); 4
// Task 11 typedef struct int x,y,z; unsigned char R,G,B; point; void sortp(point *parr, int n) int i,j; point temp; for (i=0;i < n-1; i++) for (j=i+1; j < n; j++) if(parr[i].x > parr[j].x) temp = parr[i]; parr[i] = parr[j]; parr[j] = temp; int main() unsigned int i,n; point *pp; printf("how many point values:"); scanf("%d",&n); pp = (point*)calloc(n, sizeof(point)); for(i=0;i < n; i++) printf("point x,y,z:"); fflush(stdin); scanf("%d,%d,%d",&pp[i].x,&pp[i].y,&pp[i].z ); sortp(pp,n); for (i=0; i< n; i++) printf("\npt[%d]:%d,%d,%d",i,pp[i].x,pp[i].y,pp[i].z); free(pp); 6
// Task 12 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> int main() char buffer[1024], *str[3], *str12; unsigned int i,strl; for(i=0; i < 3; i++) printf("\ninput s%d:",i+1); fflush(stdin); scanf("%s",buffer); strl = strlen(buffer)+1; str[i] = (char*)malloc(sizeof(char) * strl); strcpy(str[i], buffer); strl = strlen(str[0]) + strlen(str[1])+1; str12= (char*)(malloc(strl * sizeof(char))); strcpy(str12,str[0]); strcat(str12,str[1]); printf("\n\nnew s12 is:%s",str12); if (strstr(str12,str[2])!=null) printf("\ns3 is part of s12"); else printf("\ns3 is not part of s12"); 8