logging in or signing up C++ Program VIVEKAVC Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINT lite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 21 Category: Education License: All Rights Reserved Like it (0) Dislike it (0) Added: September 17, 2011 This Presentation is Public Favorites: 0 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Pointers, Arrays, and Dynamic Memory: Pointers, Arrays, and Dynamic MemoryPointer Variables: Pointer Variables A pointer is a variable whose value is the address of another variable . The size of the pointer variable must be n bits where 2 n bytes is the size of the address space.Pointer Variables: Pointer Variables Allow C programs to simulate call-by-reference Allow a programmer to create and manipulate dynamic data structures. Must be defined before it can be used. Should be initialized to NULL.Declaring a Pointer Variable: Declaring a Pointer Variable To declare a pointer in a program just use the type it points to followed by * . <type> * variableName; e.g. char *phrase; int *xPtr; phrase and xPtr are the names of variables The * informs the compiler that we want a pointer variable, i.e. to set aside however many bytes is required to store an address in memory.Pointers: Pointers A pointer variable has two associated values: Direct value address of another memory cell Referenced by using the name of the variable Indirect value value of the memory cell whose address is the pointer's direct value. Referenced by applying the indirection *Pointer Variables: Pointer Variables To refer to the entity to which the pointer points prepend *, the indirection (or dereferencing) operator *xPtr = 10; stores the value 10 in the address pointed to by xPtr. in this case, 10 is stored in x, since xPtr points to xPointer Operators: Pointer Operators * operator - indirection operator or dereferencing operator. - returns a synonym, alias or nickname to which its operand points. & operator - address operator - returns the address of its operand.Pointer Variables: Pointer Variables One way to store a value in a pointer variable is to use the & operator. int x = 5; int *xPtr = &x; The address of x is stored in xPtr. We say, xPtr points to x .Pointer Variables: Pointer Variables int x = 5; Assume x is stored in memory at location 300000 and y is stored at location 700000 300000 The statement, int *xPtr = &x; causes the address of x to be stored in xPtr 700000 5 300000 x xPtrPointer Variables: Pointer Variables We represent this graphically as 5 x xPtrPointer Variables: Pointer Variables The indirection (dereferencing) operator is * *xPtr = 10; stores the value 10 in the address pointed to by xPtr. 10 x xPtrPointer Variables: Pointer Variables Notice that the character * is used in two ways: To declare that a variable is a pointer. To access the location pointed to by a pointer. Prepending a variable with a * in a declaration declares that the variable will be a pointer to the indicated type instead of a regular variable of that type. Prepending a variable with a * in an expression indicates the value in the location pointed to by the address stored in the variable.Pointers and Dynamic Allocation of Memory: Pointers and Dynamic Allocation of Memory So far, we have always allocated memory for variables in the function data areas that are located on the stack. Size of such variables must be known at compile time. There are times when it is convenient to allocate memory at run time using malloc() , calloc() , or other allocation functions.Pointers and Dynamic Allocation of Memory: Pointers and Dynamic Allocation of Memory The system maintains a second storage area called the heap Permits postponing the decision on the size of the memory block needed to store an array Or permits using a section of memory for the storage of an array at one point in time, and then when that memory is no longer needed it can be freed up for other uses.Pointers and Dynamic Allocation of Memory: Pointers and Dynamic Allocation of Memory When memory is allocated, the allocating function (such as malloc() , calloc() , etc.) returns a pointer of type void (depending on the compiler). void * indicates a pointer to untyped memory Will have to cast the returned value to the specific type needed. We should always release allocated space when no longer needed, so that it can be reused.Initializing Pointers: Initializing Pointers Like all variables pointers must be initialized before they are used. /* pointer1.c */ /* Example of a common error: failure to intialize */ /* a pointer before using it.. This program is */ /* is FATALLY flawed.... */ int main() { int* ptr; *ptr = 99; printf("val of *ptr = %d and ptr is %p \n", *ptr, ptr); return 0; } ptr has not been initializedInitializing Pointers: Initializing Pointers To minimize pointer problems Never declare a pointer without intializing it in the declaration. int *ptr = NULL; Never use NULL as a synonym for integer or float 0.Using gdb to find the point of failure: Using gdb to find the point of failure The gdb debugger is a handy tool for identifying the location at which a program failed. To use the debugger it is necessary to compile with the g option. lowerm@shadow[117] gcc -g pointer1.c -o p1.o To start the debugger use the gdb command and specify the program name lowerm@shadow[117] gdb p1.oUsing gdb to find the point of failure: Using gdb to find the point of failure At the (gdb) prompt you will usually want to tell the debugger to halt the program when it reaches the start of the main() function. The b command is short for breakpoint and tells the debugger where to stop. After a function is entered source code line numbers can be used to specify breakpoints. (gdb) b main Breakpoint 1 at 0x10604: file pointer1.c, line 11.Using gdb to find the point of failure: Using gdb to find the point of failure To start the program use the run command: (gdb) run Starting program: /users/lowerm/public_html/cs101/examples/p.o When the program reaches a breakpoint gdb will tell you and display the next line of code to be executed. Breakpoint 1, main () at pointer1.c:11 11 *ptr = 99; // ptr has not been initializedUsing gdb to find the point of failure: Using gdb to find the point of failure Use the next command to execute a single source statement. The next command will treat a function call as a single statement and not single step into the function being called. If you want to single step through the function use the step command to step into it. The output of the printf() is intermixed with gdb's output and is shown in blue below. (gdb) next pointer is 0 12 *ptr = 99;Using gdb to find the point of failure: Using gdb to find the point of failure Saying next again will cause the program to execute the flawed assignment. gdb will show you the line that caused the error (line # 12). (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x00010620 in main () at p18.c:12 12 *ptr = 99;Using gdb to find the point of failure: Using gdb to find the point of failure The where command can show you where the failure occured (along with a complete function activation trace. (gdb) where #0 0x00010620 in main () at pointer1.c:12 (gdb) To print the value of a variable use the print command. (gdb) print ptr $1 = (int *) 0x0Using gdb to find the point of failure: Using gdb to find the point of failure Attempting to print what ptr points to reaffirms what the problem is: (gdb) print *ptr Cannot access memory at address 0x0 Use the q (quit) command to terminate gdb (gdb) quit The program is running. Exit anyway? (y or n) y lowerm@shadow7[126]Correct use of the pointer: Correct use of the pointer In the C language, variables that are declared within any basic block are allocated on the runtime stack at the time the basic block is activated. /* pointer2.c */ main() { int y; int* ptr; static int a; ptr = &y; // assign the address of y to the pointer *ptr = 99; // assign 99 to what the pointer points to (y) printf("y = %d ptr = %p addr of ptr = %p \n", y, ptr, &ptr); ptr = &a; printf("The address of a is %p \n", ptr); }Correct use of the pointer: Correct use of the pointer lowerm@shadow[130] ./p2.o x = 99 ptr = ffbff05c addr of ptr = ffbff058 The address of a is 208e0 Note that a is heap resident and has an address far removed from the stack resident y and ptr.Use of pointers in processing Cstrings: Use of pointers in processing Cstrings Recall that a “Cstring” is an array of characters whose logical end is denoted by a zero valued byte. The C standard library has a number of functions designed to work with C strings. The strtok() function is one of them. You can see most of them on a Solaris system via the command: man -s 3C string string, strcasecmp, strncasecmp, strcat, strncat, strlcat, strchr, strrchr, strcmp, strncmp, strcpy, strncpy, strlcpy, strcspn, strspn, strdup, strlen, strpbrk, strstr, strtok, strtok_r - string operationsUse of pointers in processing Cstrings: Use of pointers in processing Cstrings In this example we will see how strcat might be implemented. Its prototype is shown below. char *strcat(char *s1, const char *s2);An implementaton of strcat: An implementaton of strcat The name zstrcat is used to avoid potential name conflicts with the “real” strcat. #include <stdio.h> #include <error.h> /* The mission of this function is to concatenate */ /* the string pointed to by p2 to the end of */ /* the string pointed to by p1 */ char *zstrcat(char *p1, char *p2) { char *src; /* source pointer */ char *dest; /* destination pointer */ dest = p1; src = p2; /* Start by advancing dest to the end of the string to be extended */ while (*dest != 0) dest = dest + 1; /* Now tack on the string to be appended */ while (*src != 0) { *dst = *src; dest = dest + 1; src = src + 1; } /* Complete the job by NULL terminating the new string */ *dest = 0; return(p1); }An alternate implementaton: An alternate implementaton The following approach produces code that is difficult to read, painful to maintain, but may (or may not) produce a trivial improvement in performance . When tempted, just say no! char *zstrcat(char *p1, char *p2) { char *r = p1; while (*p1++); p1--; while (*p1++ = *p2++); return(r); }An alternate implementaton: An alternate implementaton main() { char *s1; char *s2; char *result; s1 = (char *)malloc(40); s2 = (char *)malloc(40); result = (char *)malloc(81); *result = 0; fgets(s1, 40, stdin); fgets(s2, 40, stdin); zstrcat(result, s1); zstrcat(result, " "); zstrcat(result, s2); fputs(result, stdout); } Hello World Hello WorldPointer Variables and Arrays: Pointer Variables and Arrays Given int *ptr; *ptr = 7; the compiler will know how many bytes to copy into that memory location pointed to by ptr . defining the type that the pointer points to permits a number of other interesting ways a compiler can interpret code.Pointer Variables and Arrays: Pointer Variables and Arrays Consider a block in memory consisting of ten integers in a row. That is, 40 bytes of memory are set aside to hold 10 integers. Now, set ptr to point to the first of these integers. Suppose the integer is located at memory address 20918. What happens when we write: ptr = ptr + 1; Because the compiler "knows" this is a pointer (i.e. its value is an address) and that it points to an integer (current address, 20918 it adds 4 to ptr instead of 1, so the pointer "points to" the next integer , at memory locationPointer Variables and Arrays: Pointer Variables and Arrays Since a block of 10 integers located contiguously in memory is, by definition, an array of integers, this brings up an interesting relationship between arrays and pointers.Pointer Variables and Arrays: Pointer Variables and Arrays Consider the following: int my_array[ ] = {1, 23,17,4,-5,100}; Here we have an array containing 6 integers. We refer to each of these integers by means of a subscript to my_array , i.e. using my_array[0] through my_array[5] .Pointer Variables and Arrays: Pointer Variables and Arrays The name of an array and the address of the first element in the array represent the same thing; consequently, we could alternatively access them via a pointer as follows: int *ptr; ptr = &myArray[0]; /* points to the first integer in the array */ Then we could print out our array either using the array notation or by dereferencing our pointer.Pointer Variables and Arrays: Pointer Variables and Arrays Since the name of an array is a pointer constant to the first element of the array; therefore, we could also use the following: ptr = myArray;Pointer Arithmetic and Arrays: Pointer Arithmetic and Arrays If ptr is pointing to a specific element in an array, ptr + n is the pointer value n elements away. The following two expressions are exactly the same when array is the name of an array and n is an integer: *(array + n) array[n]Using a one-dimensional array to represent 2-D data: Using a one-dimensional array to represent 2-D data Suppose the integer variables numRows and numCols represent the number of rows and columns in an image and that they have been correctly set using information in the .ppm header. Grayscale images Space for a grayscale image encoded in binary can be allocatged by: unsigned char *image; image = (unsigned char *) malloc(numRows * numCols);Using a one-dimensional array to represent 2-D data: Using a one-dimensional array to represent 2-D data To read in the grayscale image from the standard input: pixelCount = fread(image, 1, numRows * numCols, stdin); if(pixelCount != numRows * numCols) { fprintf(stderr, "pixel count err – expected %d got %d\n", numRows * numCols, pixelCount); exit(1); }Accessing a specific element in a malloc'd 2-D data: Accessing a specific element in a malloc'd 2-D data The value of any grayscale pixel at location (row, col) within the image is accessed in the following way: pixel = *(image + row * numCols + col) or equivalently pixel = image[row * numCols + col); For example, if the value of numCols is 7, then there are 7 pixels per image row. To reach the pixel whose (row, column) address is (3, 5) it is necessary to pass over three complete rows and 5 pixels in row three. The offset of the pixel at (3,5) is 3 * 7 + 5 as shown aboveProcessing an image one row at a time: Processing an image one row at a time for (row = ; row < numRows; row++) { unsigned char *location; location = image + row * numCols; // first pixel in row printf("\n"); for(col = 0; col < numCols; col++) { printf("%03x", *location); location = location + 1; } }Processing an image one row at a time: Processing an image one row at a time An equivalent method that uses array notation: for (row = 0; row < numRows; row++) { printf("\n"; for(col = 0; col < numCols; col++) { printf("%03x", image[row * numCols + col]); location = location + 1; } }Color Images: Color Images A color image is often called an rgb image because the red, green, and blue intensities of each pixel are stored together. Space for a color image in binary rgb format can be allocated by: unsigned char* image; image = (unsigned char *) malloc (3 * numrows * numcols ); To read in the rgb image: pixcount = fread ( imageloc , 3, numrows * numcols , stdin ); if ( pixcount != numrows * numcols ) { fprintf ( stderr , “pix count err - wanted %d got %d \n”, numrows * numcols , pixcount ); exit(1); }Accessing the Individual Pixels of the Binary RGB Image: Accessing the Individual Pixels of the Binary RGB Image Here the process is slightly more complex because each pixel is represented by three constituent components (r, g, and b) where each of (r, g, and b) are represented by a single unsigned char. Nevertheless a bit of reflection yields: red = *(image + 3 * row * numcols + 3 * col ); green = *(image + 3 * row * numcols + 3 * col + 1); blue = *(image + 3 * row * numcols + 3 * col + 2); or equivalently red = image[3 * row * numcols + 3 * col ]; green = image[3 * row * numcols + 3 * col + 1]; blue = image[3 * row * numcols + 3 * col + 2]; It is necessary to muliply by 3 because each pixel occupies three bytes of memory.Functions that Modify Variables of Their Callers: Functions that Modify Variables of Their Callers When a function tries to modify a parameter that is passed to it, it has no effect on the callers copy of that variable. A caller can allow a function to modify its variables by passing a pointer to the value:Functions that Modify Variables of Their Callers: Functions that Modify Variables of Their Callers #include < stdio.h > int getDims ( int * numcols , int * numrows ) { int main( ) { int rows; int cols; getdims (&cols, &rows); fprintf ( stdout , “rows = %d cols = %d \n”, rows, cols); }Functions that Modify Variables of Their Callers: Functions that Modify Variables of Their Callers int getDims ( int * numcols , int * numrows ) { fscanf ( stdin , "%d %d", numcols , numrows ); } You do not have the permission to view this presentation. In order to view it, please contact the author of the presentation.
C++ Program VIVEKAVC Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINT lite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 21 Category: Education License: All Rights Reserved Like it (0) Dislike it (0) Added: September 17, 2011 This Presentation is Public Favorites: 0 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Pointers, Arrays, and Dynamic Memory: Pointers, Arrays, and Dynamic MemoryPointer Variables: Pointer Variables A pointer is a variable whose value is the address of another variable . The size of the pointer variable must be n bits where 2 n bytes is the size of the address space.Pointer Variables: Pointer Variables Allow C programs to simulate call-by-reference Allow a programmer to create and manipulate dynamic data structures. Must be defined before it can be used. Should be initialized to NULL.Declaring a Pointer Variable: Declaring a Pointer Variable To declare a pointer in a program just use the type it points to followed by * . <type> * variableName; e.g. char *phrase; int *xPtr; phrase and xPtr are the names of variables The * informs the compiler that we want a pointer variable, i.e. to set aside however many bytes is required to store an address in memory.Pointers: Pointers A pointer variable has two associated values: Direct value address of another memory cell Referenced by using the name of the variable Indirect value value of the memory cell whose address is the pointer's direct value. Referenced by applying the indirection *Pointer Variables: Pointer Variables To refer to the entity to which the pointer points prepend *, the indirection (or dereferencing) operator *xPtr = 10; stores the value 10 in the address pointed to by xPtr. in this case, 10 is stored in x, since xPtr points to xPointer Operators: Pointer Operators * operator - indirection operator or dereferencing operator. - returns a synonym, alias or nickname to which its operand points. & operator - address operator - returns the address of its operand.Pointer Variables: Pointer Variables One way to store a value in a pointer variable is to use the & operator. int x = 5; int *xPtr = &x; The address of x is stored in xPtr. We say, xPtr points to x .Pointer Variables: Pointer Variables int x = 5; Assume x is stored in memory at location 300000 and y is stored at location 700000 300000 The statement, int *xPtr = &x; causes the address of x to be stored in xPtr 700000 5 300000 x xPtrPointer Variables: Pointer Variables We represent this graphically as 5 x xPtrPointer Variables: Pointer Variables The indirection (dereferencing) operator is * *xPtr = 10; stores the value 10 in the address pointed to by xPtr. 10 x xPtrPointer Variables: Pointer Variables Notice that the character * is used in two ways: To declare that a variable is a pointer. To access the location pointed to by a pointer. Prepending a variable with a * in a declaration declares that the variable will be a pointer to the indicated type instead of a regular variable of that type. Prepending a variable with a * in an expression indicates the value in the location pointed to by the address stored in the variable.Pointers and Dynamic Allocation of Memory: Pointers and Dynamic Allocation of Memory So far, we have always allocated memory for variables in the function data areas that are located on the stack. Size of such variables must be known at compile time. There are times when it is convenient to allocate memory at run time using malloc() , calloc() , or other allocation functions.Pointers and Dynamic Allocation of Memory: Pointers and Dynamic Allocation of Memory The system maintains a second storage area called the heap Permits postponing the decision on the size of the memory block needed to store an array Or permits using a section of memory for the storage of an array at one point in time, and then when that memory is no longer needed it can be freed up for other uses.Pointers and Dynamic Allocation of Memory: Pointers and Dynamic Allocation of Memory When memory is allocated, the allocating function (such as malloc() , calloc() , etc.) returns a pointer of type void (depending on the compiler). void * indicates a pointer to untyped memory Will have to cast the returned value to the specific type needed. We should always release allocated space when no longer needed, so that it can be reused.Initializing Pointers: Initializing Pointers Like all variables pointers must be initialized before they are used. /* pointer1.c */ /* Example of a common error: failure to intialize */ /* a pointer before using it.. This program is */ /* is FATALLY flawed.... */ int main() { int* ptr; *ptr = 99; printf("val of *ptr = %d and ptr is %p \n", *ptr, ptr); return 0; } ptr has not been initializedInitializing Pointers: Initializing Pointers To minimize pointer problems Never declare a pointer without intializing it in the declaration. int *ptr = NULL; Never use NULL as a synonym for integer or float 0.Using gdb to find the point of failure: Using gdb to find the point of failure The gdb debugger is a handy tool for identifying the location at which a program failed. To use the debugger it is necessary to compile with the g option. lowerm@shadow[117] gcc -g pointer1.c -o p1.o To start the debugger use the gdb command and specify the program name lowerm@shadow[117] gdb p1.oUsing gdb to find the point of failure: Using gdb to find the point of failure At the (gdb) prompt you will usually want to tell the debugger to halt the program when it reaches the start of the main() function. The b command is short for breakpoint and tells the debugger where to stop. After a function is entered source code line numbers can be used to specify breakpoints. (gdb) b main Breakpoint 1 at 0x10604: file pointer1.c, line 11.Using gdb to find the point of failure: Using gdb to find the point of failure To start the program use the run command: (gdb) run Starting program: /users/lowerm/public_html/cs101/examples/p.o When the program reaches a breakpoint gdb will tell you and display the next line of code to be executed. Breakpoint 1, main () at pointer1.c:11 11 *ptr = 99; // ptr has not been initializedUsing gdb to find the point of failure: Using gdb to find the point of failure Use the next command to execute a single source statement. The next command will treat a function call as a single statement and not single step into the function being called. If you want to single step through the function use the step command to step into it. The output of the printf() is intermixed with gdb's output and is shown in blue below. (gdb) next pointer is 0 12 *ptr = 99;Using gdb to find the point of failure: Using gdb to find the point of failure Saying next again will cause the program to execute the flawed assignment. gdb will show you the line that caused the error (line # 12). (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x00010620 in main () at p18.c:12 12 *ptr = 99;Using gdb to find the point of failure: Using gdb to find the point of failure The where command can show you where the failure occured (along with a complete function activation trace. (gdb) where #0 0x00010620 in main () at pointer1.c:12 (gdb) To print the value of a variable use the print command. (gdb) print ptr $1 = (int *) 0x0Using gdb to find the point of failure: Using gdb to find the point of failure Attempting to print what ptr points to reaffirms what the problem is: (gdb) print *ptr Cannot access memory at address 0x0 Use the q (quit) command to terminate gdb (gdb) quit The program is running. Exit anyway? (y or n) y lowerm@shadow7[126]Correct use of the pointer: Correct use of the pointer In the C language, variables that are declared within any basic block are allocated on the runtime stack at the time the basic block is activated. /* pointer2.c */ main() { int y; int* ptr; static int a; ptr = &y; // assign the address of y to the pointer *ptr = 99; // assign 99 to what the pointer points to (y) printf("y = %d ptr = %p addr of ptr = %p \n", y, ptr, &ptr); ptr = &a; printf("The address of a is %p \n", ptr); }Correct use of the pointer: Correct use of the pointer lowerm@shadow[130] ./p2.o x = 99 ptr = ffbff05c addr of ptr = ffbff058 The address of a is 208e0 Note that a is heap resident and has an address far removed from the stack resident y and ptr.Use of pointers in processing Cstrings: Use of pointers in processing Cstrings Recall that a “Cstring” is an array of characters whose logical end is denoted by a zero valued byte. The C standard library has a number of functions designed to work with C strings. The strtok() function is one of them. You can see most of them on a Solaris system via the command: man -s 3C string string, strcasecmp, strncasecmp, strcat, strncat, strlcat, strchr, strrchr, strcmp, strncmp, strcpy, strncpy, strlcpy, strcspn, strspn, strdup, strlen, strpbrk, strstr, strtok, strtok_r - string operationsUse of pointers in processing Cstrings: Use of pointers in processing Cstrings In this example we will see how strcat might be implemented. Its prototype is shown below. char *strcat(char *s1, const char *s2);An implementaton of strcat: An implementaton of strcat The name zstrcat is used to avoid potential name conflicts with the “real” strcat. #include <stdio.h> #include <error.h> /* The mission of this function is to concatenate */ /* the string pointed to by p2 to the end of */ /* the string pointed to by p1 */ char *zstrcat(char *p1, char *p2) { char *src; /* source pointer */ char *dest; /* destination pointer */ dest = p1; src = p2; /* Start by advancing dest to the end of the string to be extended */ while (*dest != 0) dest = dest + 1; /* Now tack on the string to be appended */ while (*src != 0) { *dst = *src; dest = dest + 1; src = src + 1; } /* Complete the job by NULL terminating the new string */ *dest = 0; return(p1); }An alternate implementaton: An alternate implementaton The following approach produces code that is difficult to read, painful to maintain, but may (or may not) produce a trivial improvement in performance . When tempted, just say no! char *zstrcat(char *p1, char *p2) { char *r = p1; while (*p1++); p1--; while (*p1++ = *p2++); return(r); }An alternate implementaton: An alternate implementaton main() { char *s1; char *s2; char *result; s1 = (char *)malloc(40); s2 = (char *)malloc(40); result = (char *)malloc(81); *result = 0; fgets(s1, 40, stdin); fgets(s2, 40, stdin); zstrcat(result, s1); zstrcat(result, " "); zstrcat(result, s2); fputs(result, stdout); } Hello World Hello WorldPointer Variables and Arrays: Pointer Variables and Arrays Given int *ptr; *ptr = 7; the compiler will know how many bytes to copy into that memory location pointed to by ptr . defining the type that the pointer points to permits a number of other interesting ways a compiler can interpret code.Pointer Variables and Arrays: Pointer Variables and Arrays Consider a block in memory consisting of ten integers in a row. That is, 40 bytes of memory are set aside to hold 10 integers. Now, set ptr to point to the first of these integers. Suppose the integer is located at memory address 20918. What happens when we write: ptr = ptr + 1; Because the compiler "knows" this is a pointer (i.e. its value is an address) and that it points to an integer (current address, 20918 it adds 4 to ptr instead of 1, so the pointer "points to" the next integer , at memory locationPointer Variables and Arrays: Pointer Variables and Arrays Since a block of 10 integers located contiguously in memory is, by definition, an array of integers, this brings up an interesting relationship between arrays and pointers.Pointer Variables and Arrays: Pointer Variables and Arrays Consider the following: int my_array[ ] = {1, 23,17,4,-5,100}; Here we have an array containing 6 integers. We refer to each of these integers by means of a subscript to my_array , i.e. using my_array[0] through my_array[5] .Pointer Variables and Arrays: Pointer Variables and Arrays The name of an array and the address of the first element in the array represent the same thing; consequently, we could alternatively access them via a pointer as follows: int *ptr; ptr = &myArray[0]; /* points to the first integer in the array */ Then we could print out our array either using the array notation or by dereferencing our pointer.Pointer Variables and Arrays: Pointer Variables and Arrays Since the name of an array is a pointer constant to the first element of the array; therefore, we could also use the following: ptr = myArray;Pointer Arithmetic and Arrays: Pointer Arithmetic and Arrays If ptr is pointing to a specific element in an array, ptr + n is the pointer value n elements away. The following two expressions are exactly the same when array is the name of an array and n is an integer: *(array + n) array[n]Using a one-dimensional array to represent 2-D data: Using a one-dimensional array to represent 2-D data Suppose the integer variables numRows and numCols represent the number of rows and columns in an image and that they have been correctly set using information in the .ppm header. Grayscale images Space for a grayscale image encoded in binary can be allocatged by: unsigned char *image; image = (unsigned char *) malloc(numRows * numCols);Using a one-dimensional array to represent 2-D data: Using a one-dimensional array to represent 2-D data To read in the grayscale image from the standard input: pixelCount = fread(image, 1, numRows * numCols, stdin); if(pixelCount != numRows * numCols) { fprintf(stderr, "pixel count err – expected %d got %d\n", numRows * numCols, pixelCount); exit(1); }Accessing a specific element in a malloc'd 2-D data: Accessing a specific element in a malloc'd 2-D data The value of any grayscale pixel at location (row, col) within the image is accessed in the following way: pixel = *(image + row * numCols + col) or equivalently pixel = image[row * numCols + col); For example, if the value of numCols is 7, then there are 7 pixels per image row. To reach the pixel whose (row, column) address is (3, 5) it is necessary to pass over three complete rows and 5 pixels in row three. The offset of the pixel at (3,5) is 3 * 7 + 5 as shown aboveProcessing an image one row at a time: Processing an image one row at a time for (row = ; row < numRows; row++) { unsigned char *location; location = image + row * numCols; // first pixel in row printf("\n"); for(col = 0; col < numCols; col++) { printf("%03x", *location); location = location + 1; } }Processing an image one row at a time: Processing an image one row at a time An equivalent method that uses array notation: for (row = 0; row < numRows; row++) { printf("\n"; for(col = 0; col < numCols; col++) { printf("%03x", image[row * numCols + col]); location = location + 1; } }Color Images: Color Images A color image is often called an rgb image because the red, green, and blue intensities of each pixel are stored together. Space for a color image in binary rgb format can be allocated by: unsigned char* image; image = (unsigned char *) malloc (3 * numrows * numcols ); To read in the rgb image: pixcount = fread ( imageloc , 3, numrows * numcols , stdin ); if ( pixcount != numrows * numcols ) { fprintf ( stderr , “pix count err - wanted %d got %d \n”, numrows * numcols , pixcount ); exit(1); }Accessing the Individual Pixels of the Binary RGB Image: Accessing the Individual Pixels of the Binary RGB Image Here the process is slightly more complex because each pixel is represented by three constituent components (r, g, and b) where each of (r, g, and b) are represented by a single unsigned char. Nevertheless a bit of reflection yields: red = *(image + 3 * row * numcols + 3 * col ); green = *(image + 3 * row * numcols + 3 * col + 1); blue = *(image + 3 * row * numcols + 3 * col + 2); or equivalently red = image[3 * row * numcols + 3 * col ]; green = image[3 * row * numcols + 3 * col + 1]; blue = image[3 * row * numcols + 3 * col + 2]; It is necessary to muliply by 3 because each pixel occupies three bytes of memory.Functions that Modify Variables of Their Callers: Functions that Modify Variables of Their Callers When a function tries to modify a parameter that is passed to it, it has no effect on the callers copy of that variable. A caller can allow a function to modify its variables by passing a pointer to the value:Functions that Modify Variables of Their Callers: Functions that Modify Variables of Their Callers #include < stdio.h > int getDims ( int * numcols , int * numrows ) { int main( ) { int rows; int cols; getdims (&cols, &rows); fprintf ( stdout , “rows = %d cols = %d \n”, rows, cols); }Functions that Modify Variables of Their Callers: Functions that Modify Variables of Their Callers int getDims ( int * numcols , int * numrows ) { fscanf ( stdin , "%d %d", numcols , numrows ); }