Click here to Skip to main content
15,611,599 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Today I am trying to learn better pointer differencing and I edited some code from a C-book. The problem is that where the book says it should be 1 my result is -0.100000. Here is the code:

// Jones, Bradley L.; Peter Aitken; Dean Miller. C Programming in One Hour a Day, Sams Teach Yourself (pp. 339-340). Pearson Education. Kindle Edition.
   /* ptr_math.c--Demonstrates using pointer arithmetic to
      access array elements with pointer notation. */

   #include <stdio.h>
   #define MAX 10

   // Declare and initialize an integer array.

   int i_array[MAX] = { 0,1,2,3,4,5,6,7,8,9 };

  // Declare a pointer to int and an int variable.

  int *i_ptr, *i2_ptr, *i3_ptr, count;

  // Declare and initialize a float array.

  float f_array[MAX] = { .0, .1, .2, .3, .4, .5, .6, .7, .8, .9 };

  // Declare a pointer to float.

  float *f_ptr, f2_ptr, f3_ptr;

  int main( void )
  {
      /* Initialize the pointers. */

      i_ptr = i_array;
      i2_ptr = i_array[2];
      i3_ptr = i_array[3];
      f_ptr = f_array;
      f2_ptr = f_array[2];
      f3_ptr = f_array[3];

      /* Print the array elements. */

    //  for (count = 0; count < MAX; count++)
    //      printf("%d\t%f\n", *i_ptr++, *f_ptr++);
    for (count = 0; count < MAX; count++)
    {
    printf("%d\t%f\n", *i_ptr, *f_ptr );
    i_ptr++;
    f_ptr++;
    }
    printf("\n%d\n", i2_ptr - i3_ptr );
    printf("\n%f\n", f2_ptr - f3_ptr );

      return 0;
  }

So it's the last 2 printf's where I difference with pointers. I understand that they are 1 position away from each other but the float value is not 1 but -0.100000. Why?

What I have tried:

I don't remember today. It has passed some time since I edited the code from the C-book.
Posted
Updated 6-Aug-21 6:31am
v2
Comments
jeron1 6-Aug-21 10:43am    
try something like,

i2_ptr = &i_array[2];
Mieczyslaw1683 6-Aug-21 10:56am    
Hmm, I don't understand. The result is weird with that & symbol before. However, this is what I understand how the code should look and work correctly:
// Jones, Bradley L.; Peter Aitken; Dean Miller. C Programming in One Hour a Day, Sams Teach Yourself (pp. 339-340). Pearson Education. Kindle Edition.
   /* ptr_math.c--Demonstrates using pointer arithmetic to
      access array elements with pointer notation. */

   #include <stdio.h>
   #define MAX 10

   // Declare and initialize an integer array.

   int i_array[MAX] = { 0,1,2,3,4,5,6,7,8,9 };

  // Declare a pointer to int and an int variable.

  int *i_ptr, *i2_ptr, *i3_ptr, count;

  // Declare and initialize a float array.

  float f_array[MAX] = { .0, .1, .2, .3, .4, .5, .6, .7, .8, .9 };

  // Declare a pointer to float.

  float *f_ptr, *f2_ptr, *f3_ptr;

  int main( void )
  {
      /* Initialize the pointers. */

      i_ptr = i_array;
      i2_ptr = i_array[2];
      i3_ptr = i_array[3];
      f_ptr = f_array;
      f2_ptr = f_array[2];
      f3_ptr = f_array[3];

      /* Print the array elements. */

    //  for (count = 0; count < MAX; count++)
    //      printf("%d\t%f\n", *i_ptr++, *f_ptr++);
    for (count = 0; count < MAX; count++)
    {
    printf("%d\t%f\n", *i_ptr, *f_ptr );
    i_ptr++;
    f_ptr++;
    }
    printf("\n%d\n", i2_ptr - i3_ptr );
    printf("\n%f\n", f2_ptr - f3_ptr );

      return 0;
  }

The f2_ptr and f3_ptr are real pointers but the error when trying this code is:
"... \Giraffe\main.c|34|error: incompatible types when assigning to type 'float *' from type 'float'|
... \Giraffe\main.c|35|error: incompatible types when assigning to type 'float *' from type 'float'|"
jeron1 6-Aug-21 11:02am    
Like Griff said,

i2_ptr = i_array[2];

You've specified i2_ptr as a pointer, i_array[2] is not a pointer but the float value at index 2 of the array. When you have,

i2_ptr - i3_ptr

what is your expectation?

I didn't read the whole thing prior to commenting the first time, I apologize.
Richard MacCutchan 6-Aug-21 11:30am    
f2_ptr = f_array[2];

You cannot assign a floating point value to a pointer. If you want it to point to the third element of the array then you need to add the addressof operator, thus:
f2_ptr = &f_array[2];
Richard MacCutchan 6-Aug-21 11:32am    
If you really want to learn C then start with The C Programming Language - Wikipedia[^], the best book ever written on the subject.

Because you aren't working with pointers:
C
float *f_ptr, f2_ptr, f3_ptr;
    f_ptr = f_array;
    f2_ptr = f_array[2];
    f3_ptr = f_array[3];

f_ptr is a pointer, but f2_ptr and f3_ptr aren't = they are float values, you you copy the content of two array elements into them before you do the subtraction: 0.2 and 0.3
Subtract 0.3 from 0.2 and you get ... -0.1

i2_ptr and i3_ptr are pointers, so when you subtract them, you get the number of elements between them.
 
Share this answer
 
Comments
Mieczyslaw1683 6-Aug-21 10:59am    
Ok. So yes. I have noticed that I skipped the "*" symbol before so they became float values. Because I got this error when making pointers to the f_array elements: "... \Giraffe\main.c|34|error: incompatible types when assigning to type 'float *' from type 'float'|
... \Giraffe\main.c|35|error: incompatible types when assigning to type 'float *' from type 'float'|"

Why do I get that errors when making pointers to the array elements?
Okay. So I have learned that pointers with adresses (adress-pointers) need the & before the, for example, array name. Then they can be int's without problems because it's just a value. So now I got it to work. Here is the code:

// Jones, Bradley L.; Peter Aitken; Dean Miller. C Programming in One Hour a Day, Sams Teach Yourself (pp. 339-340). Pearson Education. Kindle Edition.
   /* ptr_math.c--Demonstrates using pointer arithmetic to
      access array elements with pointer notation. */

   #include <stdio.h>
   #define MAX 10

   // Declare and initialize an integer array.

   int i_array[MAX] = { 0,1,2,3,4,5,6,7,8,9 };

  // Declare a pointer to int and an int variable.

  int *i_ptr, *i2_ptr, *i3_ptr, *i4_ptr, *i5_ptr, count;

  // Declare and initialize a float array.

  float f_array[MAX] = { .0, .1, .2, .3, .4, .5, .6, .7, .8, .9 };

  // Declare a pointer to float.

  float *f_ptr;

  int main( void )
  {
      /* Initialize the pointers. */

      i_ptr = i_array;
      i2_ptr = i_array[2];
      i3_ptr = i_array[3];
      f_ptr = f_array;
      i4_ptr = &f_array[2];
      i5_ptr = &f_array[3];

      /* Print the array elements. */

    //  for (count = 0; count < MAX; count++)
    //      printf("%d\t%f\n", *i_ptr++, *f_ptr++);
    for (count = 0; count < MAX; count++)
    {
    printf("%d\t%f\n", *i_ptr, *f_ptr );
    i_ptr++;
    f_ptr++;
    }
    printf("\n%d\n", i2_ptr - i3_ptr );
    printf("\n%d\n", i4_ptr - i5_ptr );

      return 0;
  }
 
Share this answer
 
v2
Comments
OriginalGriff 6-Aug-21 11:40am    
Don't assign pointers to variables of a different type of pointer:
float * fp = float_array;
int *ip = fp;
It'll work, but ... it'll also give you problems, because pointer arithmetic works on the size of the type the variable is a pointer to: and int and float are not the same size in all systems. In your case, they are both 32 bits, but that is system dependant, not a "fixed feature of C" so it works. But in a different system where an integer is 2 bytes (and they exist) and a float is 4 bytes the arithmetic goes wrong!

This gets really noticeable (and causes horrible bugs) when you start mixing char pointers with anything else because char is a byte (except when it's unicode) and anything else is aligned to different address boundaries. Which means that a char pointer can reference any address, but a 32bit int pointer can only address values which are a multiple of four.

Yes, I know - that's confusing.
Just don't do it, OK? It'll bite you hard some day if you do! :laugh:
Mieczyslaw1683 6-Aug-21 11:51am    
Ok, thanks. It seems logical to use float pointers to float arrays.
Okay. I have learned to do some pointer arithmetic and I have seen how far apart 2 elements in two different types of arrays are from each other. Here is the code:

// Jones, Bradley L.; Peter Aitken; Dean Miller. C Programming in One Hour a Day, Sams Teach Yourself (pp. 339-340). Pearson Education. Kindle Edition.
   /* ptr_math.c--Demonstrates using pointer arithmetic to
      access array elements with pointer notation. */

   #include <stdio.h>
   #define MAX 10

   // Declare and initialize an integer array.

   int i_array[MAX] = { 0,1,2,3,4,5,6,7,8,9 };

  // Declare a pointer to int and an int variable.

  int *i_ptr, *i2_ptr, *i3_ptr, count;

  // Declare and initialize a float array.

  float f_array[MAX] = { .0, .1, .2, .3, .4, .5, .6, .7, .8, .9 };

  // Declare a pointer to float.

  float *f_ptr, *f2_ptr, *f3_ptr;

  int main( void )
  {
      /* Initialize the pointers. */

      i_ptr = i_array;
      i2_ptr = i_array[2];
      i3_ptr = i_array[3];
      f_ptr = f_array;
      f2_ptr = &f_array[2];
      f3_ptr = &f_array[3];

      /* Print the array elements. */

    //  for (count = 0; count < MAX; count++)
    //      printf("%d\t%f\n", *i_ptr++, *f_ptr++);
    for (count = 0; count < MAX; count++)
    {
    printf("%d\t%f\n", *i_ptr, *f_ptr );
    i_ptr++;
    f_ptr++;
    }
    printf("\n%d\n", i2_ptr - i3_ptr );
    printf("\n%d\n", f2_ptr - f3_ptr );

      return 0;
  }


For the future, I would like to understand why integer pointers don't need the "&" symbol before array names (with elements marked)?

P.s. If it would be the same for both the int array and float array it would look more logical.
 
Share this answer
 
v2
Comments
jeron1 6-Aug-21 12:10pm    
It does work the same for int's and floats.

int *i_ptr, *i2_ptr, *i3_ptr; // i2_ptr, i3_ptr declared as pointers to integers

i2_ptr = i_array[2]; // this assigns the int value at array index 2 (not the address) to the pointer variable i2_ptr
i3_ptr = i_array[3]; // this assigns the int value at array index 3 (not the address) to the pointer variable i3_ptr

same issue as before.
Mieczyslaw1683 6-Aug-21 12:23pm    
Okay. So in pointer arithmetic when subtracting two pointers (to elements in an array), then you need to use address-pointers (they have a "&" symbol before them). I tried this code below:
// Jones, Bradley L.; Peter Aitken; Dean Miller. C Programming in One Hour a Day, Sams Teach Yourself (pp. 339-340). Pearson Education. Kindle Edition.
   /* ptr_math.c--Demonstrates using pointer arithmetic to
      access array elements with pointer notation. */

   #include <stdio.h>
   #define MAX 10

   // Declare and initialize an integer array.

   int i_array[MAX] = { 0,1,5,3,4,5,6,7,8,9 };

  // Declare a pointer to int and an int variable.

  int *i_ptr, *i2_ptr, *i3_ptr, count;

  // Declare and initialize a float array.

  float f_array[MAX] = { .0, .1, .2, .3, .4, .5, .6, .7, .8, .9 };

  // Declare a pointer to float.

  float *f_ptr, *f2_ptr, *f3_ptr;

  int main( void )
  {
      /* Initialize the pointers. */

      i_ptr = i_array;
      i2_ptr = i_array[2];
      i3_ptr = i_array[3];
      f_ptr = f_array;
      f2_ptr = &f_array[2];
      f3_ptr = &f_array[3];

      /* Print the array elements. */

    //  for (count = 0; count < MAX; count++)
    //      printf("%d\t%f\n", *i_ptr++, *f_ptr++);
    for (count = 0; count < MAX; count++)
    {
    printf("%d\t%f\n", *i_ptr, *f_ptr );
    i_ptr++;
    f_ptr++;
    }
    printf("\n%d\n", i2_ptr - i3_ptr );
    printf("\n%d\n", f2_ptr - f3_ptr );

      return 0;
  }


To try to see if it would give me the value "2" from the pointer arithmetic subtraction: Copy Code
printf("\n%d\n", i2_ptr - i3_ptr );
. It gave me a "0". This made me wonder a bit. It looks wrong to be doing pointer arithmetic with pointers that have values.

However the correct way is to specify that its adress-pointers and then do the pointer arithmetic.
Now I have made correct pointer arithmetic subtractions (in 2 types of arrays), I think. The code is below:
// Jones, Bradley L.; Peter Aitken; Dean Miller. C Programming in One Hour a Day, Sams Teach Yourself (pp. 339-340). Pearson Education. Kindle Edition.
   /* ptr_math.c--Demonstrates using pointer arithmetic to
      access array elements with pointer notation. */

   #include <stdio.h>
   #define MAX 10

   // Declare and initialize an integer array.

   int i_array[MAX] = { 0,1,2,3,4,5,6,7,8,9 };

  // Declare a pointer to int and an int variable.

  int *i_ptr, *i2_ptr, *i3_ptr, count;

  // Declare and initialize a float array.

  float f_array[MAX] = { .0, .1, .2, .3, .4, .5, .6, .7, .8, .9 };

  // Declare a pointer to float.

  float *f_ptr, *f2_ptr, *f3_ptr;

  int main( void )
  {
      /* Initialize the pointers. */

      i_ptr = i_array;
      i2_ptr = &i_array[2];
      i3_ptr = &i_array[3];
      f_ptr = f_array;
      f2_ptr = &f_array[2];
      f3_ptr = &f_array[3];

      /* Print the array elements. */

    //  for (count = 0; count < MAX; count++)
    //      printf("%d\t%f\n", *i_ptr++, *f_ptr++);
    for (count = 0; count < MAX; count++)
    {
    printf("%d\t%f\n", *i_ptr, *f_ptr );
    i_ptr++;
    f_ptr++;
    }
    printf("\n%d\n", i2_ptr - i3_ptr );
    printf("\n%d\n", f2_ptr - f3_ptr );

      return 0;
  }
 
Share this answer
 
Comments
jeron1 6-Aug-21 12:55pm    
printf("\n%d\n", i2_ptr - i3_ptr );
printf("\n%d\n", f2_ptr - f3_ptr );

Those lines will give you the difference between 2 addresses (not the values at those addresses), and in these cases will probably end up being negative.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900