Variables in Memory
1000 1003 1004 1005 1012
xi c
The compiler determines where variables are placed in memory
This placement cannot be changed by the programmer
int n;char c;double x;
Address of Operator
The operator & gives the address of a variable in memory &i is 1000 &c is 1004 &x is 1005
1000 1003 1004 1005 1012
i c xi c
Address of Operator
Can only be applied to variables in memory Cannot be applied to expressions and
constants &3 &(x + 1) &(a == b)
Address Variables (Take 1)
An address is just a number let’s use an integer to hold it
int address_n = &n, address_c = &c, address_x = &x;
Problem?
Value Given Address
The * operator access the content of a variable given its address
*address_n gives the value of the variable n
How can we tell how many bytes we need to read given an address?
We need both the variable’s address and its size
Address Variables (Take 2)
Pointers are variables that hold the address of other variables. starting address type (size)
1000 1003 1004
i ci c ip1000 1004
cp
A pointer is declared by adding a * before the variable name.
double *dp; int *ip, n; char* cp1, *cp2;
type* variable_name;
Declaring a Pointer Variable
pointer to double
pointer to int “regular” int
pointer to char another pointer to char
Referencing
The operator & gives the address of a variable
ptr = &c;Assigns the address of c to the pointer ptr
We say that ptr points to c
Dereferencing
The operator * is the dereferencing operator
Access the variable the pointer points to
int n = 1, m = 2;int* ip;
ip = &n;m = *ip;*ip = 0;
ip is a pointer to int
ip now points to xip now points to n
m is now 1
n is now 0
Is This OK?
int ival = 1024, ival2 = 2048;
int* pi1 = &ival, *pi2 = &ival2;
ival = pi2;
int int*
warning C4047: '=' : 'int' differs in levels of indirection from 'int'*
Is This OK?
int ival = 1024, ival2 = 2048;
int* pi1 = &ival, *pi2 = &ival2;
pi2 = *pi1;
int* int
warning C4047: '=' : 'int *' differs in levels of indirection from 'int'
Is This OK?
int ival = 1024, ival2 = 2048;
int* pi1 = &ival, *pi2 = &ival2;
pi1 = ival;
int* int
warning C4047: '=' : 'int *' differs in levels of indirection from 'int'
NULL
Special “address” indicating “nowhere” int* ip = NULL;
ip does not point to any variable We can test
if (ip != NULL) { *ip = …;
}
Function Arguments - Reminder
Changes to the local variable do not modify the value in the caller
Call “by value”
void increment_counter(int counter){ counter++;}
int main(void){ int count; ... increment_counter(count);}
We can access the variable pointed to by the local variable
Call “by reference”
Pointers as Function Arguments
void increment_counter(int* counter){ (*counter)++;}
int main(void){ int count; ... increment_counter(&count);}
main
incerement_counter(&count)
Caller Callee
main
incerement_counter(count)
count
by value
increment_counter(int counter)
by reference
increment_counter(int* counter)
copy of count
counter
Pointers as Function Arguments
scanf Revisited
We can now understand the & in scanf("%d", &a);
The argument list in scanf is simply passed by address, so scanf can change its content
Exercise
Implement the function: void split(double d, int* i_part, double* f_part);
The function accepts a double parameter and assigns its integer and fraction parts to the two variable pointed to by i_part and f_part respectively.
Write a program that accepts a number from the user and prints out its integer and fraction parts.
Solutionvoid split(double d, int* i_part, double* f_part){ *i_part = (int)d; *f_part = d – (*i_part);}
int main(void){ double num, fraction; int integer;
printf("Please enter a real number: "); scanf("%lf", &num);
split(num, &integer, &fraction); printf("The integer part is %d\n", integer); printf("The remaining fraction is %g\n", fraction);
return 0;}
Example - Swap
void swap(int* x, int* y){ int temp = *x; *x = *y; *y = temp;
}
Call swap: swap(&x, &y);
Const Pointers
A pointer can be declared constantconst int* cip;
The pointer can be changed, but the object it points to can not. cip = &i; ✓ cip = &j; ✓ *cip = 5; ✗
Pointers as Return Values
A function may return the address of a variable
The variable must not be a local variable
char* strchr(const char* str, char c){ while (*str != '\0') { if (*str == c) return str; ++str; } return NULL;}
Address, Pointers and Arrays
int a[10];Defines a block of 10 consecutive objects named a[0],a[1],…,a[9].
The name of the array is a synonym for the location of the first element. a is &a[0]
The name of the array is not a variable, hence its value cannot be modified.
a[0] a[1] a[9]
a:
Address, Pointers and Arrays
a[0] a[1] a[9]
a:
int a[10];int *pa;
pa:
int a[10];int* pa;
pa = &a[0];
Array Names are Not Pointers
Pointers are variables (can be modified) legal:
pa = a pa++
Array name is not a variable (cannot be modified) illegal:
a = pa a++
Pointers Vs. Arrays - Example
int arr[3] = {1, 2, 3};int* ptr;const int* cptr;
arr = ptr;ptr = arr;*ptr = 3;cptr = arr;*cptr = 5;ptr = cptr;*arr = 6;
Pointer Arithmetic
If pa points to an element in the array, then pa+1 points to the next element
pa+i points I elements after pa
a[0] a[1] a[9]
a:
pa:
pa+1:
pa+2:
Pointer Arithmetic
if pa points to a[0]*(pa + 1) is the content of a[1]
*(pa + i) is equivalent to a[i]
More Pointer Arithmetic
Pointers can be incremented and decremented p++ advance p one place in the array p += I advances p i places in the array
Example:if str points to the first character of a string then str + strlen(str) -1 points to the last character
Pointers and Increment Operators
Walk down an array
Pointer notation ++(*p) - increment thing pointed to (*p)++ - increment thing pointed to *(p++) - fetch value, then increment pointer *(++p) - increment pointer, then fetch value
int ar[ARLEN], *ip;ip = ar;while(ip < &ar[ARLEN]) *(ip++) = 0;
Reverseint main(void){ char str[STR_SIZE + 1]; char* ptr = NULL;
printf("Enter a string:\n"); getline(str, STR_SIZE);
for (ptr = str + strlen(str) - 1; ptr >= str; --ptr) { putchar(*ptr); } putchar('\n');
return 0;}
\0str:
ptr:
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’ ‘s’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’ ‘s’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’ ‘s’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’ ‘s’
dest
...
...
my_strcpy
void my_strcpy(char* dest, const char* src){ while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0';}
‘y’ ‘e’ ‘s’ \‘0’
src
‘y’ ‘e’ ‘s’ \‘0’
dest
...
...
Using my_strcpy
int main(void){ char str[STR_LEN + 1], temp[SR_LEN + 1];
... my_strcpy(temp, str); ...}
Common Error
Return of a local array
char* foo(const char* str){ char temp[BIG_ENOUGH];
strcpy(temp, str);
/* manipulate temp */ . . .
return temp; }
Exercise
Write a function with the prototype:void replace_char(char* str,
char c1, char c2);
It replaces each appearance of c1 by c2 in the string str. Do not use the [] operator!
Demonstrate your function with a program that uses it
Top Related