08 Pointers
08 Pointers
pointers
when you get stuck today, raise your hand, stop me
3
i
4
5
j
6
size of a pointer today is typically long pointers can point anywhere in memory
enough to reach any address in memory.
resolution of pointers is one byte
For > 4GB of RAM that's 8 bytes
(but it may not be very efficient to do so)
(otherwise 32 bit = 4 bytes)
To find out
int main() {
printf("My pointers occupy \
%ld bytes\n",sizeof(int*));
}
(pointers can point anywhere, but they may
not be able to access it ! seg fault)
printf("t
return 0; = %ld\n", t); // _big_ + 1
}
what's going on here/what will it output?
<30sec brainstorming>
confusing: here the * defines that t is a pointer (but does nothing)…
pointer (syntax) ::
char *t; // defines a varable t as a pointer to char
NU
‘l’ ‘i’ ‘s’ LL ‘t’
list the key to processing variable amounts of data (which arrays lack)
‘t’ NU
LL ‘r’ NU
LL
‘e’ NU
LL ‘e’ NU
LL
NU
LL ‘e’
pointers
#include <stdio.h> H e l l o \0
int main(void) {
char s[] = "Hello";
char *t = s; // *t just definest t, does not dereference
t++;
// advance pointer to ‘e’
t += 2;
// ... by another two steps to second ‘l’
t *= 2;
// error, undefined (or can you think
t = t + s; // of a case where this would be useful)
return 0; // error, same reason
}
ok or not?
<30sec brainstorming>
not the same as… math on what is being pointed at
#include <stdio.h>
H e l l o \0
int main(void) {
char s[] = "Hello";
t
char *t = s;
*t += 17; // increment what t points at : 'H' ! 'Y'
(*(t+4))++; // move t 4 over to 'o', increment that ='p'
printf(s); // prints "Yellp"
return 0;
lots of () here to help us read.
} we'll reduce them some other time
ok or not?
<30sec brainstorming>
the message here is: a pointer always represents two things
1.the thing that's being pointed at
2.the pointer itself
c =c *(s++)
= *s++ 1. copies the pointer s
(and increments s afterwards)
<3min repl>
use pointers to traverse arrays…
stringcopy.c
void strcpy1(char from[], char to[]) {
int i = 0;
do
H e l l o \0
to[i] = from[i];
while(to[i++] != '\0')
fr[0] fr[1] fr [2] fr [3] fr [4] fr [5]
}
H e l l o \0
void strcpy2(char *from, char *to) {
while (*to++ = *from++)
;
pointers
}
some say "elegant!"
1. uses one variable less from from from from from from
2. clarifies program flow
<vote>
3. executes faster what do you say?
others say "confusing!"
another
warm-up
even though pointers are whole numbers and may well be represented using the
same number of bits as int, C does not consider them as int
it restricts math to what is considered useful/meaningful.
int main(void) {
char s[] = "string"; // initialization like an array = ok
char *t;
int i;
t = s; // ok
t = s + 2; // ok
of limited use unless p and
t = 2 * s; // error q point to same array
t = s + s; // sneaky. but still error
i = t – s; // ok & useful: num of elements in between
t = t + t – s; // error (stops at t + t)
t = t + (t – s); // ok
i = s; // warning
i = *t; // valid
i = (t < s); // (a Boolean…) ok and done all the time
} ok or error?
<vote>
NULL
NU
‘l’ ‘i’ ‘s’ LL ‘t’
ok or error?
<vote>
so pointers and arrays are pretty much the same things…
only minor difference….
C does not allow array variables to be modified
char a[5];
char *pa = a + 1; // legal
a = pa; // illegal
<30sec brainstorming>
http://stackoverflow.com/questions/3839553/array-as-const-pointer
but if you really want to have something that acts as array and can be modified
#include <stdio.h>
int main(void) {
int a[100] = {1,2,3,4,5};
a += 2; // error: C will not modify an array
int *b = a; // but, we can point b to our array
printf ("b[2] = %d\n", b[2]); // and use b as array (wild)
b += 2; // screw around with b
printf ("b[2] = %d\n", b[2]); // and still pretend
return 0; // it's an array
}
any errors/what does it print?
<30sec brains>
pointing to
non-arrays
pointers can point to anything, not just arrays…
we already looked at
* declaration
int *p; // pointer to int <30sec
* dereferences (indirection operator)
brains>
int d = *p; // copy value of c
*&c == c
NEW: one may say that *
& returns the address of a variable is the inverse of &
int c;
int *p = &c; // initialization &*c == <syntax error>
#include <stdio.h>
int main()
{
int number1, number2;
printf("Enter two integers: \n");
fflush(stdout);
scanf("%d %d", &number1, &number2);
ah, this is what was
going on here!
if(number1 == number2)
printf("%d = %d\n", number1, number2);
else if (number1 > number2)
printf("%d > %d\n", number1, number2);
else
printf("%d < %d\n", number1, number2);
return 0;
}
# include <stdio.h>
int main(void) {
int x = 1;
int y = 2;
int *ip; // ip is a pointer, can point to ints
ip = &x;
y = *ip; // ip now points to x
*ip = 0; // value of y becomes same as x, i.e., 1
printf("y = %d\n", //
y);value of x becomes 0, (y stays 1)
return 0; // prints y = 1
}
what does it print?
<30sec brainstorming>
#include <stdio.h> we can use the address operator to write
functions that affect multiple values
C
void swap(int
(int*x, intint
*x, *y)*y)
{ {
int temp;
int temp;
temp = *x;
temp = *x;
*x = *y;
*x
*y = =temp;
*y;
*y
return;= temp;
} return;
int main () {
int a = 100, b = 200;
<3min repl>
swap(&a, &b);
printf("After swap: a = %d, b = %d\n", a, b);
(&a,
return 0; &b);
}
main insight here:
pointers ::
enable access to objects in scope of the caller
In languages that support true "call by reference", such as C++, we can write
swap(x,y); // does not work in C
http://stackoverflow.com/questions/17423218/diff-between-call-by-reference-and-call-by-pointer
even cooler,
in languages that allow for multiple return parameters or "implicit tuples",
you can avoid the problem in the first place by writing
(x, y) = (y, x); // cannot say this in C
http://stackoverflow.com/questions/31374721/what-is-the-logic-for-x-y-y-x-to-swap-the-values-in-python
back to pointing at arrays…
start third lecture
how C does pointer
math
#define arraySize 10
char s[arraySize];
char *t = s + arraySize - 1;
// t now points to the last elememt of s
int a[arraySize];
int *b = a + arraySize - 1;
yep!
#include <stdio.h> H e l l o \0
char element(char s[], int i) {
return s[i];
}
s s[4]
char elementBasedOnPointerMath(char *s, int i) {
return *(s + i);
} return *(s + i);
this is how arrays are actually implemented
int main(void) {
char s[] = "Hello";
printf("s[4] = %c\n", element(s,4));
printf("s[4] = %c\n", elementBasedOnPointerMath(s,4));
return 0;
}
H e l l o \0
;
}
int main (void) {
char sArray[] = "hello";
char tArray[20];
char *s = sArray;
char *t = tArray; s s s s s s
strcpy1(s, t);
strcpy2(sArray, tArray);
printf("%s\n%s\n%s\n%s",
sArray, tArray, s, t); yes, these are all ok.
}
array access operator [] and
pointer dereferencing operator*
can often be used synonymously
formatting
char * s, char * t; for C, all three are ok.
char *s, char *t; but which format to use and why?
char* s, char* t;
<30sec brainstorming>
when would we say two strings are "the same"?
<30sec brainstorming>
this is a deeply rooted issue
and we will re-encounter this ambiguity with other data structures
#include <stdio.h>
int my_stery(char *s, char *t) {
while (*s != '\0') {
if (*t == '\0') return 1;
if (*s < *t) return -1; = strcmp()
if (*s > *t) return 1; iterates over the strings and
s++; compares char by char
t++;
}
if (*t != '\0') return -1;
return 0;
}
int main(void) {
char s[] = "Hello World";
char t[] = "Hello Worm";
printf("my_stery (\"%s\", \"%s\") = %d\n", s, t, my_stery(s,t));
return 0;
}
<30sec brains>
what does it do?
here is a case where this becomes a problem…
#include <stdio.h> 5 5 01 \0
#include <string.h>
int main(void) {
char phoneNumberTholen[] = "550"; 5 5 0 \0
tb
// I started out co-using my admin's phone
5 5 0 \0
char *phoneNumberBaudisch = phoneNumberTholen; 1
Solution 1: replace line with t
phoneNumberBaudisch = strdup(phoneNumberTholen);
// then I changed my mind and switched to my own number b
strcpy(phoneNumberBaudisch, "551");
5 5 0 \0
Solution 2: replace line with
phoneNumberBaudisch = "551";
printf("%s\n",phoneNumberBaudisch);
5 5 1 \0
printf("%s\n",phoneNumberTholen); problem: now Tholen and I
tb
both have my new number
return 0;
} b
<30sec brains>
thoughts?
why pointers
are hard
http://stackoverflow.com/questions/4025768/what-do-people-find-difficult-about-c-pointers
end
pointers
professor patrick baudisch
pt1
hasso-plattner institute
I did not do the following samples in the lecture,
but consider solving them at home in order to practice…
practice!
more array examples
incString.c
#include <stdio.h>
"Hello World"
! "Ifmmp Xpsme"
C
char incChar(char c) {return c+1;}
}
printf("%s\n", s);
return 0; <3min repl>
numberToReverseString.c
#include <stdio.h> // works by copying every non-c to the current j position
C
void itoa(int n,char s[]) {
int i = 0; char *t = s;
do { do {
s[i++] = n % 10 + '0';
*t++ = n % 10 + '0';
} while ((n /= 10) > 0);
} while ((n /= 10) > 0);
}
int main(void) {
char s[255];
int n = 2016;
itoa(n, s);
printf("itoa(\"%d\") = %s\n", n,s);
return 0;
translate to pointers
}
<3min repl>
reverseString.c
#include <stdio.h>
C
#include <string.h>
the comma operator allows evaluating
int main(void) {
multiple expressions in for statement.
char s[] = "Hello";
(general idea: pair of expressions separated
int i, j, tmp;
by comma is evaluated left to right)
<30sec brains>
reverseStringWithPointers.c
#include <stdio.h>
C
#include <string.h>
int main(void) {
char s[] = "Hello";
char *i = s, tmp;
char *j = s + strlen(s) - 1; // j points at last char
while (i < j) {
tmp = *i,
*i++ = *j,
*j-- = tmp;
} s H e l l o \0
printf("s = %s\n", s); i j
return 0;
} same using pointers
<30sec brains>
deleteThisCharfromStr.c
#include <stdio.h> H e l l o \0
i
// works by copying every non-c to the current j position
char *deleteThisCharfromStr(char s[], int c) {
j
int i, j; char *i, *j;
for (i = j = 0; s[i] != '\0'; i++) for (i = j = s; *i != '\0'; i++)
if (s[i] != c) if (*i != c)
s[j++] = s[i];
*j++ = *i;
s[j] = '\0';
*j = '\0';
return s;
}
int main(void) {
char s[] = "Hello World";
printf("Delete l from (\"%s\") = %s\n", s, deleteThisCharfromStr(s, 'l'));
return 0;
<3min repl>
}
translate to pointers
priority (also in
priority.ppt)
so far we have placed parentheses to make things clear
t++
(*t)++;
(*(t+4))++;
++*ip
<30sec brains>
operators * and & bind stronger than arithmetic operations