PLT 101 Computer Programming CHAPTER 4 POINTERS Lecturer

  • Slides: 63
Download presentation
PLT 101 Computer Programming CHAPTER 4 POINTERS Lecturer: Mrs Nurul Izni Rusli nurulizni@unimap. edu.

PLT 101 Computer Programming CHAPTER 4 POINTERS Lecturer: Mrs Nurul Izni Rusli nurulizni@unimap. edu. my UNICITI S 2 BK 5 Level 1

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 2

Introduction to Pointer Variable which contains the address of another variable Pointer variable used

Introduction to Pointer Variable which contains the address of another variable Pointer variable used to hold an address of the memory It can refer to different objects/variable at different times. Pointers are used in C programs for a variety of purposes: o To return more than one value from a function(using pass by reference) o To create and process strings o To manipulate the contents of arrays and structures o To construct data structures whose size can grow or shrink dynamically 3

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 4

Pointer Variable Definitions and Initialization Normal Variables Contain a specific value (direct reference) num

Pointer Variable Definitions and Initialization Normal Variables Contain a specific value (direct reference) num 7 Pointer variables Contain memory addresses as their values Pointer contains an address of a variable that has a specific value (indirect reference) Indirection – referencing a pointer value num. Ptr 5 num 7

Pointer Variable Definitions and Initialization –cont. Pointer definitions * used with pointer variables int

Pointer Variable Definitions and Initialization –cont. Pointer definitions * used with pointer variables int *num. Ptr; Defines a pointer to an int (pointer of type int *) Multiple pointers require using a * before each variable definition int *num. Ptr 1, *num. Ptr 2; Can define pointers to any data type Initialize pointers to 0, NULL, or an address 0 or NULL – points to nothing (NULL preferred) int *num. Ptr = NULL; or int *num. Ptr = 0; 6

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 7

Pointer Operators Symbol & is called address operator Returns address of operand int num

Pointer Operators Symbol & is called address operator Returns address of operand int num = 7; int *num. Ptr; num. Ptr = # /* num. Ptr gets address of num */ //num. Ptr “points to” num num. Ptr 8 num 7 num. Ptr 500000 600000 num 600000 Address of num is value of num. Ptr 7

Pointer Operators –cont. Symbol * is called indirection/dereferencing operator Returns a synonym/alias of what

Pointer Operators –cont. Symbol * is called indirection/dereferencing operator Returns a synonym/alias of what its operand points to *num. Ptr returns num (because num. Ptr points to num) * can also be used for assignment Returns alias to an object *num. Ptr = 10; /* changes num to 10 */ For example, the statement printf( "%d", *num. Ptr ); prints the value of variable num, namely 7. * and & operators are complements of one another They can be applied in consecutively in either order as the same result will be printed Example: &*num. Ptr or *&num. Ptr 9

Pointer Operators –cont. Sample Program #include <stdio. h> int main() { int num; int

Pointer Operators –cont. Sample Program #include <stdio. h> int main() { int num; int *num. Ptr; int num 1=5; OUTPUT number = 7 num. Ptr points to num whereby the value is = 7 Address of num. Ptr : 1245060 Contents of num. Ptr : 1245064 Address of num : 1245064 Dereferencing pointer, *num. Ptr = 15 num = 20 *num. Ptr + num 1 = 25 num = 7; printf("number = %dn", num); num. Ptr = &num; printf("num. Ptr points to num whereby the value is = %dn", *num. Ptr); printf("Address of num. Ptr : %d Contents of num. Ptr : %dn", &num. Ptr, num. Ptr); printf("Address of num : %dnn", &num); *num. Ptr = 15; printf("Dereferencing pointer, *num. Ptr = %dn", *num. Ptr); num = num + num 1; printf(“num = %dn”, num); printf("*num. Ptr = %dn", *num. Ptr); printf("*num. Ptr + num 1 = %dn", *num. Ptr + num 1); return 0; } 10

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 11

Calling Functions by Reference Call by reference with pointer arguments Passes address of argument

Calling Functions by Reference Call by reference with pointer arguments Passes address of argument using & operator Allows you to change actual location in memory Arrays are not passed with ‘&’ because the array name is already a pointer * operator Used as alias or nickname for variable inside of function void fun 1 (int *number) { *number = 2 * (*number); } *number used as nickname for the variable passed 12

Passing Arguments to Functions by Reference There are two ways to pass arguments to

Passing Arguments to Functions by Reference There are two ways to pass arguments to a function: call-by-value and call-by-reference. All arguments in C are passed by value. In C, you use pointers and the indirection operator to simulate call-by -reference. When calling a function with arguments that should be modified, the addresses of the arguments are passed. This is normally accomplished by applying the address operator (&) to the variable (in the caller) whose value will be modified. Arrays are not passed using operator & because C automatically passes the starting location in memory of the array (the name of an array is equivalent to &array. Name[0]). When the address of a variable is passed to a function, the indirection operator (*) may be used in the function to modify the value at that location in the caller’s memory. 13

Passing Arguments to Functions by Reference Sample Program 14 Figure 1

Passing Arguments to Functions by Reference Sample Program 14 Figure 1

Passing Arguments to Functions by Reference -cont. Figure 1 passes the variable number to

Passing Arguments to Functions by Reference -cont. Figure 1 passes the variable number to function cube. By. Value using call-by-value (line 14). The cube. By. Value function cubes its argument and passes the new value back to main using a return statement. The new value is assigned to number in main (line 14). 15

Passing Arguments to Functions by Reference Sample Program 16 Figure 2

Passing Arguments to Functions by Reference Sample Program 16 Figure 2

Passing Arguments to Functions by Reference -cont. Figure 2 passes the variable number using

Passing Arguments to Functions by Reference -cont. Figure 2 passes the variable number using call-by-reference (line 15) —the address of number is passed — to function cube. By. Reference. Function cube. By. Reference takes as a parameter a pointer to an int called n. Ptr (line 22). The function dereferences the pointer and cubes the value to which n. Ptr points (line 24), then assigns the result to *n. Ptr (which is really number in main), thus changing the value of number in main. 17

Call by Value VS Call by Reference Figure 1 18 Figure 2

Call by Value VS Call by Reference Figure 1 18 Figure 2

Call by Value VS Call by Reference Figure 3 19

Call by Value VS Call by Reference Figure 3 19

Call by Value VS Call by Reference Figure 3 20

Call by Value VS Call by Reference Figure 3 20

Call by Value VS Call by Reference Figure 3 21

Call by Value VS Call by Reference Figure 3 21

Call by Value VS Call by Reference Figure 4 22

Call by Value VS Call by Reference Figure 4 22

Call by Value VS Call by Reference Figure 4 23

Call by Value VS Call by Reference Figure 4 23

Call by Value VS Call by Reference Example #include <stdio. h> #include <stdlib. h>

Call by Value VS Call by Reference Example #include <stdio. h> #include <stdlib. h> void printtotal(int total); void addxy(int x, int y, int total); void subxy(int x, int y, int *total); int main() { int x, y, total; x = 10; y = 5; total = 0; printtotal(total); addxy(x, y, total); printtotal(total); subxy(x, y, &total); printtotal(total); return 0; } 24 Variable pass by value Variable pass by reference void printtotal(int total) { printf("Total in Main: %dn", total); } void addxy(int x, int y, int total) { total = x + y; printf("Total from inside addxy: %dn", total); } void subxy(int x, int y, int *total) { *total = x - y; printf("Total from inside subxy: %dn", *total); } Output

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 25

Recap… Type /element 26 Variable Pointer Variable & Address operator -return address of operand

Recap… Type /element 26 Variable Pointer Variable & Address operator -return address of operand * - Indirection/dereferencing operator -return value of whatever operand pointed to Declaration/Define int a; int *a. Ptr; Initialization int a = 5; int *a. Ptr = &a; int *a. Ptr = NULL; int *a. Ptr = 0; Verify address &a &a. Ptr //address of pointer Verify content a a. Ptr//address of variable a Value pointed a *a. Ptr//value of variable a e. g. printf ( “%dn” , *a. Ptr); //will return value of a

Using the const Qualifier with Pointers const qualifier Variable cannot be changed Use const

Using the const Qualifier with Pointers const qualifier Variable cannot be changed Use const if function does not need to change a variable Attempting to change a const variable produces an error const pointers Point to a constant memory location Must be initialized when defined int *const my. Ptr = &x; constant pointer to an int x x can be changed, but not *Ptr (cannot pointed to anything else. const int *my. Ptr = &x; regular pointer to a const int x x cannot be changed, but *Ptr can const int *const Ptr = &x; const pointer to a const int x 27 both x and *Ptr cannot be change

sizeof Operator C provides the special unary operator sizeof to determine the size in

sizeof Operator C provides the special unary operator sizeof to determine the size in bytes of an array (or any other data type) during program compilation. When applied to the name of an array the sizeof operator returns the total number of bytes in the array as an integer. 28

sizeof Operator –cont. The number of elements in an array also can be determined

sizeof Operator –cont. The number of elements in an array also can be determined with sizeof. For example, consider the following array definition: double real[ 22 ]; Variables of type double normally are stored in 8 bytes of memory. Thus, array real contains a total of 176 bytes (22 x 8 bytes) To determine the number of elements in the array, the following expression can be used: sizeof( real ) / sizeof(double ) 29

sizeof Operator –cont. Sample Program o o 30 Example Program is to calculates the

sizeof Operator –cont. Sample Program o o 30 Example Program is to calculates the number of bytes used to store each of the standard data types. The results could be different between computers.

sizeof Operator –cont. Sample Program – cont. Output 31

sizeof Operator –cont. Sample Program – cont. Output 31

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 32

Pointer Expressions and Pointer Arithmetic operations can be performed on pointers Increment/decrement pointer (++

Pointer Expressions and Pointer Arithmetic operations can be performed on pointers Increment/decrement pointer (++ or --) Add an integer to a pointer( + or += , - or -=) Pointers may be subtracted from each other Operations meaningless unless performed on an array 33

Pointer Expressions and Pointer Arithmetic –cont. 5 elements int array on machine with 4

Pointer Expressions and Pointer Arithmetic –cont. 5 elements int array on machine with 4 byte ints ◦ v. Ptr points to first element v[ 0 ] at location 3000 (v. Ptr = 3000) ◦ v. Ptr += 2; sets v. Ptr to 3008 v. Ptr points to v[ 2 ] (incremented by 2), but the machine has 4 byte ints, so it points to address 3008 int *v. Ptr; v. Ptr = v; 34 v. Ptr += 2

Pointer Expressions and Pointer Arithmetic –cont. If v. Ptr had been incremented to 3016,

Pointer Expressions and Pointer Arithmetic –cont. If v. Ptr had been incremented to 3016, which points to v[4], the statement v. Ptr -= 4; would set v. Ptr back to 3000—the beginning of the array. If a pointer is being incremented or decremented by one, the increment (++) and decrement (--) operators can be used. Either of the statements ++v. Ptr; v. Ptr++; increments the pointer to point to the next location in the array. Either of the statements --v. Ptr; v. Ptr--; decrements the pointer to point to the previous element of the array. 35

Pointer Expressions and Pointer Arithmetic –cont. Subtracting pointers Returns number of elements from one

Pointer Expressions and Pointer Arithmetic –cont. Subtracting pointers Returns number of elements from one to the other. If v. Ptr 2 v. Ptr = &v[ 2 ]; = &v[ 0 ]; v. Ptr 2 - v. Ptr would produce 2 Pointer comparison ( <, == , > ) See which pointer points to the higher numbered array element Also, see if a pointer points to 0 36

Example of Pointer Operation #include <stdio. h> int main() { int *v. Ptr; int

Example of Pointer Operation #include <stdio. h> int main() { int *v. Ptr; int *v. Ptr 2; int v[5] = {10, 20, 30, 40, 50}; int temp; int *p, *q; v. Ptr= v; printf("Address of v. Ptr : %d Contents of v. Ptr : %dn", &v. Ptr, v. Ptr); printf("Address of v[0] : %dn", &v); v. Ptr +=2; printf("Address of v. Ptr + 2: %dn", v. Ptr); v. Ptr +=2; printf("Address of v. Ptr + 4: %dn", v. Ptr); v. Ptr 2=&v[2]; v. Ptr=&v[0]; temp=v. Ptr 2 -v. Ptr; printf("Contents of temp : %dn", temp); p=q; printf("Contents of p : %d q: %dn", p, q); return 0; } 37 Output Address of v. Ptr : 1245064 Contents of v. Ptr : 1245020 Address of v[0] : 1245020 Address of v. Ptr + 2: 1245028 Address of v. Ptr + 4: 1245036 Contents of temp : 2 Contents of p : 2147323904 q: 2147323904

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 38

The Relationship between Pointers and Arrays • Arrays and pointers are closely related •

The Relationship between Pointers and Arrays • Arrays and pointers are closely related • Array name like a constant pointer • Pointers can do array subscripting operations • Define an array b[5] and a pointer b. Ptr • To set them equal to one another use: b. Ptr = b; • The array name b is actually the address of first element of the array b[ 5 ] b. Ptr = &b[0]; • Explicitly assigns b. Ptr to the address of first element of b 39

The Relationship between Pointers and Arrays –cont. ◦ Element b[3] Can be accessed by

The Relationship between Pointers and Arrays –cont. ◦ Element b[3] Can be accessed by *(b. Ptr + 3) Where * is the offset. Called pointer/offset notation Can be accessed by b. Ptr[3] Called pointer/subscript notation b. Ptr[3] same as b[3] Can be accessed by performing pointer arithmetic on the array itself *(b + 3) 40

The Relationship between Pointers and Arrays –cont. Figure 5 uses the four methods we

The Relationship between Pointers and Arrays –cont. Figure 5 uses the four methods we have discussed for referring to array elements-array subscripting, pointer/offset with the array name as a pointer, pointer subscripting, and pointer/offset with a pointer - to print the four elements of the integer array b. 41

The Relationship between Pointers and Arrays –cont. Sample Program 42 Figure 5

The Relationship between Pointers and Arrays –cont. Sample Program 42 Figure 5

Sample Program –cont. 43 Figure 5

Sample Program –cont. 43 Figure 5

Sample Program –cont. 44 Figure 5

Sample Program –cont. 44 Figure 5

Example #include <stdio. h> int main() { int *b. Ptr; int i; int b[10]={10,

Example #include <stdio. h> int main() { int *b. Ptr; int i; int b[10]={10, 20, 30, 40, 50}; b. Ptr = b; printf("Address of b. Ptr : %d Contents of b. Ptr : %dn", &b. Ptr, b. Ptr); printf("Address of b : %d Contents of b[0] : %d %d %dn", &b, b[0], *b. Ptr, *b); printf("b. Ptr points to b[0] = %dn", *b. Ptr); printf("n. I am accessing element b[3]!!n. Let see how many ways I can do itn"); printf("b[3] = %dn", b[3]); printf("*(b. Ptr + 3) = %dn", *(b. Ptr + 3)); printf("*(b + 3) = %dn", *(b + 3)); printf("b. Ptr[3] = %dnn", b. Ptr[3]); for(i=0; i<10; i++) printf("b[%d] = %dn", i, *(b. Ptr+i)); return 0; } 45

Example –cont. Program Output Address of b. Ptr : 1245064 Contents of b. Ptr

Example –cont. Program Output Address of b. Ptr : 1245064 Contents of b. Ptr : 1245016 Address of b : 1245016 Contents of b[0]: 10 10 10 b. Ptr points to b[0] = 10 46 I am accessing element b[3]!! Let see how many ways I can do it b[3] = 40 *(b. Ptr + 3) = 40 *(b + 3) = 40 b. Ptr[3] = 40 b[0] = 10 b[1] = 20 b[2] = 30 b[3] = 40 b[4] = 50 b[5] = 0 b[6] = 0 b[7] = 0 b[8] = 0 b[9] = 0

The Relationship between Pointers and Arrays –cont. Figure 6 shows the interchangeability of arrays

The Relationship between Pointers and Arrays –cont. Figure 6 shows the interchangeability of arrays and pointers. Using the two string-copying functions— copy 1 and copy 2 Both functions copy a string (possibly a character array) into a character array. After a comparison of the function prototypes for copy 1 and copy 2, the functions appear identical. They accomplish the same task; however, they’re implemented differently. 47

The Relationship between Pointers and Arrays –cont. Sample Program 48 Figure 6

The Relationship between Pointers and Arrays –cont. Sample Program 48 Figure 6

Sample Program –cont. 49 Figure 6

Sample Program –cont. 49 Figure 6

The Relationship between Pointers and Arrays –cont. Function copy 1 uses array subscript notation

The Relationship between Pointers and Arrays –cont. Function copy 1 uses array subscript notation to copy the string in s 2 to the character array s 1. The function defines counter variable i as the array subscript. The for statement header (line 29) performs the entire copy operation—its body is the empty statement. The header specifies that i is initialized to zero and incremented by one on each iteration of the loop. The expression s 1[i] = s 2[i] copies one character from s 2 to s 1. When the null character is encountered in s 2, it’s assigned to s 1, and the value of the assignment becomes the value assigned to the left operand (s 1). 50

The Relationship between Pointers and Arrays –cont. The loop terminates because the integer value

The Relationship between Pointers and Arrays –cont. The loop terminates because the integer value of the null character is zero (false). Function copy 2 uses pointers and pointer arithmetic to copy the string in s 2 to the character array s 1. Again, the for statement header (line 38) performs the entire copy operation. The header does not include any variable initialization. As in function copy 1, the expression (*s 1 = *s 2) performs the copy operation. Pointer s 2 is dereferenced, and the resulting character is assigned to the dereferenced pointer *s 1. 51

The Relationship between Pointers and Arrays –cont. After the assignment in the condition, the

The Relationship between Pointers and Arrays –cont. After the assignment in the condition, the pointers are incremented to point to the next element of array s 1 and the next character of string s 2, respectively. When the null character is encountered in s 2, it’s assigned to the dereferenced pointer s 1 and the loop terminates. The first argument to both copy 1 and copy 2 must be an array large enough to hold the string in the second argument. Otherwise, an error may occur when an attempt is made to write into a memory location that is not part of the array. Also, the second parameter of each function is declared as const char * (a constant string). 52

The Relationship between Pointers and Arrays –cont. In both functions, the second argument is

The Relationship between Pointers and Arrays –cont. In both functions, the second argument is copied into the first argument—characters are read from it one at a time, but the characters are never modified. Therefore, the second parameter is declared to point to a constant value so that the principle of least privilege is enforced—neither function requires the capability of modifying the second argument, so neither function is provided with that capability. 53

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling

Outline • Introduction • Pointer Variable Definitions and Initialization • Pointer Operators • Calling Functions by Reference • Using the const Qualifier with Pointers • Pointer Expressions and Pointer Arithmetic • Relationship between Pointers and Arrays • Arrays of Pointers 54

Arrays of Pointers Arrays may contain pointers. A common use of an array of

Arrays of Pointers Arrays may contain pointers. A common use of an array of pointers is to form an array of strings, referred to simply as a string array. Each entry in the array is a string, but in C a string is essentially a pointer to its first character. So each entry in an array of strings is actually a pointer to the first character of a string. For example: an array of strings 2 -D array: const char suit[ 4 ][ 10 ] = { "Hearts", "Diamonds", "Clubs", "Spades" }; Array of pointers const char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" }; 55

Arrays of Pointers –cont. The suit[4] portion of the definition indicates an array of

Arrays of Pointers –cont. The suit[4] portion of the definition indicates an array of 4 elements. The char * portion of the declaration indicates that each element of array suit is of type “pointer to char. ” Qualifier const indicates that the strings pointed to by each element pointer will not be modified. The four strings are 7, 9, 6 and 7 characters long, respectively. Although it appears as though these strings are being placed in the suit array, only pointers are actually stored in the array. Each pointer points to the first character of its corresponding string. Thus, even though the suit array is fixed in size, it provides access to character strings of any length. This flexibility is one example of C’s powerful data-structuring capabilities. 56

Arrays of Pointers –cont. suit array has a fixed size, but strings can be

Arrays of Pointers –cont. suit array has a fixed size, but strings can be of any size 57

Arrays of Pointers –cont. Example #include <stdio. h> #define N 5 int main() {

Arrays of Pointers –cont. Example #include <stdio. h> #define N 5 int main() { char *student. Name[10]; int i; for(i=0; i<N; i++) { printf("Enter student[%d] name : ", i); scanf("%s", student. Name + i); printf("You just entered : %sn", student. Name + i); } return 0; } Output Enter student[0] name : ali You just entered : ali Enter student[1] name : abu You just entered : abu Enter student[2] name : cheah You just entered : cheah Enter student[3] name : dali You just entered : dali 58 Enter student[4] name : gheeta You just entered : gheeta

FINAL EXAM 2014/2015 59

FINAL EXAM 2014/2015 59

FINAL EXAM 2014/2015 – ANSWER 60

FINAL EXAM 2014/2015 – ANSWER 60

EXAMPLE Based on the following line numbers, what will the program in Figure 1

EXAMPLE Based on the following line numbers, what will the program in Figure 1 print to the screen when it compiled and executed? LINE NO LINE 9 LINE 11 LINE 14 LINE 15 LINE 16 LINE 17 LINE 19 LINE 21 LINE 22 LINE 23 61 ANSWER Line 1 Line 2 Line 3 Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 Line 11 Line 12 Line 13 Line 14 Line 15 Line 16 Line 17 Line 18 Line 19 Line 20 Line 21 Line 22 Line 23 Line 24 Line 25 #include <stdio. h> int main( void ) { char s[]="Alexander Graham Bell"; char* p; int x=45; int *px; int *sx=&x; p=s; printf( "%sn", s ); *p = ’F’; printf( "%sn", s ); p += 17; *p = ’D’; printf( "%sn", s ); printf( "%dn", *sx + 5 ); printf( "%dn", *sx ); px = sx; printf( "%dn", *px ); *px = 83; printf( "%dn", x ); printf( "%dn", *sx ); printf( "%dn", *px+5 ); return 0; } / * end main */ Figure 1

EXAMPLE- Answer LINE 62 LINE 9 ANSWER Alexander Graham Bell LINE 11 Flexander Graham

EXAMPLE- Answer LINE 62 LINE 9 ANSWER Alexander Graham Bell LINE 11 Flexander Graham Bell LINE 14 Flexander Graham Dell LINE 15 45 LINE 16 50 LINE 17 45 LINE 19 45 LINE 21 83 LINE 22 83 LINE 23 88

Q & A! Quotes of the day:

Q & A! Quotes of the day: