Pointers(Part 2) Flashcards

(19 cards)

1
Q

Array Internals

A

Really, what is an array?
– It’s a sequence of values of the same type stored consecutively in memory.
* Why do these qualities matter?
– If you know the size of each element
– … and where the array starts in memory
– … you can find the memory storing any element.
* So, to use an array, the compiler needs to keep up with:
– How big each element is, so it can do indexing
* That’s implied by the element type
– The location of the first element in memory
* That sounds like a pointer
* And, the compiler will give you this pointer if
you want it.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Arrays as Pointers

A
  • We have a general rule.
    – If a is an array of some type T
    a evaluates to a pointer to the first element
    with a type of pointer to T ( i.e., T *)
    int a[ 6 ];
    int *ap = a;
    a evaluates to pointer to int.
    float b[ 100 ];
    float *bp = b;
    b evaluates to pointer to float.
    Whatever c[ 10 ];
    Whatever *cp = c;
    c evaluates to pointer to Whatever.
  • Useful? Well no, not very useful … yet.
  • This just gives us two ways of getting to the first
    array element.
  • But, what if we could move this pointer around in
    memory?
    – Maybe we could get to other elements of the array.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Pointer Arithmetic

A
  • We can do (some) math on pointers, and it
    behaves in a very useful way.
    – It moves by multiples of sizeof for the type of
    object pointed to.
    – Adding 1 to an int
    pointer moves ahead
    4 bytes.
    – Adding 2 to an int
    pointer moves ahead
    8 bytes.
    – Adding 3 to an int
    pointer … well, you get
    the idea.
  • This works for any type
    – Adding to a short pointer moves by 2 bytes at a
    time.
    – Adding to a long
    pointer moves by 8
    bytes at a time.
    – Adding to a char
    pointer moves one
    byte at a time.
    – …
  • We can see the effects of pointer arithmetic if
    we print the pointer’s value.
    char ca[ 10 ];
    int ia[ 10 ];
    double da[ 10 ];
    char *cp = ca;
    int *ip = ia;
    double *dp = da;
    printf( “%p %p %p\n”, cp, ip, dp );
    printf( “%p %p %p\n”, cp + 1, ip + 1, dp + 1);
    I’m 1 byte later. -> cp + 1
    I’m 4 byte later. -> ip + 1
    I’m 8 bytes later -> dp + 1
    More examples on doc
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Array Elements as Pointers

A
  • This behavior makes it easy to access nearby
    elements of the same type.
    int a[ 10 ];
    int *p = a;

Pointer dereference to
access the first element.
*p = 25;
Pointer arithmetic and
dereference to access other
elements.
*( p + 1 ) = 35;
*( p + 2 ) = 75;
Array name evaluates to a
pointer, so you can even do
this. In fact, you’re in for a
surprise …
*a = 26;
*( a + 1 ) = 36;
*( a + 2 ) = 76;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Array Indexing Explained

A
  • This is what array indexing means in C
    a[ i ] -> *( a + i )
    Addition is commutative, so this is why we can
    write indexing backward:
    i[a] -> *(i + a)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Indexing with Pointer

A
  • If a[i] is just a nice way of writing *(a+i) …
  • … and *(p+i) works for any pointer p … then:
    *( p + i ) <-p[ i ]
    We already know this works for a pointer
    … and we can write it like this, since it means the same thing anyway.
  • Arrays and pointers aren’t the same thing,
    – But, in lots of situations, we can use them
    interchangeably.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Passing Arrays and Pointers

A
  • So, this gives us an alternative way to pass
    arrays to functions (or you might think so)
    – Just pass the address of the first element.
    void g( int *p )
    {
    p[ 0 ] += 1; -> You can index from me,
    like I was an array.
    p[ 1 ] += 2;
    }
    int *p -> I’m a pointer to the first
    element.
    int myList[ ] = { 1, 4, 9 };
    g( myList );
    g(myList); -> I evaluate to the
    address of the first
    element.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Array Parameters(Us v Compiler)

A
  • But, this is secretly how we’ve been passing
    arrays all along.
    – We’ve just been using an alternative syntax.
    ask for this…
    void g( int p[] )
    {
    p[ 0 ] += 1;
    p[ 1 ] += 2;
    }
    int myList[ ] = { 1, 4, 9 };
    g( myList );
    compiler does this
    void g( int *p )
    {
    p[ 0 ] += 1;
    p[ 1 ] += 2;
    }
    int myList[ ] = { 1, 4, 9 };
    g( myList );
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Functions we’ve covered

A
  • So far, we’ve described string-handling
    functions as taking a char array parameter:
    size_t strlen(char const str[])
    strcpy(char dest[], char const src[])
    int sprintf(char str[], char const format[], …);
  • Really, you will probably see them
    documented as char pointer:
    size_t strlen(char const *str)
    strcpy(char *dest, char const *src)
    int sprintf(char *str, char const *format, …);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Array Offset

A
  • Array Parameters are passed by pointer
  • Any pointer will do, it doesn’t have to be at
    the start of an array.
    void capitalize( char *msg ) -> I’ll take any char
    pointer.
    {
    for ( int i = 0; msg[i]; i++ ) {
    msg[i] = toupper( msg[ i ] ); -> I can still use it
    like an array.
    }
    }
    char str[] = “hello world”;
    capitalize( str + 6); -> Here, just work on
    the last part of this array.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Marking your Spot

A
  • scanf() and fscanf() automatically move
    forward in the input as you read.
  • But not sscanf(), it just reads the string you
    give it from the start.
    sscanf( buffer, “%d”, &value );
    sscanf( buffer, “%s”, word );
    These will start at the beginning of the buffer for each call
    With pointer arithmetic %n can let you
    continue from where you left off.
    sscanf( buffer, “%d%n”, &value, &pos );
    sscanf( buffer + pos, “%s”, word );
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Arrays are not pointers

A
  • You might start to think arrays and pointers are
    the same thing … but you’d be wrong.
  • We can see a few situations where they don’t
    behave exactly the same:
    int a[ 6 ];
    int *p = a;
    … sizeof( a ) … -> 24 bytes
    int b[ 6 ];
    a = b; -> can’t do this
    int a[ 6 ];
    int *p = a;
    … sizeof( p ) …-> size of pointer so 8 bytes(all pointers is the same size)
    int b[ 6 ];
    p = b; -> can do this
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Useful Pointer Arithmetic

A

You can add and subtract pointers and
numbers
pointer + number -> pointer
number + pointer -> pointer
pointer – number -> pointer
These each evaluate to a pointer to a nearby
value.
pointer – pointer -> number
This evaluates to the number of values
between two nearby pointers.
number – pointer -> nonsense
Not all operations are meaningful.
* You can compare pointers
pointer == pointer pointer != pointer
pointer < pointer pointer > pointer
pointer <= pointer pointer >= pointer

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Alternatives In Array Indexing

A
  • We have some choices in how we can process
    and iterate over arrays.
  • Plain-old array syntax:
    int a[] = { 1, 4, 9, 16, 25 };
    int len = sizeof( a ) / sizeof( a[ 0 ] );
    int sum = 0;
    for ( int i = 0; i < len; i++ )
    sum += a[ i ];
  • Or, with a pointer visiting each element.
    int a[] = { 1, 4, 9, 16, 25 };
    int len = sizeof( a ) / sizeof( a[ 0 ] );
    int *end = a + len; -> Pointer right past the end of the
    array. This is OK, as long as we
    don’t dereference this pointer.
    int sum = 0;
    for ( int *p = a; p < end; p++ ) -> Iterate from the start of the
    array, stopping when we
    pass its last element.
    sum += *p; -> Less to do here.
    This could give you
    a little performance
    improvement.
  • Or, we can work backward, from the end
    toward the start.
    int a[] = { 1, 4, 9, 16, 25 };
    int len = sizeof( a ) / sizeof( a[ 0 ] );
    for ( int *p = a + len - 1; p >= a; p– )
    sum += *p;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Alternatives In Array Indexing(part 2)

A
  • One more example, measuring string length:
    int stringLen1( char const *str )
    {
    int i = 0;
    while ( str[ i ] != ‘\0’ )
    i++;
    return i;
    }
    int stringLen2( char const *str )
    {
    char const *p = str;
    while ( *p )
    p++;
    return p - str;
    }
    Here’s the interesting part. The difference in pointers tells us how far away p got from the start.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Making Arrays(2 ways)

A
  • There are two ways to make a new array.
  • We get different things in memory.
    // list1 is a new array.
    int list1[] = { 5, 10, 15, 20 };
    // list2 is a pointer.
    int *list2 = (int []){ 7, 14, 21, 28 };
17
Q

Literal Strings

A
  • Literal strings are a special syntax for making an array.
  • The constant “abc123” evaluates to a char pointer.
  • When the compiler sees a string literal like “abc123”
    – It allocates an array for the string literal (with a null
    character at the end)
    – And uses the address of this array as the value of the literal
  • You can even evaluate things like:
    – “abc123”[ 2 ]
18
Q

String Creation Alternatives

A
  • This gives us some options in how to make a
    string variable:
  • This allocates and initializes memory differently:
    // Make me a new array containing this.
    char str1[] = “abc123”;
    // Make this string and just give a pointer
    char *str2 = “xyz789”;
19
Q

Command Line Arguments

A
  • You can run a C program with command-line
    arguments:
    shell$ ./myProgram red green “pale blue”
  • These are stored as an array of char pointers,
    each one pointing to one of the arguments:
    More on Doc
  • To see these arguments, you can define main
    with two parameters:
    int main( int argc, char *argv[] ) …
    argc: Number of arguments.
    argv: Array of char pointers, one
    for each argument
    Say, we wanted to just report the arguments:
  • More typically, we would use the arguments
    to change how the program operates.
    int main( int argc, char *argv[] )
    {
    printf( “%d arguments\n”, argc );
    for ( int i = 0; i < argc; i++ )
    printf( “ %s\n”, argv[ i ] );
    }