Download presentation
Presentation is loading. Please wait.
Published byEustacia Noreen Farmer Modified over 9 years ago
1
CSCI 171 Presentation 11 Pointers
2
Pointer Basics
3
Why use pointers? Some routines can be more efficiently written with pointers Some routines need pointers
4
Memory Usage Programmer declares a variable int x; Compiler sets aside memory 4 bytes for an integer Memory has a unique address Address and variable name are associated Address is hidden from the programmer
5
Memory Address Address is an integer Can be printed out with %p –result represents a segment and an offset what segment of memory the location is in what offset (how far from the start of the segment) the location is –Most compilers show the two separated by a colon –Code Warrior does not
6
Pointers Address can be stored in another variable –pointer Pointer - variable that contains the address of another variable
7
Using Pointers Pointers must be declared before use Names must be unique Declaration: typename * ptrname; int * x; * - Indirection operator –Informs the compiler that the variable is a pointer
8
Initializing Pointers Pointers must be initialized –Always initialize pointers to NULL –int * ptr = NULL; –Symbolic constant for 0 Impossible to know what uninitialized pointers are pointing to –could be anywhere in memory
9
Address of Operator & - address of operator int x = 3; &x is interpreted as ‘the address of x’ Sample code: int x = 3; int * y = NULL; y = &x;
10
Using Pointers Once a pointer has been declared and initialized it can be used When indirection operator (*) precedes a pointer, it refers to the contents of the variable to which it points
11
Using Pointers - Example int x = 3; int *y = NULL; y = &x; printf(“%d”, *y); The preceding code results in 3 printed to the screen
12
Accessing Information Definitions Direct Access - accessing contents of a variable using the variable name Indirect Access - accessing the contents of a variable by using a pointer to the variable
13
Accessing Information Assume ptr is a pointer variable that points to the variable var –*ptr and var each refer to the contents of var –ptr and &var each refer to the address of var
14
Using Pointers - Example int x = 3, *y = NULL; y = &x; printf(“%d”, x); printf(“%d”, *y); printf(“%p”, &x); printf(“%p”, y); } Equivalent Statements } Equivalent statements
15
Arrays and Pointers The name of an array is a pointer to the array –points to the first byte of the first element –remains fixed throughout program execution Example: if int x[10] is an array declaration, then x and &x[0] are equivalent both represent the addresses of the first array element
16
Arrays and Pointers Consider the following code: int array[3] = {1, 2, 3}, *ptr = NULL, z=2; ptr = array; –array points to the first element in the array cannot be changed array = &z; causes a compiler error –ptr points to the first element in the array can be changed ptr = &z; does not cause a compiler error
17
Pointer Arithmetic Pointers are often manipulated arithmetically –incremention –decrementation The compiler ‘knows’ the size of a data type, and will increment the address accordingly –adding 1 to an integer pointer increments the address by 4 integers take up 4 bytes of space
18
Using pointer arithmetic - Ex. 1 Print out the contents of a 10 element integer array using pointer arithmetic int main( void ) { int x[10] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}, *y = NULL, count; y = x; for (count = 0; count < 10; count++) printf("%d ", *y++); }
19
Using pointer arithmetic - Ex. 2 #include int main( void ) { int x[5] = {2, 4, 6, 8, 10}, *y = NULL, count = 0; char a[5] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’}, *b = NULL; y = x; b = a; for (count = 0; count < 5; count++) { printf("\n%d ", *y++); //incrementing y increments the pointer 4 bytes printf("\n%c ", *b++);//incrementing b increments the pointer 1 byte }
20
Other pointer arithmetic Incrementation, decrementation are valid +, - must be an integer (compiler error if not) Other arithmetic is not valid *, /, %, etc.
21
Valid Pointer Operations
22
Pointers and Functions Arrays cannot be passed into functions, but pointers can –In our programs when we pass in an array, we have actually passed in a pointer Prototype of a function that accepts an array int func1(int []); int func1(int x[]); int func1(int *x); } Almost equivalent, only difference is the first does not specify variable name
23
Sample Program #include void changeInt(int *); int main( void ) { int *ptr = NULL, var = 0; ptr = &var; changeInt(ptr); printf("The variable ptr is pointing to: %d", *ptr); return 0; } void changeInt(int * argPtr) { *argPtr = 11; }
24
Characters, strings, and an introduction to dynamic memory allocation
25
Strings arrays of characters char string[10]; string: array of characters ending with the null character –null character: ‘\0’ To store ‘Computer’ in a string, need an array of 9 characters (8 for the letters, one for the null character)
26
String Initialization Strings can be initialized many ways: char string1[10] = “Hello”; char string2[6] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’}; char string3[] = “Hi”; What is the output of the following? printf(“%d %d %d”, sizeof(string1), sizeof(string2), sizeof(string3); Answer: 10 6 3
27
String / Pointer Relationship Recall: Array name is a pointer to the first element in the array Character array is a pointer to the first element in an array –i.e. the beginning of the string ‘\0’ indicates the end of the string Array size is incidental Array name, and ‘\0’ give us all the information we need
28
String / Pointer Relationship
29
Allocating Strings Strings can be allocated without actually declaring an array –Only the pointer to the first character and the ‘\0’ is needed Example: char * msg = “Hello”;is equivalent to: char msg[] = “Hello”;
30
Dynamic Allocation of Strings Dynamic memory allocation –allocating memory ‘on the fly’ –memory allocated at program execution time –using the malloc( ) function is one way to do this Always include Example: char *ptr = NULL; ptr = malloc(5);
31
malloc( ) function returns an address –pointer to type void –can store any of C’s data types accepts an integer parameter allows for more efficient memory usage
32
Possible errors with malloc( ) If there is not enough memory for malloc( ) to complete the request, malloc( ) returns null Return value should ALWAYS be checked
33
Sample code using malloc( ) #include int main( void ) { char *ptr = NULL; ptr = malloc(10); if (ptr = = NULL) printf("Memory not allocated"); else printf("Successful allocation of memory"); return 0; }
34
Sample code using malloc( ) #include int main( void ) { char *ptr = NULL; if ((ptr = malloc(10)) = = NULL) printf("Memory not allocated"); else printf("Successful allocation of memory"); return 0; }
35
Sample code using malloc( ) Structured example #include int main( void ) { char *ptr = NULL; if ((ptr = (char *)malloc(10 * sizeof(char))) = = NULL) { printf("Memory not allocated"); exit(1); } //Code continues from this point return 0; }
36
Displaying Strings - puts( ) puts( ) accepts a pointer to a string –string literal evaluates as a pointer to a string prints the string to the screen automatically inserts new line character at end of string Example: char * name = “CSCI 131”; puts(name); puts(“this is a string literal”);
37
Displaying Strings - printf( ) %s is the string conversion specifier Example: char * ptr = "Hello"; printf("%s", ptr); printf("%s\n%s", ptr, "there");
38
Accepting strings from keyboard Two options –gets( ) –scanf( )
39
Accepting strings - gets( ) Reads all characters up to first new line Discards new line, adds ‘\0’ to end Returns value as a string (ptr to type char)
40
Accepting strings - gets( ) Example: #include int main( void ) { char name[15]; printf(“Enter your name\n”); gets(name); }
41
Accepting strings - scanf( ) Reads all characters up to first occurrence of whitespace Adds ‘\0’ to end Returns value as a string (ptr to type char)
42
Accepting strings - scanf( ) Sample code: puts(“Enter your name”) scanf(“%s”, x);
43
Can scan a specific number of characters Sample code (scans first 3 characters): puts(“Enter your name”) scanf(“%3s”, x);
44
gets( ) verses scanf( ) gets( ) is good when entering text scanf( ) is useful when entering text and numeric values, or just numeric values
45
Memory management and more advanced dynamic memory allocation
46
Type Casting Consider the following code: #include int main( void ) { int i = 3, j = 2; float z = 0.0; z = i / j; printf("%f", z); } Output: 1.000000
47
Type Casting Solving the problem on the previous slide: #include int main( void ) { int i = 3, j = 2; float z = 0.0; z = (float)i / (float)j; //Typecast the i and j to floats printf("%f", z); } Output: 1.500000
48
Casting Pointers #include int main( void ) { void * x = NULL; int p = 3; (int *)x = &p;//Type casting the void pointer to a //integer pointer printf("%d", *(int *)x);//Type casting and dereferencing return 0; }
49
Memory Allocation Static allocation –explicitly allocating memory in source code –allocation determined at compile time Dynamic allocation –allocating memory at run time occurs during program execution
50
Memory Allocation functions stdlib.h file Allocating and freeing memory –malloc( ) –calloc( ) –realloc( ) –free( )
51
malloc( ) function revisited returns an address –pointer to type void –can store any of C’s data types accepts an integer parameter allows for more efficient memory usage malloc( ) is not restricted to character arrays should cast the returned pointer
52
malloc( ) example #include int main( void ) { int *x = NULL, y = 0, i = 0; printf("Enter the number of elements for an array: "); scanf("%d", &y); if (x = (int *)malloc(y*(sizeof(int))) = = NULL) printf("Memory not allocated"); exit(1); } for (i = 0; i < y; i++) *(x+i) = 0;//Can access the elements using //pointer arithmetic for (i = 0; i < y; i++) printf("%d", x[i]);//Can access the elements using }//array notation
53
calloc( ) function similar to malloc accepts 2 parameters –number of objects –bytes per object clears allocated memory –initializes to binary 0 returns a type void pointer –return value should be cast
54
Sample code using calloc( ) #include int main( void ) { int *ptr = NULL; if ((ptr = (int *)calloc(10, (sizeof(int)))) = = NULL) { printf("Memory not allocated"); exit(1); } printf("Successful allocation of memory"); return 0; }
55
realloc( ) function Changes size of memory block allocated by malloc( ) or calloc( ) Accepts 2 parameters –pointer –new size (in bytes) Functionality depends on several factors
56
realloc( ) functionality 1. Current space can be expanded –space is allocated, original pointer is returned 2. Current space cannot be expanded –new block is allocated –existing data is copied from old to new block –old block is freed –pointer to new block is returned
57
realloc( ) functionality 3. pointer argument is NULL –function acts like malloc( ) 4. argument size is 0 –memory pointer argument points to is freed –function returns NULL 5. memory cannot be allocated –function returns NULL –original block unchanged
58
Sample code using realloc( ) #include int main( void ) { int *ptr = NULL; if ((ptr = (int *)calloc(10, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } else printf("Successful allocation of memory"); if ((ptr = (int *)realloc(ptr, 50*sizeof(int))) == NULL) { printf("\nMemory reallocation unsuccessful"); exit(1); } else printf("\nSuccessful reallocation of memory"); return 0; }
59
free( ) function When dynamically allocated memory is no longer needed, the resources should be freed –amount of memory available for allocation is finite Passing the pointer to the free( ) function will free up memory free( ) function –accepts a pointer as an argument –has no return value (i.e. void)
60
Sample code using free( ) #include int main( void ) { int *ptr = NULL; if ((ptr = (int *)calloc(10, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } else printf("Successful allocation of memory"); free(ptr); return 0; }
61
Memory Leaks #include int main( void ) { int *ptr = NULL; if ((ptr = (int *)calloc(10, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } //Code using ptr would go here if ((ptr = (int *)calloc(12, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } //More code using pointer would go here return 0; }
62
Avoiding Memory Leaks #include int main( void ) { int *ptr = NULL; if ((ptr = (int *)calloc(10, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } //Code using ptr would go here free(ptr); if ((ptr = (int *)calloc(12, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } //More code using pointer would go here return 0; }
63
Avoiding Memory Leaks #include int main( void ) { int *ptr = NULL; if ((ptr = (int *)calloc(10, sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } //Code using ptr would go here if ((ptr = (int *)realloc(ptr, 48*sizeof(int))) == NULL) { printf("Memory not allocated"); exit(1); } //More code using pointer would go here return 0; }
64
Passing Values to Functions Passing by Value –Changes to the parameter do not affect changes to the argument Passing by Reference –Arrays, pointers –Changes to the parameter do affect changes to the argument
65
Passing by Value x = 5; myFunction(x) –causes a copy of x to be made, and accessible to the function Changes at addresses 2018-2021 do not affect the contents of addresses 1000-1003
66
Passing by Reference Used with arrays and pointers myFunction(&x) –causes the address of x to be passed to the function Changes are made at the address (1000), and hence changes made in the function are reflected in the calling function
67
Why pass by Reference? If you need to modify the argument (i.e. if you need to modify the value of the variable in the calling program within the function) If you are using arrays
68
Passing by Reference Passing by reference Advantage: The function can modify the value of the argument Disadvantage: The function can modify the value of the argument Passing by reference should be avoided unless there is a specific reason for doing it
69
Passing by Value Ex: #include void changeVal(int); main( void ) { int x = 3; changeVal(x); printf("\nx in the main function is: %d", x); } void changeVal(int x) { x = x * 6; printf("x in the changeVal function is: %d", x); }
70
Passing by Reference Ex 1: #include void changeVal(int *); main( void ) { int x = 3; changeVal(&x); printf("\nx in the main function is: %d", x); } void changeVal(int * x) { *x = *x * 6; printf("x in the changeVal function is: %d", *x); }
71
Passing by Reference Ex 2: #include void changeVal(int []); main( void ) { int x[2] = {3, 6}; changeVal(x); printf("\nx in the main function is: %d %d", x[0], x[1]); } void changeVal(int x[]) { x[0] = x[0] * 2; x[1] = x[1] * 2; printf("x in the changeVal function is: %d %d", x[0], x[1]); }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.