Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - pointers and different results?

Tags:

c

pointers

I cannot figure this out. Perhaps it is because it's 2am. At any rate, I am at a loss here.

#include <stdio.h>

int main()
{
    char array[] = "123456789";
    char* ptr = array;

    printf("%c\n", *(ptr++));
    printf("%c\n", *ptr);

    *ptr = array[3];
    printf("%c\n", *(ptr++));
    printf("%c\n\n", *ptr);

    return 0;
}

The result is:

1
2
4
3
  1. I have a pointer, which I assign to array.

  2. I then print, what I thought would be the first index ( '2' ), but instead get 1. -- So, I assume that *(ptr++) actually dereferences, before it increments the pointers.

  3. Then I reassign ptr the 4th index ( '4' ) and repeat step 2. This works as expected now that I see C does not calculate the parenthesis first before dereferencing.

  4. Then I print the newly incremented ptr to display ( '5' ) ... and I get 3?

How is that, step 1&2 and 3&4 are identical, but I get different results?

like image 218
sherrellbc Avatar asked Jul 14 '13 06:07

sherrellbc


People also ask

Why pointer to different data types are different?

The data type of pointer is needed when dereferencing the pointer so it knows how much data it should read. For example, dereferencing a char pointer should read the next byte from the address it is pointing to, while an integer pointer should read 4 bytes.

How are pointers and variables different?

A pointer variable (or pointer in short) is basically the same as the other variables, which can store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a char), a pointer stores a memory address. Pointers must be declared before they can be used, just like a normal variable.

What are the disadvantages of pointers in C?

Drawbacks of Pointers:Segmentation fault can occur due to uninitialized pointer. Pointers are slower than normal variable. It requires one additional dereferences step. If we forgot to deallocate a memory then it will lead to a memory leak.


1 Answers

Let's go through the code step-by-step:

Step 0:

char* ptr = array;

Point the char pointer to the start of array (namely position 0).

Step 1:

printf("%c\n", *(ptr++));

Dereference the pointer at position 0, print the value residing there (1) and then increment the pointer to position 1

Step 2:

printf("%c\n", *ptr);

Dereference the pointer at position 1 and print the value residing there (2)

Step 3:

*ptr = arr[3];

Dereference the pointer at position 1 and update the value pointed to with the value at position 3 of the array. This is value 4.

Step 4:

printf("%c\n\n", *(ptr++));

Dereference the pointer at position 1, print the value we just updated (4) and then increment the pointer to position 2

Step 5:

printf("%c\n", *ptr);

Dereference the pointer at position 2 and print the value there (3).

Perhaps what you actually intended is to have ptr = &arr[3]; which will assign the pointer to a new position (namely the address of arr[3]).

Note that the braces around ptr in the above are actually redundant due to operator precedence.

For the case of *(ptr++), post-increment has higher precedence than indirection therefore it will be applied before we dereference the pointer

Braces are also unnecessary around *(++ptr) too. Here even though pre-increment and indirection have the same precedence, they are evaluated right-to-left. And so the pointer will be incremented before it is dereferenced.

like image 142
Nobilis Avatar answered Oct 23 '22 17:10

Nobilis