Pointer

51
POINTER Dong-Chul Kim BioMeCIS CSE @ UTA 03/30/22 1

description

Pointer. Dong- Chul Kim BioMeCIS CSE @ UTA. Addresses in Memory. Everything in memory has an address. C allows us to obtain the address that a variable is stored at. scanf() is an example using the address of a variable scanf("%d", & year);. Address in Memory. - PowerPoint PPT Presentation

Transcript of Pointer

Page 1: Pointer

POINTER

Dong-Chul KimBioMeCISCSE @ UTA

04/21/23 1

Page 2: Pointer

• Everything in memory has an address. C allows us to obtain the address that a variable is stored at.

• scanf() is an example using the address of a variable

scanf("%d", &year);

Addresses in Memory

Page 3: Pointer

• Preceding a variable name by an ampersand, known as the address operator, will return its address:#include <stdio.h>

int main(void)

{

int x;

/* notice the format specifier in printf() for an

address is %p */

printf("The address for the memory allocated to x is %p\n", &x);

return 0;

}

Address in Memory

Page 4: Pointer

• hexadecimal (or called base-16) 0123456789ABCDEF• The address for the memory allocated to x is 0012FF60 in

the previous exam.• For 32 bits system the 0012FF60 hexadecimal will be

converted to 32 bits binary (one hex character represented by 4 bits).

Page 5: Pointer

• A pointer is a variable whose value is a memory address.• Note the type of a pointer indicates the type of variable

which it points to. • E.g., int * (called pointer-to-int type) should be initialized to point to

a variable of type int.• Similarly, we have char*, float *, ……

• Given a pointer variable, assignment can be done by using:int * ptr = &pooh; /*assigns pooh’s address to ptr, we say ptr points to pooh*/

ptr = &bah; /*make ptr point to some other variables*/

Pointer(1) Data type(2) Initialization(3) Updating

Page 6: Pointer

#include<stdio.h>

int main(void)

{

int num = 3, num1 = 5;

int* numptr; /* numptr is a pointer */

printf("content of num is %d\n", num);

printf("address of num is %p\n", &num);

printf("address of num1 is %p\n", &num1);

numptr = &num; /* initialize numptr with the address of num */

printf("content of numptr is %p\n", numptr);

numptr = &num1;

printf("content of numptr is %p\n", numptr);

return 0;

}

Page 7: Pointer

• Pointers allow us to modify content in memory by using indirection operator (or called dereference operator).

• Putting an asterisk before your pointer variable• See the example in the next slide

Indirection operator

Page 8: Pointer

• What’s going here?#include <stdio.h>

int main(void)

{

int bah = 10, val;

int* ptr = &bah;

val = *ptr;

printf("The value of val is %d.\n", val);

return 0;

}

bah

val

10

ptr

0012FF60

10

Page 9: Pointer

• We can use pointers in much the same way we do the variables that they point to.

int main(void)

{

int a = 3, b = 3; /* a and b start with equal values */

int* bptr = &b; /* we’ll modify b using a pointer */

a *= 4;

*bptr *= 4;

printf("a is %d, b is %d\n", a, b);

a--;

(*bptr)--; /* parentheses are necessary here to override the order of precedence */

printf("a is %d, b is %d\n", a, b);

return 0;

}

Pointers

Page 10: Pointer

• Wrong! int * a, b;• Instead, you should use int * a, *b;

Define multiple pointers together

Page 11: Pointer

• Pointers can contain the address of another pointer.int main(void)

{

int num = 5;

int* numptr = &num;

int** ptr2 = &numptr; /* notice the two asterisks */

printf(" num is %d\n", num);

printf("*numptr is %d\n", *numptr);

printf(" **ptr2 is %d\n", **ptr2);

return 0;

}

Pointers to Pointers

Page 12: Pointer

• Note the difference between comparing the contents of pointers and the variables that pointers point to.

• To compare the addresses stored in pointers, use• if(numptr == valptr)

• To compare the values of the variables that pointers point to, use• if(*numptr == *valptr)

Comparing Pointers

Page 13: Pointer

• Repeat again here: you have to initialize a variable before you use it.

• If there is no specific initialization, we usually initialize a pointer to NULL (in uppercase). Later we can check the value of that pointer to know whether we have pointed it to any variable.

• If you didn’t initialize your program may not pass the compilation.

Initializing Pointers to NULL

Page 14: Pointer

#include <stdio.h>

int main(void)

{

int num = 3;

int* numptr;

numptr = NULL;/*Try another example without this statement*/

if (numptr != NULL)

printf("num is %d\n", *numptr);

else

printf("Oops. numptr has a value of %p.\n", numptr);

return 0;

}

Initializing Pointers to NULL

Page 15: Pointer

• Previously, we made function calls like this:int x = 3;

int y;

y = do_something(x);

• In this case, a copy of the variable’s value are passed to the function in a process called pass by value.

• Changes made to the copy do not affect the original value.

Pointers and Functions

Page 16: Pointer

• Passing pointers to a function will allow us to change the value of the original variable, called pass by reference,

• We do this by passing the variable’s address to the function.

• We already know passing array to a function is pass by reference.

• What’s the association between array and pointer?????

Pointers and Functions

Page 17: Pointer

#include<stdio.h>void interchange(int * u, int * v);int main(void){

int x = 5, y = 10;printf("Originally x = %d and y = %d.\n", x,y);interchange(&x, &y);printf("Now x = %d and y = %d.\n", x,y);

return 0;}void interchange(int * u, int * v){

int temp;temp = *u;*u = *v;*v = temp;

}

Pointers and Functions

Page 18: Pointer

#include <stdio.h>

void tripleNum(int*); /* notice the function argument has a type of int * */

int main(void)

{

int num = 8;

int* numptr = &num;

printf("before the function call, num is %d\n", num);

tripleNum(numptr); /*or simply use &num*/

printf("after the function call, num is %d\n", num);

}

void tripleNum(int* aptr) /* pass by reference */

{

*aptr = 3 * *aptr; /* first asterisk is for multiplication, second is to dereference the pointer */

}

Pointers and Functions

Page 19: Pointer

#include <stdio.h>

void fx(int x);void fxptr(int* x);

int main(void){ int x = 7; printf("outside: x is at %p\n", &x); fx( x ); fxptr(&x);}

void fx(int x){ printf("inside fx(): x is at %p\n", &x);}

void fxptr(int* x){ printf("inside fxptr(): x contains %p\n", x);}

Difference between copy by value and copy by reference

Page 20: Pointer

• We have already learned how to work with arrays using subscript notation.

• Example:float myData[] = {3.5, 4.0, 9.34};

myData[0] += 2;

printf("myData[0] is %3.1f\n", myData[0]);

Arrays, Part 2

Page 21: Pointer

• The array name evaluates to the address of the first element in the array.int data[] = {5, 6, 7};

int* dataptr = data; /* notice that we don’t use the ampersand here */

int* firstptr = &data[0]; /* we use & here since data[0] evaluates to a number */

printf("*dataptr is %d, *firstptr is %d\n", *dataptr, *firstptr);

Pointers and Arrays

Page 22: Pointer

• Since arrays consist of contiguous memory locations, we can increment (or decrement) the addresses to move through the array.

int data[] = {5, 6, 7};

int i;

for (i = 0; i < 3; i++)

printf("the value at address %p is %d\n", (data + i), *(data + i));

Pointer Arithmetic

Page 23: Pointer

• In the previous example, we also used pointer arithmetic in the lineprintf("the value at address %p is %d\n", (data + i), *(data + i));

• Since data was declared to be an array of ints, the expression (data + i) addsi * sizeof(int)

• to the address of data to get the location of the next int.• This is a reason why we can’t mix types, e.g., point an int*

type pointer to a variable of type double.

Pointer Arithmetic

Page 24: Pointer

• We can use pointer arithmetic with pointers to non-array

int some;

int* someptr = &some;

int data[] = {5, 6, 7};

int* dataptr = data;

printf("pointer address = %p, next address = %p\n", someptr, someptr + 1);

printf("pointer address = %p, next address = %p\n", dataptr, dataptr + 1);type variables as well.

Pointer Arithmetic

Page 25: Pointer

• Pointer arithmetic handles the task of determining the address of the next element in the array.

char chararray[] = {68, 97, 114, 105, 110}; /* 1 byte each */

int intarray[] = {10, 11, 12, 13, 14}; /* 4 bytes each */

int i;

printf("chararray intarray\n");

printf("-------------------\n");

for(i = 0; i < 5; i++)

printf("%p, %p\n", (chararray + i), (intarray + i));

Pointer Arithmetic

Page 26: Pointer

• When you use the increment and decrement operators with pointer variables, you need to be careful that we order the dereference and increment/decrement operators properly.

• ∗, ++ and -- are at the same level of precedence and are evaluated from right to left.

• The primary issue is whether we wish to increment the address stored in the pointer, or increment the value at the address in the pointer.

Incrementing Pointers

Page 27: Pointer

Incrementing Pointers

Page 28: Pointer

• Earlier we learned how to pass the address of a non-array type variable, for exampleint myValue = 5;

someFunct(&myValue);

• We’ve already been passing the address of the first member of an array when we did something like this:float data[] = {1, 2, 3};

anotherFunct(data);

Arrays and Functions, Part 2

Page 29: Pointer

• The subscript style of having 1D arrays as function parameters used square brackets, e.g.,void somefunction(int data[])

{

}

• The pointer style of having 1D arrays as function• parameters is this:void somefunction(int* data)

{

}

Page 30: Pointer

• #include <stdio.h>

• int main(void)• {• int intArray[] = {8, 4, 13, 7};• double doubleArray[] = {93.2, 67.12, 2, 19.03};• int i;• int* ptrI = intArray;• double* ptrD = doubleArray;

• for(i = 0; i < 4; i++)• printf("%p = %2d, %p = %5.2f\n", &intArray[i], intArray[i],• &doubleArray[i], doubleArray[i]);

• for(i = 0; i < 4; i++)• {• printf("%p = %2d, %p = %5.2f\n", ptrI, *ptrI, ptrD, *ptrD);• ptrI++;• ptrD++;• }• }

Page 31: Pointer

• We can have an array whose members are pointers, in this example pointers-to-int.int* data[3];

int i;

int x = 5;

int y = 89;

int z = 34;

data[0] = &x;

data[1] = &y;

data[2] = &z;

for(i = 0; i < 3; i++)

printf("%d\n", *data[i]);

Arrays of Pointers

Page 32: Pointer

• Functions, arrays and pointers• 2-dimentional arrays and pointers• More string functions

Outline

Page 33: Pointer

#include <stdio.h>

int main(void){

int n = 5;int m = 8;float a1[5];/*Yes*/float a2[5*2+1];/*Yes*/

float a3[sizeof(int)+1];/*Yes*/float a4[-4];float a5[0];float a6[2.5];float a7[(int) 2.5];/*Yes*/float a8[n];/*No for C89, but Yes for after C89*/

return 0;}

Define an array of a particular size

Page 34: Pointer

• (1) a fixed array size in your function• (2) passing the array size as a second argument• (3) passing the address after the last element in the array

Function and array size

Page 35: Pointer

int sum(int *ar)

{

int i;

int total = 0;

for (i = 0 ; i < 10; i++)

{

total += ar[i];

}

return total;

}

(1) a fixed array size in your function

Page 36: Pointer

int sum(int *ar, int n)

{

int i;

int total = 0;

for (i = 0 ; i < n; i++)

{

total += ar[i];

}

return total;

}

(2) passing the array size as a second argument

Page 37: Pointer

#include <stdio.h>int sump(int * start, int * end);int main(void){

int marbles[] = {20, 14, 23, 54};int answer;answer = sump(marbles, marbles + 4);printf("The sum of integers in marbles is %d.\n", answer);

return 0;}

int sump(int * start, int * end){

int total = 0;while(start < end){

total += *start;start++;

}return total;

}

(3) passing the address after the last element in the array

Page 38: Pointer

#include <stdio.h>int sump(int ar[], int n);int main(void){

int marbles[] = {20, 14, 23, 54};int answer;printf("The size of marbles is %d bytes.\n", sizeof(marbles));answer = sump(marbles, sizeof(marbles)/sizeof(int));

return 0;}

int sump(int ar[], int n){

int i;int total = 0;for (i = 0 ; i < n; i++){

total += ar[i];}printf("The size of ar is %d bytes.\n", sizeof(ar));return total;

}

sizeof( ) for array name in different places

Page 39: Pointer

• Assignment• Adding an integer to a pointer• Incrementing a pointer• Subtracting an integer from a pointer• Decrementing a pointer• Differencing: different from subtracting an integer from a

pointer

Pointer operations

Page 40: Pointer

int main(void)

{

int marbles[] = {20, 14, 23, 54};

int * ptr1, * ptr2;

ptr1 = &marbles[0];

ptr2 = &marbles[3];

printf("There are %d elements between marbles[0] (inclusive) and marbles[3].\n", ptr2-ptr1);

return 0;

}

Differencing of pointers

Page 41: Pointer

• int zippo[4][2];• zippo, being the name of an array, is the address of the first

element of the array. The first element of zippo is an array of two ints, so zippo is the address of an array of two ints. That is zippo has the same value as &zippo[0].

• Since zippo[0] is itself an array of two integers, so zippo[0] has the same value as &zippo[0][0], the address of its first element, an int.

• In short, zippo[0] is the address of an int-sized object, and zippo is the address of a two-int-sized object. Because both the integer and the array of two integers begin at the same location, both zippo and zioop[0] have the same numeric value.

2-Dimentional array

Page 42: Pointer

• Adding 1 to a pointer or address yields a value larger by the size of the referred-to object. In this respect, zippo and zippo[0] differ, because zippo refers to an object two ints in size, and zippo[0] refers to an object one int in size. Therefore, zippo + 1 has a different value from zippo[0] + 1.

2-Dimentional array cont.

Page 43: Pointer

• The general form for getting the address of any element of any row is*(array_name + row) + column

• For example, when we write *(data + 1) + 2, we are saying “add the size of one row to the address of data, get the address of this, then add the size of two elements of a row to this”.

• The general form for getting the value of any element of any row is*(*(array_name + row) + column)

2-Dimentional array cont.

Page 44: Pointer

#include <stdio.h>int main(void){

int i, j;char* text[4] = {"this", /* text[0] points to this word */"is", /* text[1] points to this word */"a", /* text[2] points to this word */"string"}; /* text[3] points to this word */char * tmp;for(i = 0; i < 4; i++){

j = 0;while (*(text[i] + j) != '\0') /* print each character */{ tmp = (text[i] + j++);

printf("%c: %p ", *tmp,tmp ); /* note the %c */}printf(" \n");

}return 0;

}

String array

Page 45: Pointer

• strtok()• strcat()• strcpy()

String functions

Page 46: Pointer

• char *strtok( pointer-to-str1, pointer-to-str2);

• The strtok() function returns a pointer to the next "token" found in str1

• str2 contains the delimiters that determine the token• strtok() returns NULL if no token is found.• In order to convert a string to tokens, the first call to strtok() should have str1 point to the string to be tokenized. All calls after this should have str1 be NULL.

strtok( )

Page 47: Pointer

#include <stdio.h>

#include <string.h>

int main(void)

{

char str[] = "12333$q4tqrgtq$4524;lkj;$;lkj";

char delims[] = "$";

char *result = NULL;

result = strtok( str, delims);

while( result != NULL )

{

printf( "result is \"%s\"\n", result );

result = strtok( NULL, delims);

}

return 0;

}

strtok( ) cont.

Page 48: Pointer

• strcat() for string concatenation

• Take two strings for arguments

• A copy of the second string is tacked onto the end of the first, and this combined version becomes the new first string.

• The second string is not altered.• The return type of strcat() is char *, the value of its

first argument – the address of the first character of the string to which the second string is appended.

strcat( )

Page 49: Pointer

#include <stdio.h>#include <string.h>int main(void){

char flower[80];char addon[] = " is a cat.";scanf("%s", flower);strcat(flower, addon);printf("%s\n",flower);return 0;

}•Note!!! strcar( ) not checking whether the first array is large enough to hold the second string.

•strncat( ) (different from strcat( ) )

•strncat(bugs, addon, 5) will add the contents of the addon string to bugs, stopping when it reaches 5 additional characters or the null character, whichever comes first.

strcat( ) cont.

Page 50: Pointer

• char * strcyp(char * s1, const char * s2)

• This function copies the string (including the null character) pointed to by s2 to the location pointed to by s1. The return value is s1.

• The strcyp( ) function has type char *, and it returns the value of its first argument – the address of a character.

• The first argument need not point to the beginning of an array.

strcpy( )

Page 51: Pointer

#include <stdio.h>#include <string.h>int main(void){

char orig[] = "beast";char copy[80] = "Be the best that you can be.";char *ps;ps = strcpy(copy+7, orig);printf("copy - %s\n", copy);

printf("ps - %s\n", ps);return 0;

}

Still, strcpy() doesn’t check whether the first array is large enough to fit the second string. A better way is to use strncpy() function.

strcpy( ) cont.